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" 22using 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 30static 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. 41bool LoongArchInstPrinter::applyTargetSpecificCLOption(StringRef Opt) { 42 if (Opt == "numeric") { 43 NumericReg = true; 44 return true; 45 } 46 47 return false; 48} 49 50void 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 59void LoongArchInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const { 60 O << '$' << getRegisterName(Reg); 61} 62 63void 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 82void 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 90const char *LoongArchInstPrinter::getRegisterName(MCRegister Reg) { 91 // Default print reg alias name 92 return getRegisterName(Reg, NumericReg ? LoongArch::NoRegAltName 93 : LoongArch::RegAliasName); 94} 95