[x86] fix assert with horizontal math + broadcast of vector (PR43402)
[llvm-core.git] / lib / Target / RISCV / Disassembler / RISCVDisassembler.cpp
blob4b85955a97be79c1deb0ea0875b15e177c3c9f12
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/RISCVMCTargetDesc.h"
14 #include "TargetInfo/RISCVTargetInfo.h"
15 #include "Utils/RISCVBaseInfo.h"
16 #include "llvm/CodeGen/Register.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
19 #include "llvm/MC/MCFixedLenDisassembler.h"
20 #include "llvm/MC/MCInst.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 {
35 public:
36 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
37 : MCDisassembler(STI, Ctx) {}
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;
44 } // end anonymous namespace
46 static MCDisassembler *createRISCVDisassembler(const Target &T,
47 const MCSubtargetInfo &STI,
48 MCContext &Ctx) {
49 return new RISCVDisassembler(STI, Ctx);
52 extern "C" void LLVMInitializeRISCVDisassembler() {
53 // Register the disassembler for each target.
54 TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
55 createRISCVDisassembler);
56 TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
57 createRISCVDisassembler);
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
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];
80 if (RegNo > array_lengthof(GPRDecoderTable) || (IsRV32E && RegNo > 15))
81 return MCDisassembler::Fail;
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];
87 Inst.addOperand(MCOperand::createReg(Reg));
88 return MCDisassembler::Success;
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
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;
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));
113 return MCDisassembler::Success;
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;
122 Register Reg = FPR32DecoderTable[RegNo + 8];
123 Inst.addOperand(MCOperand::createReg(Reg));
124 return MCDisassembler::Success;
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
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;
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));
149 return MCDisassembler::Success;
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;
158 Register Reg = FPR64DecoderTable[RegNo + 8];
159 Inst.addOperand(MCOperand::createReg(Reg));
160 return MCDisassembler::Success;
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;
170 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
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;
180 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
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;
189 Register Reg = GPRDecoderTable[RegNo + 8];
190 Inst.addOperand(MCOperand::createReg(Reg));
191 return MCDisassembler::Success;
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);
206 if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
207 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
208 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
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));
218 return MCDisassembler::Success;
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);
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)));
237 return MCDisassembler::Success;
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);
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)));
258 return MCDisassembler::Success;
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);
268 Inst.addOperand(MCOperand::createImm(Imm));
269 return MCDisassembler::Success;
272 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm,
273 int64_t Address,
274 const void *Decoder) {
275 assert(isUInt<3>(Imm) && "Invalid immediate");
276 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
277 return MCDisassembler::Fail;
279 Inst.addOperand(MCOperand::createImm(Imm));
280 return MCDisassembler::Success;
283 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
284 uint64_t Address, const void *Decoder);
286 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
287 uint64_t Address, const void *Decoder);
289 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
290 uint64_t Address,
291 const void *Decoder);
293 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
294 uint64_t Address, const void *Decoder);
296 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
297 uint64_t Address,
298 const void *Decoder);
300 #include "RISCVGenDisassemblerTables.inc"
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");
309 return MCDisassembler::Success;
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");
321 return MCDisassembler::Success;
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");
334 return MCDisassembler::Success;
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);
343 return MCDisassembler::Success;
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);
354 return MCDisassembler::Success;
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;
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;
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;
382 Insn = support::endian::read16le(Bytes.data());
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;
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;
402 return Result;