[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / RISCV / Disassembler / RISCVDisassembler.cpp
blob504a78d91f3217d18fe1ea5e514a1fa19ed81d27
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.
11 //===----------------------------------------------------------------------===//
13 #include "MCTargetDesc/RISCVBaseInfo.h"
14 #include "MCTargetDesc/RISCVMCTargetDesc.h"
15 #include "TargetInfo/RISCVTargetInfo.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
18 #include "llvm/MC/MCFixedLenDisassembler.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/Support/Endian.h"
24 #include "llvm/Support/TargetRegistry.h"
26 using namespace llvm;
28 #define DEBUG_TYPE "riscv-disassembler"
30 typedef MCDisassembler::DecodeStatus DecodeStatus;
32 namespace {
33 class RISCVDisassembler : public MCDisassembler {
34 std::unique_ptr<MCInstrInfo const> const MCII;
36 public:
37 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
38 MCInstrInfo const *MCII)
39 : MCDisassembler(STI, Ctx), MCII(MCII) {}
41 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
42 ArrayRef<uint8_t> Bytes, uint64_t Address,
43 raw_ostream &CStream) const override;
45 } // end anonymous namespace
47 static MCDisassembler *createRISCVDisassembler(const Target &T,
48 const MCSubtargetInfo &STI,
49 MCContext &Ctx) {
50 return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
53 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {
54 // Register the disassembler for each target.
55 TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
56 createRISCVDisassembler);
57 TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
58 createRISCVDisassembler);
61 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
62 uint64_t Address,
63 const void *Decoder) {
64 const FeatureBitset &FeatureBits =
65 static_cast<const MCDisassembler *>(Decoder)
66 ->getSubtargetInfo()
67 .getFeatureBits();
68 bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
70 if (RegNo >= 32 || (IsRV32E && RegNo >= 16))
71 return MCDisassembler::Fail;
73 MCRegister Reg = RISCV::X0 + RegNo;
74 Inst.addOperand(MCOperand::createReg(Reg));
75 return MCDisassembler::Success;
78 static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint64_t RegNo,
79 uint64_t Address,
80 const void *Decoder) {
81 if (RegNo >= 32)
82 return MCDisassembler::Fail;
84 MCRegister Reg = RISCV::F0_H + RegNo;
85 Inst.addOperand(MCOperand::createReg(Reg));
86 return MCDisassembler::Success;
89 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
90 uint64_t Address,
91 const void *Decoder) {
92 if (RegNo >= 32)
93 return MCDisassembler::Fail;
95 MCRegister Reg = RISCV::F0_F + RegNo;
96 Inst.addOperand(MCOperand::createReg(Reg));
97 return MCDisassembler::Success;
100 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo,
101 uint64_t Address,
102 const void *Decoder) {
103 if (RegNo >= 8) {
104 return MCDisassembler::Fail;
106 MCRegister Reg = RISCV::F8_F + RegNo;
107 Inst.addOperand(MCOperand::createReg(Reg));
108 return MCDisassembler::Success;
111 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
112 uint64_t Address,
113 const void *Decoder) {
114 if (RegNo >= 32)
115 return MCDisassembler::Fail;
117 MCRegister Reg = RISCV::F0_D + RegNo;
118 Inst.addOperand(MCOperand::createReg(Reg));
119 return MCDisassembler::Success;
122 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo,
123 uint64_t Address,
124 const void *Decoder) {
125 if (RegNo >= 8) {
126 return MCDisassembler::Fail;
128 MCRegister Reg = RISCV::F8_D + RegNo;
129 Inst.addOperand(MCOperand::createReg(Reg));
130 return MCDisassembler::Success;
133 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo,
134 uint64_t Address,
135 const void *Decoder) {
136 if (RegNo == 0) {
137 return MCDisassembler::Fail;
140 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
143 static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo,
144 uint64_t Address,
145 const void *Decoder) {
146 if (RegNo == 2) {
147 return MCDisassembler::Fail;
150 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
153 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
154 uint64_t Address,
155 const void *Decoder) {
156 if (RegNo >= 8)
157 return MCDisassembler::Fail;
159 MCRegister Reg = RISCV::X8 + RegNo;
160 Inst.addOperand(MCOperand::createReg(Reg));
161 return MCDisassembler::Success;
164 static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo,
165 uint64_t Address,
166 const void *Decoder) {
167 if (RegNo >= 32)
168 return MCDisassembler::Fail;
170 MCRegister Reg = RISCV::V0 + RegNo;
171 Inst.addOperand(MCOperand::createReg(Reg));
172 return MCDisassembler::Success;
175 static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint64_t RegNo,
176 uint64_t Address,
177 const void *Decoder) {
178 if (RegNo >= 32)
179 return MCDisassembler::Fail;
181 if (RegNo % 2)
182 return MCDisassembler::Fail;
184 const RISCVDisassembler *Dis =
185 static_cast<const RISCVDisassembler *>(Decoder);
186 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
187 MCRegister Reg =
188 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
189 &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
191 Inst.addOperand(MCOperand::createReg(Reg));
192 return MCDisassembler::Success;
195 static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint64_t RegNo,
196 uint64_t Address,
197 const void *Decoder) {
198 if (RegNo >= 32)
199 return MCDisassembler::Fail;
201 if (RegNo % 4)
202 return MCDisassembler::Fail;
204 const RISCVDisassembler *Dis =
205 static_cast<const RISCVDisassembler *>(Decoder);
206 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
207 MCRegister Reg =
208 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
209 &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);
211 Inst.addOperand(MCOperand::createReg(Reg));
212 return MCDisassembler::Success;
215 static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint64_t RegNo,
216 uint64_t Address,
217 const void *Decoder) {
218 if (RegNo >= 32)
219 return MCDisassembler::Fail;
221 if (RegNo % 8)
222 return MCDisassembler::Fail;
224 const RISCVDisassembler *Dis =
225 static_cast<const RISCVDisassembler *>(Decoder);
226 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
227 MCRegister Reg =
228 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
229 &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
231 Inst.addOperand(MCOperand::createReg(Reg));
232 return MCDisassembler::Success;
235 static DecodeStatus decodeVMaskReg(MCInst &Inst, uint64_t RegNo,
236 uint64_t Address, const void *Decoder) {
237 MCRegister Reg = RISCV::NoRegister;
238 switch (RegNo) {
239 default:
240 return MCDisassembler::Fail;
241 case 0:
242 Reg = RISCV::V0;
243 break;
244 case 1:
245 break;
247 Inst.addOperand(MCOperand::createReg(Reg));
248 return MCDisassembler::Success;
251 // Add implied SP operand for instructions *SP compressed instructions. The SP
252 // operand isn't explicitly encoded in the instruction.
253 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
254 if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
255 Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
256 Inst.getOpcode() == RISCV::C_FLWSP ||
257 Inst.getOpcode() == RISCV::C_FSWSP ||
258 Inst.getOpcode() == RISCV::C_FLDSP ||
259 Inst.getOpcode() == RISCV::C_FSDSP ||
260 Inst.getOpcode() == RISCV::C_ADDI4SPN) {
261 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
263 if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
264 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
265 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
269 template <unsigned N>
270 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
271 int64_t Address, const void *Decoder) {
272 assert(isUInt<N>(Imm) && "Invalid immediate");
273 addImplySP(Inst, Address, Decoder);
274 Inst.addOperand(MCOperand::createImm(Imm));
275 return MCDisassembler::Success;
278 template <unsigned N>
279 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
280 int64_t Address,
281 const void *Decoder) {
282 if (Imm == 0)
283 return MCDisassembler::Fail;
284 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
287 template <unsigned N>
288 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
289 int64_t Address, const void *Decoder) {
290 assert(isUInt<N>(Imm) && "Invalid immediate");
291 addImplySP(Inst, Address, Decoder);
292 // Sign-extend the number in the bottom N bits of Imm
293 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
294 return MCDisassembler::Success;
297 template <unsigned N>
298 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
299 int64_t Address,
300 const void *Decoder) {
301 if (Imm == 0)
302 return MCDisassembler::Fail;
303 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
306 template <unsigned N>
307 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
308 int64_t Address,
309 const void *Decoder) {
310 assert(isUInt<N>(Imm) && "Invalid immediate");
311 // Sign-extend the number in the bottom N bits of Imm after accounting for
312 // the fact that the N bit immediate is stored in N-1 bits (the LSB is
313 // always zero)
314 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
315 return MCDisassembler::Success;
318 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
319 int64_t Address,
320 const void *Decoder) {
321 assert(isUInt<6>(Imm) && "Invalid immediate");
322 if (Imm > 31) {
323 Imm = (SignExtend64<6>(Imm) & 0xfffff);
325 Inst.addOperand(MCOperand::createImm(Imm));
326 return MCDisassembler::Success;
329 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm,
330 int64_t Address,
331 const void *Decoder) {
332 assert(isUInt<3>(Imm) && "Invalid immediate");
333 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
334 return MCDisassembler::Fail;
336 Inst.addOperand(MCOperand::createImm(Imm));
337 return MCDisassembler::Success;
340 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
341 uint64_t Address, const void *Decoder);
343 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
344 uint64_t Address, const void *Decoder);
346 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
347 uint64_t Address,
348 const void *Decoder);
350 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
351 uint64_t Address, const void *Decoder);
353 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
354 uint64_t Address,
355 const void *Decoder);
357 #include "RISCVGenDisassemblerTables.inc"
359 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
360 uint64_t Address, const void *Decoder) {
361 uint64_t SImm6 =
362 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
363 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
364 (void)Result;
365 assert(Result == MCDisassembler::Success && "Invalid immediate");
366 return MCDisassembler::Success;
369 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
370 uint64_t Address,
371 const void *Decoder) {
372 DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
373 uint64_t SImm6 =
374 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
375 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
376 (void)Result;
377 assert(Result == MCDisassembler::Success && "Invalid immediate");
378 return MCDisassembler::Success;
381 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
382 uint64_t Address,
383 const void *Decoder) {
384 DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
385 Inst.addOperand(Inst.getOperand(0));
386 uint64_t UImm6 =
387 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
388 DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
389 (void)Result;
390 assert(Result == MCDisassembler::Success && "Invalid immediate");
391 return MCDisassembler::Success;
394 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
395 uint64_t Address, const void *Decoder) {
396 unsigned Rd = fieldFromInstruction(Insn, 7, 5);
397 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
398 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
399 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
400 return MCDisassembler::Success;
403 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
404 uint64_t Address,
405 const void *Decoder) {
406 unsigned Rd = fieldFromInstruction(Insn, 7, 5);
407 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
408 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
409 Inst.addOperand(Inst.getOperand(0));
410 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
411 return MCDisassembler::Success;
414 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
415 ArrayRef<uint8_t> Bytes,
416 uint64_t Address,
417 raw_ostream &CS) const {
418 // TODO: This will need modification when supporting instruction set
419 // extensions with instructions > 32-bits (up to 176 bits wide).
420 uint32_t Insn;
421 DecodeStatus Result;
423 // It's a 32 bit instruction if bit 0 and 1 are 1.
424 if ((Bytes[0] & 0x3) == 0x3) {
425 if (Bytes.size() < 4) {
426 Size = 0;
427 return MCDisassembler::Fail;
429 Insn = support::endian::read32le(Bytes.data());
430 LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
431 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
432 Size = 4;
433 } else {
434 if (Bytes.size() < 2) {
435 Size = 0;
436 return MCDisassembler::Fail;
438 Insn = support::endian::read16le(Bytes.data());
440 if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
441 LLVM_DEBUG(
442 dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
443 // Calling the auto-generated decoder function.
444 Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
445 this, STI);
446 if (Result != MCDisassembler::Fail) {
447 Size = 2;
448 return Result;
452 if (STI.getFeatureBits()[RISCV::FeatureExtZbproposedc] &&
453 STI.getFeatureBits()[RISCV::FeatureStdExtC]) {
454 LLVM_DEBUG(
455 dbgs() << "Trying RVBC32 table (BitManip 16-bit Instruction):\n");
456 // Calling the auto-generated decoder function.
457 Result = decodeInstruction(DecoderTableRVBC16, MI, Insn, Address,
458 this, STI);
459 if (Result != MCDisassembler::Fail) {
460 Size = 2;
461 return Result;
465 LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
466 // Calling the auto-generated decoder function.
467 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
468 Size = 2;
471 return Result;