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
46using namespace llvm;
47
48static MCInstrInfo *createRISCVMCInstrInfo() {
49  MCInstrInfo *X = new MCInstrInfo();
50  InitRISCVMCInstrInfo(X);
51  return X;
52}
53
54static MCRegisterInfo *createRISCVMCRegisterInfo(const Triple &TT) {
55  MCRegisterInfo *X = new MCRegisterInfo();
56  InitRISCVMCRegisterInfo(X, RISCV::X1);
57  return X;
58}
59
60static 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
72static MCObjectFileInfo *
73createRISCVMCObjectFileInfo(MCContext &Ctx, bool PIC,
74                            bool LargeCodeModel = false) {
75  MCObjectFileInfo *MOFI = new RISCVMCObjectFileInfo();
76  MOFI->initMCObjectFileInfo(Ctx, PIC, LargeCodeModel);
77  return MOFI;
78}
79
80static 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
88static 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
96static MCTargetStreamer *
97createRISCVObjectTargetStreamer(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
104static MCTargetStreamer *createRISCVAsmTargetStreamer(MCStreamer &S,
105                                                      formatted_raw_ostream &OS,
106                                                      MCInstPrinter *InstPrint,
107                                                      bool isVerboseAsm) {
108  return new RISCVTargetAsmStreamer(S, OS);
109}
110
111static MCTargetStreamer *createRISCVNullTargetStreamer(MCStreamer &S) {
112  return new RISCVTargetStreamer(S);
113}
114
115namespace {
116
117class 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
155public:
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
295private:
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
318static MCInstrAnalysis *createRISCVInstrAnalysis(const MCInstrInfo *Info) {
319  return new RISCVMCInstrAnalysis(Info);
320}
321
322namespace {
323MCStreamer *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
333extern "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