1 //===-- RISCVInstPrinter.cpp - Convert RISCV 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 RISCV MCInst to a .s file. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "RISCVInstPrinter.h" 14 #include "MCTargetDesc/RISCVMCExpr.h" 15 #include "Utils/RISCVBaseInfo.h" 16 #include "llvm/MC/MCAsmInfo.h" 17 #include "llvm/MC/MCExpr.h" 18 #include "llvm/MC/MCInst.h" 19 #include "llvm/MC/MCRegisterInfo.h" 20 #include "llvm/MC/MCSubtargetInfo.h" 21 #include "llvm/MC/MCSymbol.h" 22 #include "llvm/Support/CommandLine.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/FormattedStream.h" 25 using namespace llvm; 26 27 #define DEBUG_TYPE "asm-printer" 28 29 // Include the auto-generated portion of the assembly writer. 30 #define PRINT_ALIAS_INSTR 31 #include "RISCVGenAsmWriter.inc" 32 33 // Include the auto-generated portion of the compress emitter. 34 #define GEN_UNCOMPRESS_INSTR 35 #include "RISCVGenCompressInstEmitter.inc" 36 37 static cl::opt<bool> 38 NoAliases("riscv-no-aliases", 39 cl::desc("Disable the emission of assembler pseudo instructions"), 40 cl::init(false), cl::Hidden); 41 42 void RISCVInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 43 StringRef Annot, const MCSubtargetInfo &STI) { 44 bool Res = false; 45 const MCInst *NewMI = MI; 46 MCInst UncompressedMI; 47 if (!NoAliases) 48 Res = uncompressInst(UncompressedMI, *MI, MRI, STI); 49 if (Res) 50 NewMI = const_cast<MCInst *>(&UncompressedMI); 51 if (NoAliases || !printAliasInstr(NewMI, STI, O)) 52 printInstruction(NewMI, STI, O); 53 printAnnotation(O, Annot); 54 } 55 56 void RISCVInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { 57 O << getRegisterName(RegNo); 58 } 59 60 void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 61 const MCSubtargetInfo &STI, raw_ostream &O, 62 const char *Modifier) { 63 assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"); 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 RISCVInstPrinter::printCSRSystemRegister(const MCInst *MI, unsigned OpNo, 81 const MCSubtargetInfo &STI, 82 raw_ostream &O) { 83 unsigned Imm = MI->getOperand(OpNo).getImm(); 84 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 85 if (SysReg && SysReg->haveRequiredFeatures(STI.getFeatureBits())) 86 O << SysReg->Name; 87 else 88 O << Imm; 89 } 90 91 void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo, 92 const MCSubtargetInfo &STI, 93 raw_ostream &O) { 94 unsigned FenceArg = MI->getOperand(OpNo).getImm(); 95 assert (((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg"); 96 97 if ((FenceArg & RISCVFenceField::I) != 0) 98 O << 'i'; 99 if ((FenceArg & RISCVFenceField::O) != 0) 100 O << 'o'; 101 if ((FenceArg & RISCVFenceField::R) != 0) 102 O << 'r'; 103 if ((FenceArg & RISCVFenceField::W) != 0) 104 O << 'w'; 105 if (FenceArg == 0) 106 O << "unknown"; 107 } 108 109 void RISCVInstPrinter::printFRMArg(const MCInst *MI, unsigned OpNo, 110 const MCSubtargetInfo &STI, raw_ostream &O) { 111 auto FRMArg = 112 static_cast<RISCVFPRndMode::RoundingMode>(MI->getOperand(OpNo).getImm()); 113 O << RISCVFPRndMode::roundingModeToString(FRMArg); 114 } 115 116 void RISCVInstPrinter::printAtomicMemOp(const MCInst *MI, unsigned OpNo, 117 const MCSubtargetInfo &STI, 118 raw_ostream &O) { 119 const MCOperand &MO = MI->getOperand(OpNo); 120 121 assert(MO.isReg() && "printAtomicMemOp can only print register operands"); 122 O << "("; 123 printRegName(O, MO.getReg()); 124 O << ")"; 125 return; 126 } 127