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 const Register GPRDecoderTable[] = {
61  RISCV::X0, RISCV::X1, RISCV::X2, RISCV::X3,
62  RISCV::X4, RISCV::X5, RISCV::X6, RISCV::X7,
63  RISCV::X8, RISCV::X9, RISCV::X10, RISCV::X11,
64  RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15,
65  RISCV::X16, RISCV::X17, RISCV::X18, RISCV::X19,
66  RISCV::X20, RISCV::X21, RISCV::X22, RISCV::X23,
67  RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27,
68  RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31
69 };
70 
71 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
72  uint64_t Address,
73  const void *Decoder) {
74  const FeatureBitset &FeatureBits =
75  static_cast<const MCDisassembler *>(Decoder)
76  ->getSubtargetInfo()
77  .getFeatureBits();
78  bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
79 
80  if (RegNo > array_lengthof(GPRDecoderTable) || (IsRV32E && RegNo > 15))
81  return MCDisassembler::Fail;
82 
83  // We must define our own mapping from RegNo to register identifier.
84  // Accessing index RegNo in the register class will work in the case that
85  // registers were added in ascending order, but not in general.
86  Register Reg = GPRDecoderTable[RegNo];
89 }
90 
91 static const Register FPR32DecoderTable[] = {
92  RISCV::F0_32, RISCV::F1_32, RISCV::F2_32, RISCV::F3_32,
93  RISCV::F4_32, RISCV::F5_32, RISCV::F6_32, RISCV::F7_32,
94  RISCV::F8_32, RISCV::F9_32, RISCV::F10_32, RISCV::F11_32,
95  RISCV::F12_32, RISCV::F13_32, RISCV::F14_32, RISCV::F15_32,
96  RISCV::F16_32, RISCV::F17_32, RISCV::F18_32, RISCV::F19_32,
97  RISCV::F20_32, RISCV::F21_32, RISCV::F22_32, RISCV::F23_32,
98  RISCV::F24_32, RISCV::F25_32, RISCV::F26_32, RISCV::F27_32,
99  RISCV::F28_32, RISCV::F29_32, RISCV::F30_32, RISCV::F31_32
100 };
101 
102 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
103  uint64_t Address,
104  const void *Decoder) {
105  if (RegNo > array_lengthof(FPR32DecoderTable))
106  return MCDisassembler::Fail;
107 
108  // We must define our own mapping from RegNo to register identifier.
109  // Accessing index RegNo in the register class will work in the case that
110  // registers were added in ascending order, but not in general.
111  Register Reg = FPR32DecoderTable[RegNo];
112  Inst.addOperand(MCOperand::createReg(Reg));
114 }
115 
116 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo,
117  uint64_t Address,
118  const void *Decoder) {
119  if (RegNo > 8) {
120  return MCDisassembler::Fail;
121  }
122  Register Reg = FPR32DecoderTable[RegNo + 8];
123  Inst.addOperand(MCOperand::createReg(Reg));
125 }
126 
127 static const Register FPR64DecoderTable[] = {
128  RISCV::F0_64, RISCV::F1_64, RISCV::F2_64, RISCV::F3_64,
129  RISCV::F4_64, RISCV::F5_64, RISCV::F6_64, RISCV::F7_64,
130  RISCV::F8_64, RISCV::F9_64, RISCV::F10_64, RISCV::F11_64,
131  RISCV::F12_64, RISCV::F13_64, RISCV::F14_64, RISCV::F15_64,
132  RISCV::F16_64, RISCV::F17_64, RISCV::F18_64, RISCV::F19_64,
133  RISCV::F20_64, RISCV::F21_64, RISCV::F22_64, RISCV::F23_64,
134  RISCV::F24_64, RISCV::F25_64, RISCV::F26_64, RISCV::F27_64,
135  RISCV::F28_64, RISCV::F29_64, RISCV::F30_64, RISCV::F31_64
136 };
137 
138 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
139  uint64_t Address,
140  const void *Decoder) {
141  if (RegNo > array_lengthof(FPR64DecoderTable))
142  return MCDisassembler::Fail;
143 
144  // We must define our own mapping from RegNo to register identifier.
145  // Accessing index RegNo in the register class will work in the case that
146  // registers were added in ascending order, but not in general.
147  Register Reg = FPR64DecoderTable[RegNo];
148  Inst.addOperand(MCOperand::createReg(Reg));
150 }
151 
152 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo,
153  uint64_t Address,
154  const void *Decoder) {
155  if (RegNo > 8) {
156  return MCDisassembler::Fail;
157  }
158  Register Reg = FPR64DecoderTable[RegNo + 8];
159  Inst.addOperand(MCOperand::createReg(Reg));
161 }
162 
163 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo,
164  uint64_t Address,
165  const void *Decoder) {
166  if (RegNo == 0) {
167  return MCDisassembler::Fail;
168  }
169 
170  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
171 }
172 
173 static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo,
174  uint64_t Address,
175  const void *Decoder) {
176  if (RegNo == 2) {
177  return MCDisassembler::Fail;
178  }
179 
180  return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
181 }
182 
183 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
184  uint64_t Address,
185  const void *Decoder) {
186  if (RegNo > 8)
187  return MCDisassembler::Fail;
188 
189  Register Reg = GPRDecoderTable[RegNo + 8];
190  Inst.addOperand(MCOperand::createReg(Reg));
192 }
193 
194 // Add implied SP operand for instructions *SP compressed instructions. The SP
195 // operand isn't explicitly encoded in the instruction.
196 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
197  if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
198  Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
199  Inst.getOpcode() == RISCV::C_FLWSP ||
200  Inst.getOpcode() == RISCV::C_FSWSP ||
201  Inst.getOpcode() == RISCV::C_FLDSP ||
202  Inst.getOpcode() == RISCV::C_FSDSP ||
203  Inst.getOpcode() == RISCV::C_ADDI4SPN) {
204  DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
205  }
206  if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
207  DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
208  DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
209  }
210 }
211 
212 template <unsigned N>
213 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
214  int64_t Address, const void *Decoder) {
215  assert(isUInt<N>(Imm) && "Invalid immediate");
216  addImplySP(Inst, Address, Decoder);
217  Inst.addOperand(MCOperand::createImm(Imm));
219 }
220 
221 template <unsigned N>
222 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
223  int64_t Address,
224  const void *Decoder) {
225  if (Imm == 0)
226  return MCDisassembler::Fail;
227  return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
228 }
229 
230 template <unsigned N>
231 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
232  int64_t Address, const void *Decoder) {
233  assert(isUInt<N>(Imm) && "Invalid immediate");
234  addImplySP(Inst, Address, Decoder);
235  // Sign-extend the number in the bottom N bits of Imm
236  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
238 }
239 
240 template <unsigned N>
241 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
242  int64_t Address,
243  const void *Decoder) {
244  if (Imm == 0)
245  return MCDisassembler::Fail;
246  return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
247 }
248 
249 template <unsigned N>
250 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
251  int64_t Address,
252  const void *Decoder) {
253  assert(isUInt<N>(Imm) && "Invalid immediate");
254  // Sign-extend the number in the bottom N bits of Imm after accounting for
255  // the fact that the N bit immediate is stored in N-1 bits (the LSB is
256  // always zero)
257  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
259 }
260 
261 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
262  int64_t Address,
263  const void *Decoder) {
264  assert(isUInt<6>(Imm) && "Invalid immediate");
265  if (Imm > 31) {
266  Imm = (SignExtend64<6>(Imm) & 0xfffff);
267  }
268  Inst.addOperand(MCOperand::createImm(Imm));
270 }
271 
272 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm,
273  int64_t Address,
274  const void *Decoder) {
275  assert(isUInt<3>(Imm) && "Invalid immediate");
277  return MCDisassembler::Fail;
278 
279  Inst.addOperand(MCOperand::createImm(Imm));
281 }
282 
283 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
284  uint64_t Address, const void *Decoder);
285 
286 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
287  uint64_t Address, const void *Decoder);
288 
289 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
290  uint64_t Address,
291  const void *Decoder);
292 
293 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
294  uint64_t Address, const void *Decoder);
295 
296 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
297  uint64_t Address,
298  const void *Decoder);
299 
300 #include "RISCVGenDisassemblerTables.inc"
301 
302 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
303  uint64_t Address, const void *Decoder) {
304  uint64_t SImm6 =
305  fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
306  DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
307  (void)Result;
308  assert(Result == MCDisassembler::Success && "Invalid immediate");
310 }
311 
312 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
313  uint64_t Address,
314  const void *Decoder) {
315  DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
316  uint64_t SImm6 =
317  fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
318  DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
319  (void)Result;
320  assert(Result == MCDisassembler::Success && "Invalid immediate");
322 }
323 
324 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
325  uint64_t Address,
326  const void *Decoder) {
327  DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
328  Inst.addOperand(Inst.getOperand(0));
329  uint64_t UImm6 =
330  fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
331  DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
332  (void)Result;
333  assert(Result == MCDisassembler::Success && "Invalid immediate");
335 }
336 
337 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
338  uint64_t Address, const void *Decoder) {
339  unsigned Rd = fieldFromInstruction(Insn, 7, 5);
340  unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
341  DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
342  DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
344 }
345 
346 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
347  uint64_t Address,
348  const void *Decoder) {
349  unsigned Rd = fieldFromInstruction(Insn, 7, 5);
350  unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
351  DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
352  Inst.addOperand(Inst.getOperand(0));
353  DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
355 }
356 
357 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
358  ArrayRef<uint8_t> Bytes,
359  uint64_t Address,
360  raw_ostream &OS,
361  raw_ostream &CS) const {
362  // TODO: This will need modification when supporting instruction set
363  // extensions with instructions > 32-bits (up to 176 bits wide).
364  uint32_t Insn;
365  DecodeStatus Result;
366 
367  // It's a 32 bit instruction if bit 0 and 1 are 1.
368  if ((Bytes[0] & 0x3) == 0x3) {
369  if (Bytes.size() < 4) {
370  Size = 0;
371  return MCDisassembler::Fail;
372  }
373  Insn = support::endian::read32le(Bytes.data());
374  LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
375  Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
376  Size = 4;
377  } else {
378  if (Bytes.size() < 2) {
379  Size = 0;
380  return MCDisassembler::Fail;
381  }
382  Insn = support::endian::read16le(Bytes.data());
383 
384  if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
385  LLVM_DEBUG(
386  dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
387  // Calling the auto-generated decoder function.
388  Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
389  this, STI);
390  if (Result != MCDisassembler::Fail) {
391  Size = 2;
392  return Result;
393  }
394  }
395 
396  LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
397  // Calling the auto-generated decoder function.
398  Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
399  Size = 2;
400  }
401 
402  return Result;
403 }
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 const Register GPRDecoderTable[]
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)
static const Register FPR32DecoderTable[]
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
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:1035
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 const Register FPR64DecoderTable[]
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)