18ba622baSZi Xuan Wu //===-- CSKYInstPrinter.cpp - Convert CSKY MCInst to asm syntax ---------===// 28ba622baSZi Xuan Wu // 38ba622baSZi Xuan Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 48ba622baSZi Xuan Wu // See https://llvm.org/LICENSE.txt for license information. 58ba622baSZi Xuan Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68ba622baSZi Xuan Wu // 78ba622baSZi Xuan Wu //===----------------------------------------------------------------------===// 88ba622baSZi Xuan Wu // 98ba622baSZi Xuan Wu // This class prints an CSKY MCInst to a .s file. 108ba622baSZi Xuan Wu // 118ba622baSZi Xuan Wu //===----------------------------------------------------------------------===// 128ba622baSZi Xuan Wu 138ba622baSZi Xuan Wu #include "CSKYInstPrinter.h" 14*de10a02fSZi Xuan Wu #include "llvm/ADT/StringExtras.h" 158ba622baSZi Xuan Wu #include "llvm/MC/MCAsmInfo.h" 168ba622baSZi Xuan Wu #include "llvm/MC/MCExpr.h" 178ba622baSZi Xuan Wu #include "llvm/MC/MCInst.h" 188ba622baSZi Xuan Wu #include "llvm/MC/MCRegisterInfo.h" 198ba622baSZi Xuan Wu #include "llvm/MC/MCSubtargetInfo.h" 208ba622baSZi Xuan Wu #include "llvm/MC/MCSymbol.h" 218ba622baSZi Xuan Wu #include "llvm/Support/CommandLine.h" 228ba622baSZi Xuan Wu #include "llvm/Support/ErrorHandling.h" 238ba622baSZi Xuan Wu #include "llvm/Support/FormattedStream.h" 248ba622baSZi Xuan Wu 258ba622baSZi Xuan Wu using namespace llvm; 268ba622baSZi Xuan Wu 278ba622baSZi Xuan Wu #define DEBUG_TYPE "csky-asm-printer" 288ba622baSZi Xuan Wu 298ba622baSZi Xuan Wu // Include the auto-generated portion of the assembly writer. 308ba622baSZi Xuan Wu #define PRINT_ALIAS_INSTR 318ba622baSZi Xuan Wu #include "CSKYGenAsmWriter.inc" 328ba622baSZi Xuan Wu 338ba622baSZi Xuan Wu static cl::opt<bool> 348ba622baSZi Xuan Wu NoAliases("csky-no-aliases", 358ba622baSZi Xuan Wu cl::desc("Disable the emission of assembler pseudo instructions"), 368ba622baSZi Xuan Wu cl::init(false), cl::Hidden); 378ba622baSZi Xuan Wu 388ba622baSZi Xuan Wu static cl::opt<bool> 398ba622baSZi Xuan Wu ArchRegNames("csky-arch-reg-names", 408ba622baSZi Xuan Wu cl::desc("Print architectural register names rather than the " 418ba622baSZi Xuan Wu "ABI names (such as r14 instead of sp)"), 428ba622baSZi Xuan Wu cl::init(false), cl::Hidden); 438ba622baSZi Xuan Wu 448ba622baSZi Xuan Wu // The command-line flags above are used by llvm-mc and llc. They can be used by 458ba622baSZi Xuan Wu // `llvm-objdump`, but we override their values here to handle options passed to 468ba622baSZi Xuan Wu // `llvm-objdump` with `-M` (which matches GNU objdump). There did not seem to 478ba622baSZi Xuan Wu // be an easier way to allow these options in all these tools, without doing it 488ba622baSZi Xuan Wu // this way. 498ba622baSZi Xuan Wu bool CSKYInstPrinter::applyTargetSpecificCLOption(StringRef Opt) { 508ba622baSZi Xuan Wu if (Opt == "no-aliases") { 518ba622baSZi Xuan Wu NoAliases = true; 528ba622baSZi Xuan Wu return true; 538ba622baSZi Xuan Wu } 548ba622baSZi Xuan Wu if (Opt == "numeric") { 558ba622baSZi Xuan Wu ArchRegNames = true; 568ba622baSZi Xuan Wu return true; 578ba622baSZi Xuan Wu } 588ba622baSZi Xuan Wu 598ba622baSZi Xuan Wu return false; 608ba622baSZi Xuan Wu } 618ba622baSZi Xuan Wu 628ba622baSZi Xuan Wu void CSKYInstPrinter::printInst(const MCInst *MI, uint64_t Address, 638ba622baSZi Xuan Wu StringRef Annot, const MCSubtargetInfo &STI, 648ba622baSZi Xuan Wu raw_ostream &O) { 658ba622baSZi Xuan Wu const MCInst *NewMI = MI; 668ba622baSZi Xuan Wu 678ba622baSZi Xuan Wu if (NoAliases || !printAliasInstr(NewMI, Address, STI, O)) 688ba622baSZi Xuan Wu printInstruction(NewMI, Address, STI, O); 698ba622baSZi Xuan Wu printAnnotation(O, Annot); 708ba622baSZi Xuan Wu } 718ba622baSZi Xuan Wu 728ba622baSZi Xuan Wu void CSKYInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { 738ba622baSZi Xuan Wu O << getRegisterName(RegNo); 748ba622baSZi Xuan Wu } 758ba622baSZi Xuan Wu 768ba622baSZi Xuan Wu void CSKYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 778ba622baSZi Xuan Wu const MCSubtargetInfo &STI, raw_ostream &O, 788ba622baSZi Xuan Wu const char *Modifier) { 798ba622baSZi Xuan Wu assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"); 808ba622baSZi Xuan Wu const MCOperand &MO = MI->getOperand(OpNo); 818ba622baSZi Xuan Wu 828ba622baSZi Xuan Wu if (MO.isReg()) { 838ba622baSZi Xuan Wu if (MO.getReg() == CSKY::C) 848ba622baSZi Xuan Wu O << ""; 858ba622baSZi Xuan Wu else 868ba622baSZi Xuan Wu printRegName(O, MO.getReg()); 878ba622baSZi Xuan Wu return; 888ba622baSZi Xuan Wu } 898ba622baSZi Xuan Wu 908ba622baSZi Xuan Wu if (MO.isImm()) { 918ba622baSZi Xuan Wu O << formatImm(MO.getImm()); 928ba622baSZi Xuan Wu return; 938ba622baSZi Xuan Wu } 948ba622baSZi Xuan Wu 958ba622baSZi Xuan Wu assert(MO.isExpr() && "Unknown operand kind in printOperand"); 968ba622baSZi Xuan Wu MO.getExpr()->print(O, &MAI); 978ba622baSZi Xuan Wu } 988ba622baSZi Xuan Wu 99*de10a02fSZi Xuan Wu void CSKYInstPrinter::printDataSymbol(const MCInst *MI, unsigned OpNo, 100*de10a02fSZi Xuan Wu const MCSubtargetInfo &STI, 101*de10a02fSZi Xuan Wu raw_ostream &O) { 102*de10a02fSZi Xuan Wu const MCOperand &MO = MI->getOperand(OpNo); 103*de10a02fSZi Xuan Wu 104*de10a02fSZi Xuan Wu O << "["; 105*de10a02fSZi Xuan Wu if (MO.isImm()) 106*de10a02fSZi Xuan Wu O << MO.getImm(); 107*de10a02fSZi Xuan Wu else 108*de10a02fSZi Xuan Wu MO.getExpr()->print(O, &MAI); 109*de10a02fSZi Xuan Wu O << "]"; 110*de10a02fSZi Xuan Wu } 111*de10a02fSZi Xuan Wu 112*de10a02fSZi Xuan Wu void CSKYInstPrinter::printConstpool(const MCInst *MI, uint64_t Address, 113*de10a02fSZi Xuan Wu unsigned OpNo, const MCSubtargetInfo &STI, 114*de10a02fSZi Xuan Wu raw_ostream &O) { 115*de10a02fSZi Xuan Wu const MCOperand &MO = MI->getOperand(OpNo); 116*de10a02fSZi Xuan Wu 117*de10a02fSZi Xuan Wu if (MO.isImm()) { 118*de10a02fSZi Xuan Wu if (PrintBranchImmAsAddress) { 119*de10a02fSZi Xuan Wu uint64_t Target = Address + MO.getImm(); 120*de10a02fSZi Xuan Wu Target &= 0xfffffffc; 121*de10a02fSZi Xuan Wu O << formatHex(Target); 122*de10a02fSZi Xuan Wu } else { 123*de10a02fSZi Xuan Wu O << MO.getImm(); 124*de10a02fSZi Xuan Wu } 125*de10a02fSZi Xuan Wu return; 126*de10a02fSZi Xuan Wu } 127*de10a02fSZi Xuan Wu 128*de10a02fSZi Xuan Wu assert(MO.isExpr() && "Unknown operand kind in printConstpool"); 129*de10a02fSZi Xuan Wu 130*de10a02fSZi Xuan Wu O << "["; 131*de10a02fSZi Xuan Wu MO.getExpr()->print(O, &MAI); 132*de10a02fSZi Xuan Wu O << "]"; 133*de10a02fSZi Xuan Wu } 134*de10a02fSZi Xuan Wu 135*de10a02fSZi Xuan Wu void CSKYInstPrinter::printCSKYSymbolOperand(const MCInst *MI, uint64_t Address, 136*de10a02fSZi Xuan Wu unsigned OpNo, 137*de10a02fSZi Xuan Wu const MCSubtargetInfo &STI, 138*de10a02fSZi Xuan Wu raw_ostream &O) { 139*de10a02fSZi Xuan Wu const MCOperand &MO = MI->getOperand(OpNo); 140*de10a02fSZi Xuan Wu if (!MO.isImm()) { 141*de10a02fSZi Xuan Wu return printOperand(MI, OpNo, STI, O); 142*de10a02fSZi Xuan Wu } 143*de10a02fSZi Xuan Wu 144*de10a02fSZi Xuan Wu if (PrintBranchImmAsAddress) { 145*de10a02fSZi Xuan Wu uint64_t Target = Address + MO.getImm(); 146*de10a02fSZi Xuan Wu Target &= 0xffffffff; 147*de10a02fSZi Xuan Wu O << formatHex(Target); 148*de10a02fSZi Xuan Wu } else { 149*de10a02fSZi Xuan Wu O << MO.getImm(); 150*de10a02fSZi Xuan Wu } 151*de10a02fSZi Xuan Wu } 152*de10a02fSZi Xuan Wu 153*de10a02fSZi Xuan Wu void CSKYInstPrinter::printRegisterSeq(const MCInst *MI, unsigned OpNum, 154*de10a02fSZi Xuan Wu const MCSubtargetInfo &STI, 155*de10a02fSZi Xuan Wu raw_ostream &O) { 156*de10a02fSZi Xuan Wu printRegName(O, MI->getOperand(OpNum).getReg()); 157*de10a02fSZi Xuan Wu O << "-"; 158*de10a02fSZi Xuan Wu printRegName(O, MI->getOperand(OpNum + 1).getReg()); 159*de10a02fSZi Xuan Wu } 160*de10a02fSZi Xuan Wu 161*de10a02fSZi Xuan Wu void CSKYInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum, 162*de10a02fSZi Xuan Wu const MCSubtargetInfo &STI, 163*de10a02fSZi Xuan Wu raw_ostream &O) { 164*de10a02fSZi Xuan Wu auto V = MI->getOperand(OpNum).getImm(); 165*de10a02fSZi Xuan Wu ListSeparator LS; 166*de10a02fSZi Xuan Wu 167*de10a02fSZi Xuan Wu if (V & 0xf) { 168*de10a02fSZi Xuan Wu O << LS; 169*de10a02fSZi Xuan Wu printRegName(O, CSKY::R4); 170*de10a02fSZi Xuan Wu auto Offset = (V & 0xf) - 1; 171*de10a02fSZi Xuan Wu if (Offset) { 172*de10a02fSZi Xuan Wu O << "-"; 173*de10a02fSZi Xuan Wu printRegName(O, CSKY::R4 + Offset); 174*de10a02fSZi Xuan Wu } 175*de10a02fSZi Xuan Wu } 176*de10a02fSZi Xuan Wu 177*de10a02fSZi Xuan Wu if ((V >> 4) & 0x1) { 178*de10a02fSZi Xuan Wu O << LS; 179*de10a02fSZi Xuan Wu printRegName(O, CSKY::R15); 180*de10a02fSZi Xuan Wu } 181*de10a02fSZi Xuan Wu 182*de10a02fSZi Xuan Wu if ((V >> 5) & 0x7) { 183*de10a02fSZi Xuan Wu O << LS; 184*de10a02fSZi Xuan Wu printRegName(O, CSKY::R16); 185*de10a02fSZi Xuan Wu 186*de10a02fSZi Xuan Wu auto Offset = ((V >> 5) & 0x7) - 1; 187*de10a02fSZi Xuan Wu 188*de10a02fSZi Xuan Wu if (Offset) { 189*de10a02fSZi Xuan Wu O << "-"; 190*de10a02fSZi Xuan Wu printRegName(O, CSKY::R16 + Offset); 191*de10a02fSZi Xuan Wu } 192*de10a02fSZi Xuan Wu } 193*de10a02fSZi Xuan Wu 194*de10a02fSZi Xuan Wu if ((V >> 8) & 0x1) { 195*de10a02fSZi Xuan Wu O << LS; 196*de10a02fSZi Xuan Wu printRegName(O, CSKY::R28); 197*de10a02fSZi Xuan Wu } 198*de10a02fSZi Xuan Wu } 199*de10a02fSZi Xuan Wu 2008ba622baSZi Xuan Wu const char *CSKYInstPrinter::getRegisterName(unsigned RegNo) { 2018ba622baSZi Xuan Wu return getRegisterName(RegNo, ArchRegNames ? CSKY::NoRegAltName 2028ba622baSZi Xuan Wu : CSKY::ABIRegAltName); 2038ba622baSZi Xuan Wu } 204