1 //===- LoongArchInstPrinter.cpp - Convert LoongArch MCInst to asm syntax --===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This class prints an LoongArch MCInst to a .s file. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "LoongArchInstPrinter.h" 14 #include "LoongArchMCTargetDesc.h" 15 #include "llvm/MC/MCAsmInfo.h" 16 #include "llvm/MC/MCInst.h" 17 #include "llvm/MC/MCSubtargetInfo.h" 18 #include "llvm/MC/MCSymbol.h" 19 #include "llvm/Support/CommandLine.h" 20 using namespace llvm; 21 22 #define DEBUG_TYPE "loongarch-asm-printer" 23 24 // Include the auto-generated portion of the assembly writer. 25 #define PRINT_ALIAS_INSTR 26 #include "LoongArchGenAsmWriter.inc" 27 28 static cl::opt<bool> 29 NumericReg("loongarch-numeric-reg", 30 cl::desc("Print numeric register names rather than the ABI " 31 "names (such as $r0 instead of $zero)"), 32 cl::init(false), cl::Hidden); 33 34 // The command-line flag above is used by llvm-mc and llc. It can be used by 35 // `llvm-objdump`, but we override the value here to handle options passed to 36 // `llvm-objdump` with `-M` (which matches GNU objdump). There did not seem to 37 // be an easier way to allow these options in all these tools, without doing it 38 // this way. 39 bool LoongArchInstPrinter::applyTargetSpecificCLOption(StringRef Opt) { 40 if (Opt == "numeric") { 41 NumericReg = true; 42 return true; 43 } 44 45 return false; 46 } 47 48 void LoongArchInstPrinter::printInst(const MCInst *MI, uint64_t Address, 49 StringRef Annot, 50 const MCSubtargetInfo &STI, 51 raw_ostream &O) { 52 if (!printAliasInstr(MI, Address, STI, O)) 53 printInstruction(MI, Address, STI, O); 54 printAnnotation(O, Annot); 55 } 56 57 void LoongArchInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) { 58 O << '$' << getRegisterName(Reg); 59 } 60 61 void LoongArchInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 62 const MCSubtargetInfo &STI, 63 raw_ostream &O) { 64 const MCOperand &MO = MI->getOperand(OpNo); 65 66 if (MO.isReg()) { 67 printRegName(O, MO.getReg()); 68 return; 69 } 70 71 if (MO.isImm()) { 72 O << MO.getImm(); 73 return; 74 } 75 76 assert(MO.isExpr() && "Unknown operand kind in printOperand"); 77 MO.getExpr()->print(O, &MAI); 78 } 79 80 void LoongArchInstPrinter::printAtomicMemOp(const MCInst *MI, unsigned OpNo, 81 const MCSubtargetInfo &STI, 82 raw_ostream &O) { 83 const MCOperand &MO = MI->getOperand(OpNo); 84 assert(MO.isReg() && "printAtomicMemOp can only print register operands"); 85 printRegName(O, MO.getReg()); 86 } 87 88 const char *LoongArchInstPrinter::getRegisterName(MCRegister Reg) { 89 // Default print reg alias name 90 return getRegisterName(Reg, NumericReg ? LoongArch::NoRegAltName 91 : LoongArch::RegAliasName); 92 } 93