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 static cl::opt<bool> 43 ArchRegNames("riscv-arch-reg-names", 44 cl::desc("Print architectural register names rather than the " 45 "ABI names (such as x2 instead of sp)"), 46 cl::init(false), cl::Hidden); 47 48 // The command-line flags above are used by llvm-mc and llc. They can be used by 49 // `llvm-objdump`, but we override their values here to handle options passed to 50 // `llvm-objdump` with `-M` (which matches GNU objdump). There did not seem to 51 // be an easier way to allow these options in all these tools, without doing it 52 // this way. 53 bool RISCVInstPrinter::applyTargetSpecificCLOption(StringRef Opt) { 54 if (Opt == "no-aliases") { 55 NoAliases = true; 56 return true; 57 } 58 if (Opt == "numeric") { 59 ArchRegNames = true; 60 return true; 61 } 62 63 return false; 64 } 65 66 void RISCVInstPrinter::printInst(const MCInst *MI, uint64_t Address, 67 StringRef Annot, const MCSubtargetInfo &STI, 68 raw_ostream &O) { 69 bool Res = false; 70 const MCInst *NewMI = MI; 71 MCInst UncompressedMI; 72 if (!NoAliases) 73 Res = uncompressInst(UncompressedMI, *MI, MRI, STI); 74 if (Res) 75 NewMI = const_cast<MCInst *>(&UncompressedMI); 76 if (NoAliases || !printAliasInstr(NewMI, Address, STI, O)) 77 printInstruction(NewMI, Address, STI, O); 78 printAnnotation(O, Annot); 79 } 80 81 void RISCVInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { 82 O << getRegisterName(RegNo); 83 } 84 85 void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 86 const MCSubtargetInfo &STI, raw_ostream &O, 87 const char *Modifier) { 88 assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"); 89 const MCOperand &MO = MI->getOperand(OpNo); 90 91 if (MO.isReg()) { 92 printRegName(O, MO.getReg()); 93 return; 94 } 95 96 if (MO.isImm()) { 97 O << MO.getImm(); 98 return; 99 } 100 101 assert(MO.isExpr() && "Unknown operand kind in printOperand"); 102 MO.getExpr()->print(O, &MAI); 103 } 104 105 void RISCVInstPrinter::printCSRSystemRegister(const MCInst *MI, unsigned OpNo, 106 const MCSubtargetInfo &STI, 107 raw_ostream &O) { 108 unsigned Imm = MI->getOperand(OpNo).getImm(); 109 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 110 if (SysReg && SysReg->haveRequiredFeatures(STI.getFeatureBits())) 111 O << SysReg->Name; 112 else 113 O << Imm; 114 } 115 116 void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo, 117 const MCSubtargetInfo &STI, 118 raw_ostream &O) { 119 unsigned FenceArg = MI->getOperand(OpNo).getImm(); 120 assert (((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg"); 121 122 if ((FenceArg & RISCVFenceField::I) != 0) 123 O << 'i'; 124 if ((FenceArg & RISCVFenceField::O) != 0) 125 O << 'o'; 126 if ((FenceArg & RISCVFenceField::R) != 0) 127 O << 'r'; 128 if ((FenceArg & RISCVFenceField::W) != 0) 129 O << 'w'; 130 if (FenceArg == 0) 131 O << "unknown"; 132 } 133 134 void RISCVInstPrinter::printFRMArg(const MCInst *MI, unsigned OpNo, 135 const MCSubtargetInfo &STI, raw_ostream &O) { 136 auto FRMArg = 137 static_cast<RISCVFPRndMode::RoundingMode>(MI->getOperand(OpNo).getImm()); 138 O << RISCVFPRndMode::roundingModeToString(FRMArg); 139 } 140 141 void RISCVInstPrinter::printAtomicMemOp(const MCInst *MI, unsigned OpNo, 142 const MCSubtargetInfo &STI, 143 raw_ostream &O) { 144 const MCOperand &MO = MI->getOperand(OpNo); 145 146 assert(MO.isReg() && "printAtomicMemOp can only print register operands"); 147 O << "("; 148 printRegName(O, MO.getReg()); 149 O << ")"; 150 return; 151 } 152 153 void RISCVInstPrinter::printVTypeI(const MCInst *MI, unsigned OpNo, 154 const MCSubtargetInfo &STI, raw_ostream &O) { 155 unsigned Imm = MI->getOperand(OpNo).getImm(); 156 unsigned Sew = (Imm >> 2) & 0x7; 157 unsigned Lmul = Imm & 0x3; 158 159 Lmul = 0x1 << Lmul; 160 Sew = 0x1 << (Sew + 3); 161 O << "e" << Sew << ",m" << Lmul; 162 } 163 164 void RISCVInstPrinter::printVMaskReg(const MCInst *MI, unsigned OpNo, 165 const MCSubtargetInfo &STI, 166 raw_ostream &O) { 167 const MCOperand &MO = MI->getOperand(OpNo); 168 169 assert(MO.isReg() && "printVMaskReg can only print register operands"); 170 if (MO.getReg() == RISCV::NoRegister) 171 return; 172 O << ", "; 173 printRegName(O, MO.getReg()); 174 O << ".t"; 175 } 176 177 void RISCVInstPrinter::printSImm5Plus1(const MCInst *MI, unsigned OpNo, 178 const MCSubtargetInfo &STI, 179 raw_ostream &O) { 180 const MCOperand &MO = MI->getOperand(OpNo); 181 182 assert(MO.isImm() && "printSImm5Plus1 can only print constant operands"); 183 O << MO.getImm() + 1; 184 } 185 186 const char *RISCVInstPrinter::getRegisterName(unsigned RegNo) { 187 return getRegisterName(RegNo, ArchRegNames ? RISCV::NoRegAltName 188 : RISCV::ABIRegAltName); 189 } 190