LLVM  10.0.0svn
RISCVDisassembler.cpp
Go to the documentation of this file.
1 //===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===//
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 implements the RISCVDisassembler class.
10 //
11 //===----------------------------------------------------------------------===//
12 
15 #include "Utils/RISCVBaseInfo.h"
16 #include "llvm/CodeGen/Register.h"
17 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/Support/Endian.h"
25 
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "riscv-disassembler"
29 
31 
32 namespace {
33 class RISCVDisassembler : public MCDisassembler {
34 
35 public:
36  RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
37  : MCDisassembler(STI, Ctx) {}
38 
39  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
40  ArrayRef<uint8_t> Bytes, uint64_t Address,
41  raw_ostream &VStream,
42  raw_ostream &CStream) const override;
43 };
44 } // end anonymous namespace
45 
47  const MCSubtargetInfo &STI,
48  MCContext &Ctx) {
49  return new RISCVDisassembler(STI, Ctx);
50 }
51 
53  // Register the disassembler for each target.
58 }
59 
60 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
61  uint64_t Address,
62  const void *Decoder) {
63  const FeatureBitset &FeatureBits =
64  static_cast<const MCDisassembler *>(Decoder)
65  ->getSubtargetInfo()
66  .getFeatureBits();
67  bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
68 
69  if (RegNo >= 32 || (IsRV32E && RegNo >= 16))
70  return MCDisassembler::Fail;
71 
72  Register Reg = RISCV::X0 + RegNo;
75 }
76 
77 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
78  uint64_t Address,
79  const void *Decoder) {
80  if (RegNo >= 32)
81  return MCDisassembler::Fail;
82 
83  Register Reg = RISCV::F0_F + RegNo;
86 }
87 
88 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo,
89  uint64_t Address,
90  const void *Decoder) {
91  if (RegNo >= 8) {
92  return MCDisassembler::Fail;
93  }
94  Register Reg = RISCV::F8_F + RegNo;
97 }
98 
99 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
100  uint64_t Address,
101  const void *Decoder) {
102  if (RegNo >= 32)
103  return MCDisassembler::Fail;
104 
105  Register Reg = RISCV::F0_D + RegNo;
106  Inst.addOperand(MCOperand::createReg(Reg));
108 }
109 
110 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo,
111  uint64_t Address,
112  const void *Decoder) {
113  if (RegNo >= 8) {
114  return MCDisassembler::Fail;
115  }
116  Register Reg = RISCV::F8_D + RegNo;
117  Inst.addOperand(MCOperand::createReg(Reg));
119 }
120 
121 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo,
122  uint64_t Address,
123  const void *Decoder) {
124  if (RegNo == 0) {
125  return MCDisassembler::Fail;
126  }
127 
128  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
129 }
130 
131 static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo,
132  uint64_t Address,
133  const void *Decoder) {
134  if (RegNo == 2) {
135  return MCDisassembler::Fail;
136  }
137 
138  return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
139 }
140 
141 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
142  uint64_t Address,
143  const void *Decoder) {
144  if (RegNo >= 8)
145  return MCDisassembler::Fail;
146 
147  Register Reg = RISCV::X8 + RegNo;
148  Inst.addOperand(MCOperand::createReg(Reg));
150 }
151 
152 // Add implied SP operand for instructions *SP compressed instructions. The SP
153 // operand isn't explicitly encoded in the instruction.
154 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
155  if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
156  Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
157  Inst.getOpcode() == RISCV::C_FLWSP ||
158  Inst.getOpcode() == RISCV::C_FSWSP ||
159  Inst.getOpcode() == RISCV::C_FLDSP ||
160  Inst.getOpcode() == RISCV::C_FSDSP ||
161  Inst.getOpcode() == RISCV::C_ADDI4SPN) {
162  DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
163  }
164  if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
165  DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
166  DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
167  }
168 }
169 
170 template <unsigned N>
171 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
172  int64_t Address, const void *Decoder) {
173  assert(isUInt<N>(Imm) && "Invalid immediate");
174  addImplySP(Inst, Address, Decoder);
175  Inst.addOperand(MCOperand::createImm(Imm));
177 }
178 
179 template <unsigned N>
180 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
181  int64_t Address,
182  const void *Decoder) {
183  if (Imm == 0)
184  return MCDisassembler::Fail;
185  return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
186 }
187 
188 template <unsigned N>
189 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
190  int64_t Address, const void *Decoder) {
191  assert(isUInt<N>(Imm) && "Invalid immediate");
192  addImplySP(Inst, Address, Decoder);
193  // Sign-extend the number in the bottom N bits of Imm
194  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
196 }
197 
198 template <unsigned N>
199 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
200  int64_t Address,
201  const void *Decoder) {
202  if (Imm == 0)
203  return MCDisassembler::Fail;
204  return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
205 }
206 
207 template <unsigned N>
208 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
209  int64_t Address,
210  const void *Decoder) {
211  assert(isUInt<N>(Imm) && "Invalid immediate");
212  // Sign-extend the number in the bottom N bits of Imm after accounting for
213  // the fact that the N bit immediate is stored in N-1 bits (the LSB is
214  // always zero)
215  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
217 }
218 
219 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
220  int64_t Address,
221  const void *Decoder) {
222  assert(isUInt<6>(Imm) && "Invalid immediate");
223  if (Imm > 31) {
224  Imm = (SignExtend64<6>(Imm) & 0xfffff);
225  }
226  Inst.addOperand(MCOperand::createImm(Imm));
228 }
229 
230 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm,
231  int64_t Address,
232  const void *Decoder) {
233  assert(isUInt<3>(Imm) && "Invalid immediate");
235  return MCDisassembler::Fail;
236 
237  Inst.addOperand(MCOperand::createImm(Imm));
239 }
240 
241 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
242  uint64_t Address, const void *Decoder);
243 
244 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
245  uint64_t Address, const void *Decoder);
246 
247 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
248  uint64_t Address,
249  const void *Decoder);
250 
251 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
252  uint64_t Address, const void *Decoder);
253 
254 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
255  uint64_t Address,
256  const void *Decoder);
257 
258 #include "RISCVGenDisassemblerTables.inc"
259 
260 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
261  uint64_t Address, const void *Decoder) {
262  uint64_t SImm6 =
263  fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
264  DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
265  (void)Result;
266  assert(Result == MCDisassembler::Success && "Invalid immediate");
268 }
269 
270 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
271  uint64_t Address,
272  const void *Decoder) {
273  DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
274  uint64_t SImm6 =
275  fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
276  DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
277  (void)Result;
278  assert(Result == MCDisassembler::Success && "Invalid immediate");
280 }
281 
282 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
283  uint64_t Address,
284  const void *Decoder) {
285  DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
286  Inst.addOperand(Inst.getOperand(0));
287  uint64_t UImm6 =
288  fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
289  DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
290  (void)Result;
291  assert(Result == MCDisassembler::Success && "Invalid immediate");
293 }
294 
295 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
296  uint64_t Address, const void *Decoder) {
297  unsigned Rd = fieldFromInstruction(Insn, 7, 5);
298  unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
299  DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
300  DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
302 }
303 
304 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
305  uint64_t Address,
306  const void *Decoder) {
307  unsigned Rd = fieldFromInstruction(Insn, 7, 5);
308  unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
309  DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
310  Inst.addOperand(Inst.getOperand(0));
311  DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
313 }
314 
315 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
316  ArrayRef<uint8_t> Bytes,
317  uint64_t Address,
318  raw_ostream &OS,
319  raw_ostream &CS) const {
320  // TODO: This will need modification when supporting instruction set
321  // extensions with instructions > 32-bits (up to 176 bits wide).
322  uint32_t Insn;
323  DecodeStatus Result;
324 
325  // It's a 32 bit instruction if bit 0 and 1 are 1.
326  if ((Bytes[0] & 0x3) == 0x3) {
327  if (Bytes.size() < 4) {
328  Size = 0;
329  return MCDisassembler::Fail;
330  }
331  Insn = support::endian::read32le(Bytes.data());
332  LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
333  Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
334  Size = 4;
335  } else {
336  if (Bytes.size() < 2) {
337  Size = 0;
338  return MCDisassembler::Fail;
339  }
340  Insn = support::endian::read16le(Bytes.data());
341 
342  if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
343  LLVM_DEBUG(
344  dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
345  // Calling the auto-generated decoder function.
346  Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
347  this, STI);
348  if (Result != MCDisassembler::Fail) {
349  Size = 2;
350  return Result;
351  }
352  }
353 
354  LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
355  // Calling the auto-generated decoder function.
356  Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
357  Size = 2;
358  }
359 
360  return Result;
361 }
static MCDisassembler * createRISCVDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static bool isValidRoundingMode(unsigned Mode)
static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
DecodeStatus
Ternary decode status.
MCDisassembler::DecodeStatus DecodeStatus
Superclass for all disassemblers.
unsigned Reg
static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
uint16_t read16le(const void *P)
Definition: Endian.h:382
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:115
void LLVMInitializeRISCVDisassembler()
Target & getTheRISCV32Target()
Context object for machine code objects.
Definition: MCContext.h:65
int decodeInstruction(InternalInstruction *insn, byteReader_t reader, const void *readerArg, dlog_t logger, void *loggerArg, const void *miiArg, uint64_t startLoc, DisassemblerMode mode)
Decode one instruction and store the decoding results in a buffer provided by the consumer...
static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Container class for subtarget features.
static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
Target & getTheRISCV64Target()
static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
const T * data() const
Definition: ArrayRef.h:145
static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:179
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Target - Wrapper for Target specific information.
static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder)
uint32_t read32le(const void *P)
Definition: Endian.h:383
Generic base class for all target subtargets.
static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
uint32_t Size
Definition: Profile.cpp:46
static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:183
unsigned getOpcode() const
Definition: MCInst.h:171
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
#define LLVM_DEBUG(X)
Definition: Debug.h:122
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:122
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)