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