1 //===-- RISCVMCTargetDesc.cpp - RISC-V Target Descriptions ----------------===// 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 file provides RISC-V specific target descriptions. 10 /// 11 //===----------------------------------------------------------------------===// 12 13 #include "RISCVMCTargetDesc.h" 14 #include "RISCVELFStreamer.h" 15 #include "RISCVInstPrinter.h" 16 #include "RISCVMCAsmInfo.h" 17 #include "RISCVMCObjectFileInfo.h" 18 #include "RISCVTargetStreamer.h" 19 #include "TargetInfo/RISCVTargetInfo.h" 20 #include "llvm/MC/MCAsmBackend.h" 21 #include "llvm/MC/MCAsmInfo.h" 22 #include "llvm/MC/MCCodeEmitter.h" 23 #include "llvm/MC/MCInstrAnalysis.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCObjectFileInfo.h" 26 #include "llvm/MC/MCObjectWriter.h" 27 #include "llvm/MC/MCRegisterInfo.h" 28 #include "llvm/MC/MCStreamer.h" 29 #include "llvm/MC/MCSubtargetInfo.h" 30 #include "llvm/MC/TargetRegistry.h" 31 #include "llvm/Support/Compiler.h" 32 #include "llvm/Support/ErrorHandling.h" 33 #include <bitset> 34 35 #define GET_INSTRINFO_MC_DESC 36 #define ENABLE_INSTR_PREDICATE_VERIFIER 37 #include "RISCVGenInstrInfo.inc" 38 39 #define GET_REGINFO_MC_DESC 40 #include "RISCVGenRegisterInfo.inc" 41 42 #define GET_SUBTARGETINFO_MC_DESC 43 #include "RISCVGenSubtargetInfo.inc" 44 45 using namespace llvm; 46 47 static MCInstrInfo *createRISCVMCInstrInfo() { 48 MCInstrInfo *X = new MCInstrInfo(); 49 InitRISCVMCInstrInfo(X); 50 return X; 51 } 52 53 static MCRegisterInfo *createRISCVMCRegisterInfo(const Triple &TT) { 54 MCRegisterInfo *X = new MCRegisterInfo(); 55 InitRISCVMCRegisterInfo(X, RISCV::X1); 56 return X; 57 } 58 59 static MCAsmInfo *createRISCVMCAsmInfo(const MCRegisterInfo &MRI, 60 const Triple &TT, 61 const MCTargetOptions &Options) { 62 MCAsmInfo *MAI = new RISCVMCAsmInfo(TT); 63 64 unsigned SP = MRI.getDwarfRegNum(RISCV::X2, true); 65 MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, SP, 0); 66 MAI->addInitialFrameState(Inst); 67 68 return MAI; 69 } 70 71 static MCObjectFileInfo * 72 createRISCVMCObjectFileInfo(MCContext &Ctx, bool PIC, 73 bool LargeCodeModel = false) { 74 MCObjectFileInfo *MOFI = new RISCVMCObjectFileInfo(); 75 MOFI->initMCObjectFileInfo(Ctx, PIC, LargeCodeModel); 76 return MOFI; 77 } 78 79 static MCSubtargetInfo *createRISCVMCSubtargetInfo(const Triple &TT, 80 StringRef CPU, StringRef FS) { 81 if (CPU.empty() || CPU == "generic") 82 CPU = TT.isArch64Bit() ? "generic-rv64" : "generic-rv32"; 83 84 MCSubtargetInfo *X = 85 createRISCVMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS); 86 87 // If the CPU is "help" fill in 64 or 32 bit feature so we can pass 88 // RISCVFeatures::validate. 89 // FIXME: Why does llvm-mc still expect a source file with -mcpu=help? 90 if (CPU == "help") { 91 llvm::FeatureBitset Features = X->getFeatureBits(); 92 if (TT.isArch64Bit()) 93 Features.set(RISCV::Feature64Bit); 94 else 95 Features.set(RISCV::Feature32Bit); 96 X->setFeatureBits(Features); 97 } 98 99 return X; 100 } 101 102 static MCInstPrinter *createRISCVMCInstPrinter(const Triple &T, 103 unsigned SyntaxVariant, 104 const MCAsmInfo &MAI, 105 const MCInstrInfo &MII, 106 const MCRegisterInfo &MRI) { 107 return new RISCVInstPrinter(MAI, MII, MRI); 108 } 109 110 static MCTargetStreamer * 111 createRISCVObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { 112 const Triple &TT = STI.getTargetTriple(); 113 if (TT.isOSBinFormatELF()) 114 return new RISCVTargetELFStreamer(S, STI); 115 return nullptr; 116 } 117 118 static MCTargetStreamer * 119 createRISCVAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, 120 MCInstPrinter *InstPrint) { 121 return new RISCVTargetAsmStreamer(S, OS); 122 } 123 124 static MCTargetStreamer *createRISCVNullTargetStreamer(MCStreamer &S) { 125 return new RISCVTargetStreamer(S); 126 } 127 128 namespace { 129 130 class RISCVMCInstrAnalysis : public MCInstrAnalysis { 131 int64_t GPRState[31] = {}; 132 std::bitset<31> GPRValidMask; 133 134 static bool isGPR(MCRegister Reg) { 135 return Reg >= RISCV::X0 && Reg <= RISCV::X31; 136 } 137 138 static unsigned getRegIndex(MCRegister Reg) { 139 assert(isGPR(Reg) && Reg != RISCV::X0 && "Invalid GPR reg"); 140 return Reg - RISCV::X1; 141 } 142 143 void setGPRState(MCRegister Reg, std::optional<int64_t> Value) { 144 if (Reg == RISCV::X0) 145 return; 146 147 auto Index = getRegIndex(Reg); 148 149 if (Value) { 150 GPRState[Index] = *Value; 151 GPRValidMask.set(Index); 152 } else { 153 GPRValidMask.reset(Index); 154 } 155 } 156 157 std::optional<int64_t> getGPRState(MCRegister Reg) const { 158 if (Reg == RISCV::X0) 159 return 0; 160 161 auto Index = getRegIndex(Reg); 162 163 if (GPRValidMask.test(Index)) 164 return GPRState[Index]; 165 return std::nullopt; 166 } 167 168 public: 169 explicit RISCVMCInstrAnalysis(const MCInstrInfo *Info) 170 : MCInstrAnalysis(Info) {} 171 172 void resetState() override { GPRValidMask.reset(); } 173 174 void updateState(const MCInst &Inst, uint64_t Addr) override { 175 // Terminators mark the end of a basic block which means the sequentially 176 // next instruction will be the first of another basic block and the current 177 // state will typically not be valid anymore. For calls, we assume all 178 // registers may be clobbered by the callee (TODO: should we take the 179 // calling convention into account?). 180 if (isTerminator(Inst) || isCall(Inst)) { 181 resetState(); 182 return; 183 } 184 185 switch (Inst.getOpcode()) { 186 default: { 187 // Clear the state of all defined registers for instructions that we don't 188 // explicitly support. 189 auto NumDefs = Info->get(Inst.getOpcode()).getNumDefs(); 190 for (unsigned I = 0; I < NumDefs; ++I) { 191 auto DefReg = Inst.getOperand(I).getReg(); 192 if (isGPR(DefReg)) 193 setGPRState(DefReg, std::nullopt); 194 } 195 break; 196 } 197 case RISCV::AUIPC: 198 setGPRState(Inst.getOperand(0).getReg(), 199 Addr + SignExtend64<32>(Inst.getOperand(1).getImm() << 12)); 200 break; 201 } 202 } 203 204 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, 205 uint64_t &Target) const override { 206 if (isConditionalBranch(Inst)) { 207 int64_t Imm; 208 if (Size == 2) 209 Imm = Inst.getOperand(1).getImm(); 210 else 211 Imm = Inst.getOperand(2).getImm(); 212 Target = Addr + Imm; 213 return true; 214 } 215 216 switch (Inst.getOpcode()) { 217 case RISCV::C_J: 218 case RISCV::C_JAL: 219 case RISCV::QC_E_J: 220 case RISCV::QC_E_JAL: 221 Target = Addr + Inst.getOperand(0).getImm(); 222 return true; 223 case RISCV::JAL: 224 Target = Addr + Inst.getOperand(1).getImm(); 225 return true; 226 case RISCV::JALR: { 227 if (auto TargetRegState = getGPRState(Inst.getOperand(1).getReg())) { 228 Target = *TargetRegState + Inst.getOperand(2).getImm(); 229 return true; 230 } 231 return false; 232 } 233 } 234 235 return false; 236 } 237 238 bool isTerminator(const MCInst &Inst) const override { 239 if (MCInstrAnalysis::isTerminator(Inst)) 240 return true; 241 242 switch (Inst.getOpcode()) { 243 default: 244 return false; 245 case RISCV::JAL: 246 case RISCV::JALR: 247 return Inst.getOperand(0).getReg() == RISCV::X0; 248 } 249 } 250 251 bool isCall(const MCInst &Inst) const override { 252 if (MCInstrAnalysis::isCall(Inst)) 253 return true; 254 255 switch (Inst.getOpcode()) { 256 default: 257 return false; 258 case RISCV::JAL: 259 case RISCV::JALR: 260 return Inst.getOperand(0).getReg() != RISCV::X0; 261 } 262 } 263 264 bool isReturn(const MCInst &Inst) const override { 265 if (MCInstrAnalysis::isReturn(Inst)) 266 return true; 267 268 switch (Inst.getOpcode()) { 269 default: 270 return false; 271 case RISCV::JALR: 272 return Inst.getOperand(0).getReg() == RISCV::X0 && 273 maybeReturnAddress(Inst.getOperand(1).getReg()); 274 case RISCV::C_JR: 275 return maybeReturnAddress(Inst.getOperand(0).getReg()); 276 } 277 } 278 279 bool isBranch(const MCInst &Inst) const override { 280 if (MCInstrAnalysis::isBranch(Inst)) 281 return true; 282 283 return isBranchImpl(Inst); 284 } 285 286 bool isUnconditionalBranch(const MCInst &Inst) const override { 287 if (MCInstrAnalysis::isUnconditionalBranch(Inst)) 288 return true; 289 290 return isBranchImpl(Inst); 291 } 292 293 bool isIndirectBranch(const MCInst &Inst) const override { 294 if (MCInstrAnalysis::isIndirectBranch(Inst)) 295 return true; 296 297 switch (Inst.getOpcode()) { 298 default: 299 return false; 300 case RISCV::JALR: 301 return Inst.getOperand(0).getReg() == RISCV::X0 && 302 !maybeReturnAddress(Inst.getOperand(1).getReg()); 303 case RISCV::C_JR: 304 return !maybeReturnAddress(Inst.getOperand(0).getReg()); 305 } 306 } 307 308 private: 309 static bool maybeReturnAddress(MCRegister Reg) { 310 // X1 is used for normal returns, X5 for returns from outlined functions. 311 return Reg == RISCV::X1 || Reg == RISCV::X5; 312 } 313 314 static bool isBranchImpl(const MCInst &Inst) { 315 switch (Inst.getOpcode()) { 316 default: 317 return false; 318 case RISCV::JAL: 319 return Inst.getOperand(0).getReg() == RISCV::X0; 320 case RISCV::JALR: 321 return Inst.getOperand(0).getReg() == RISCV::X0 && 322 !maybeReturnAddress(Inst.getOperand(1).getReg()); 323 case RISCV::C_JR: 324 return !maybeReturnAddress(Inst.getOperand(0).getReg()); 325 } 326 } 327 }; 328 329 } // end anonymous namespace 330 331 static MCInstrAnalysis *createRISCVInstrAnalysis(const MCInstrInfo *Info) { 332 return new RISCVMCInstrAnalysis(Info); 333 } 334 335 extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void 336 LLVMInitializeRISCVTargetMC() { 337 for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target()}) { 338 TargetRegistry::RegisterMCAsmInfo(*T, createRISCVMCAsmInfo); 339 TargetRegistry::RegisterMCObjectFileInfo(*T, createRISCVMCObjectFileInfo); 340 TargetRegistry::RegisterMCInstrInfo(*T, createRISCVMCInstrInfo); 341 TargetRegistry::RegisterMCRegInfo(*T, createRISCVMCRegisterInfo); 342 TargetRegistry::RegisterMCAsmBackend(*T, createRISCVAsmBackend); 343 TargetRegistry::RegisterMCCodeEmitter(*T, createRISCVMCCodeEmitter); 344 TargetRegistry::RegisterMCInstPrinter(*T, createRISCVMCInstPrinter); 345 TargetRegistry::RegisterMCSubtargetInfo(*T, createRISCVMCSubtargetInfo); 346 TargetRegistry::RegisterELFStreamer(*T, createRISCVELFStreamer); 347 TargetRegistry::RegisterObjectTargetStreamer( 348 *T, createRISCVObjectTargetStreamer); 349 TargetRegistry::RegisterMCInstrAnalysis(*T, createRISCVInstrAnalysis); 350 351 // Register the asm target streamer. 352 TargetRegistry::RegisterAsmTargetStreamer(*T, createRISCVAsmTargetStreamer); 353 // Register the null target streamer. 354 TargetRegistry::RegisterNullTargetStreamer(*T, 355 createRISCVNullTargetStreamer); 356 } 357 } 358