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