Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
35293 views
1
//===-- RISCVDisassembler.cpp - Disassembler for RISC-V -------------------===//
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
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/MCDecoderOps.h"
18
#include "llvm/MC/MCDisassembler/MCDisassembler.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/MC/TargetRegistry.h"
24
#include "llvm/Support/Endian.h"
25
26
using namespace llvm;
27
28
#define DEBUG_TYPE "riscv-disassembler"
29
30
typedef MCDisassembler::DecodeStatus DecodeStatus;
31
32
namespace {
33
class RISCVDisassembler : public MCDisassembler {
34
std::unique_ptr<MCInstrInfo const> const MCII;
35
36
public:
37
RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
38
MCInstrInfo const *MCII)
39
: MCDisassembler(STI, Ctx), MCII(MCII) {}
40
41
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
42
ArrayRef<uint8_t> Bytes, uint64_t Address,
43
raw_ostream &CStream) const override;
44
45
private:
46
void addSPOperands(MCInst &MI) const;
47
48
DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size,
49
ArrayRef<uint8_t> Bytes, uint64_t Address,
50
raw_ostream &CStream) const;
51
DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size,
52
ArrayRef<uint8_t> Bytes, uint64_t Address,
53
raw_ostream &CStream) const;
54
};
55
} // end anonymous namespace
56
57
static MCDisassembler *createRISCVDisassembler(const Target &T,
58
const MCSubtargetInfo &STI,
59
MCContext &Ctx) {
60
return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
61
}
62
63
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {
64
// Register the disassembler for each target.
65
TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
66
createRISCVDisassembler);
67
TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
68
createRISCVDisassembler);
69
}
70
71
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,
72
uint64_t Address,
73
const MCDisassembler *Decoder) {
74
bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);
75
76
if (RegNo >= 32 || (IsRVE && RegNo >= 16))
77
return MCDisassembler::Fail;
78
79
MCRegister Reg = RISCV::X0 + RegNo;
80
Inst.addOperand(MCOperand::createReg(Reg));
81
return MCDisassembler::Success;
82
}
83
84
static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo,
85
uint64_t Address,
86
const MCDisassembler *Decoder) {
87
MCRegister Reg = RISCV::X0 + RegNo;
88
if (Reg != RISCV::X1 && Reg != RISCV::X5)
89
return MCDisassembler::Fail;
90
91
Inst.addOperand(MCOperand::createReg(Reg));
92
return MCDisassembler::Success;
93
}
94
95
static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo,
96
uint64_t Address,
97
const MCDisassembler *Decoder) {
98
if (RegNo >= 32)
99
return MCDisassembler::Fail;
100
101
MCRegister Reg = RISCV::F0_H + RegNo;
102
Inst.addOperand(MCOperand::createReg(Reg));
103
return MCDisassembler::Success;
104
}
105
106
static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint32_t RegNo,
107
uint64_t Address,
108
const MCDisassembler *Decoder) {
109
if (RegNo >= 32)
110
return MCDisassembler::Fail;
111
112
MCRegister Reg = RISCV::F0_F + RegNo;
113
Inst.addOperand(MCOperand::createReg(Reg));
114
return MCDisassembler::Success;
115
}
116
117
static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint32_t RegNo,
118
uint64_t Address,
119
const MCDisassembler *Decoder) {
120
if (RegNo >= 8) {
121
return MCDisassembler::Fail;
122
}
123
MCRegister Reg = RISCV::F8_F + RegNo;
124
Inst.addOperand(MCOperand::createReg(Reg));
125
return MCDisassembler::Success;
126
}
127
128
static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint32_t RegNo,
129
uint64_t Address,
130
const MCDisassembler *Decoder) {
131
if (RegNo >= 32)
132
return MCDisassembler::Fail;
133
134
MCRegister Reg = RISCV::F0_D + RegNo;
135
Inst.addOperand(MCOperand::createReg(Reg));
136
return MCDisassembler::Success;
137
}
138
139
static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo,
140
uint64_t Address,
141
const MCDisassembler *Decoder) {
142
if (RegNo >= 8) {
143
return MCDisassembler::Fail;
144
}
145
MCRegister Reg = RISCV::F8_D + RegNo;
146
Inst.addOperand(MCOperand::createReg(Reg));
147
return MCDisassembler::Success;
148
}
149
150
static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo,
151
uint64_t Address,
152
const MCDisassembler *Decoder) {
153
if (RegNo == 0) {
154
return MCDisassembler::Fail;
155
}
156
157
return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
158
}
159
160
static DecodeStatus
161
DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint32_t Address,
162
const MCDisassembler *Decoder) {
163
if (RegNo == 2) {
164
return MCDisassembler::Fail;
165
}
166
167
return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
168
}
169
170
static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint32_t RegNo,
171
uint64_t Address,
172
const MCDisassembler *Decoder) {
173
if (RegNo >= 8)
174
return MCDisassembler::Fail;
175
176
MCRegister Reg = RISCV::X8 + RegNo;
177
Inst.addOperand(MCOperand::createReg(Reg));
178
return MCDisassembler::Success;
179
}
180
181
static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo,
182
uint64_t Address,
183
const MCDisassembler *Decoder) {
184
if (RegNo >= 32 || RegNo & 1)
185
return MCDisassembler::Fail;
186
187
MCRegister Reg = RISCV::X0 + RegNo;
188
Inst.addOperand(MCOperand::createReg(Reg));
189
return MCDisassembler::Success;
190
}
191
192
static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo,
193
uint64_t Address,
194
const void *Decoder) {
195
if (RegNo >= 8)
196
return MCDisassembler::Fail;
197
198
MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);
199
Inst.addOperand(MCOperand::createReg(Reg));
200
return MCDisassembler::Success;
201
}
202
203
static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo,
204
uint64_t Address,
205
const MCDisassembler *Decoder) {
206
if (RegNo >= 32)
207
return MCDisassembler::Fail;
208
209
MCRegister Reg = RISCV::V0 + RegNo;
210
Inst.addOperand(MCOperand::createReg(Reg));
211
return MCDisassembler::Success;
212
}
213
214
static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
215
uint64_t Address,
216
const MCDisassembler *Decoder) {
217
if (RegNo >= 32 || RegNo % 2)
218
return MCDisassembler::Fail;
219
220
const RISCVDisassembler *Dis =
221
static_cast<const RISCVDisassembler *>(Decoder);
222
const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
223
MCRegister Reg =
224
RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
225
&RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
226
227
Inst.addOperand(MCOperand::createReg(Reg));
228
return MCDisassembler::Success;
229
}
230
231
static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo,
232
uint64_t Address,
233
const MCDisassembler *Decoder) {
234
if (RegNo >= 32 || RegNo % 4)
235
return MCDisassembler::Fail;
236
237
const RISCVDisassembler *Dis =
238
static_cast<const RISCVDisassembler *>(Decoder);
239
const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
240
MCRegister Reg =
241
RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
242
&RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);
243
244
Inst.addOperand(MCOperand::createReg(Reg));
245
return MCDisassembler::Success;
246
}
247
248
static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo,
249
uint64_t Address,
250
const MCDisassembler *Decoder) {
251
if (RegNo >= 32 || RegNo % 8)
252
return MCDisassembler::Fail;
253
254
const RISCVDisassembler *Dis =
255
static_cast<const RISCVDisassembler *>(Decoder);
256
const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
257
MCRegister Reg =
258
RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
259
&RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
260
261
Inst.addOperand(MCOperand::createReg(Reg));
262
return MCDisassembler::Success;
263
}
264
265
static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo,
266
uint64_t Address,
267
const MCDisassembler *Decoder) {
268
if (RegNo >= 2)
269
return MCDisassembler::Fail;
270
271
MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister;
272
273
Inst.addOperand(MCOperand::createReg(Reg));
274
return MCDisassembler::Success;
275
}
276
277
template <unsigned N>
278
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,
279
int64_t Address,
280
const MCDisassembler *Decoder) {
281
assert(isUInt<N>(Imm) && "Invalid immediate");
282
Inst.addOperand(MCOperand::createImm(Imm));
283
return MCDisassembler::Success;
284
}
285
286
template <unsigned N>
287
static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
288
int64_t Address,
289
const MCDisassembler *Decoder) {
290
if (Imm == 0)
291
return MCDisassembler::Fail;
292
return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
293
}
294
295
template <unsigned N>
296
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,
297
int64_t Address,
298
const MCDisassembler *Decoder) {
299
assert(isUInt<N>(Imm) && "Invalid immediate");
300
// Sign-extend the number in the bottom N bits of Imm
301
Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
302
return MCDisassembler::Success;
303
}
304
305
template <unsigned N>
306
static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
307
int64_t Address,
308
const MCDisassembler *Decoder) {
309
if (Imm == 0)
310
return MCDisassembler::Fail;
311
return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
312
}
313
314
template <unsigned N>
315
static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint32_t Imm,
316
int64_t Address,
317
const MCDisassembler *Decoder) {
318
assert(isUInt<N>(Imm) && "Invalid immediate");
319
// Sign-extend the number in the bottom N bits of Imm after accounting for
320
// the fact that the N bit immediate is stored in N-1 bits (the LSB is
321
// always zero)
322
Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
323
return MCDisassembler::Success;
324
}
325
326
static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,
327
int64_t Address,
328
const MCDisassembler *Decoder) {
329
assert(isUInt<6>(Imm) && "Invalid immediate");
330
if (Imm > 31) {
331
Imm = (SignExtend64<6>(Imm) & 0xfffff);
332
}
333
Inst.addOperand(MCOperand::createImm(Imm));
334
return MCDisassembler::Success;
335
}
336
337
static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,
338
const MCDisassembler *Decoder) {
339
assert(isUInt<3>(Imm) && "Invalid immediate");
340
if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
341
return MCDisassembler::Fail;
342
343
Inst.addOperand(MCOperand::createImm(Imm));
344
return MCDisassembler::Success;
345
}
346
347
static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
348
uint64_t Address,
349
const MCDisassembler *Decoder);
350
351
static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
352
uint64_t Address,
353
const MCDisassembler *Decoder);
354
355
static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,
356
uint64_t Address,
357
const MCDisassembler *Decoder);
358
359
static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
360
uint64_t Address,
361
const MCDisassembler *Decoder);
362
363
static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
364
uint64_t Address,
365
const MCDisassembler *Decoder);
366
367
static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
368
uint64_t Address,
369
const MCDisassembler *Decoder);
370
371
static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
372
uint64_t Address, const void *Decoder);
373
374
static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
375
const MCDisassembler *Decoder);
376
377
static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,
378
uint64_t Address, const void *Decoder);
379
380
static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
381
uint64_t Address,
382
const MCDisassembler *Decoder);
383
384
#include "RISCVGenDisassemblerTables.inc"
385
386
static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
387
uint64_t Address,
388
const MCDisassembler *Decoder) {
389
uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
390
[[maybe_unused]] DecodeStatus Result =
391
DecodeGPRNoX0RegisterClass(Inst, Rd, Address, Decoder);
392
assert(Result == MCDisassembler::Success && "Invalid register");
393
Inst.addOperand(Inst.getOperand(0));
394
Inst.addOperand(MCOperand::createImm(0));
395
return MCDisassembler::Success;
396
}
397
398
static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
399
uint64_t Address,
400
const MCDisassembler *Decoder) {
401
uint32_t Rs1 = fieldFromInstruction(Insn, 7, 5);
402
[[maybe_unused]] DecodeStatus Result =
403
DecodeGPRX1X5RegisterClass(Inst, Rs1, Address, Decoder);
404
assert(Result == MCDisassembler::Success && "Invalid register");
405
return MCDisassembler::Success;
406
}
407
408
static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
409
uint64_t Address,
410
const MCDisassembler *Decoder) {
411
Inst.addOperand(MCOperand::createReg(RISCV::X0));
412
uint32_t SImm6 =
413
fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
414
[[maybe_unused]] DecodeStatus Result =
415
decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
416
assert(Result == MCDisassembler::Success && "Invalid immediate");
417
return MCDisassembler::Success;
418
}
419
420
static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,
421
uint64_t Address,
422
const MCDisassembler *Decoder) {
423
Inst.addOperand(MCOperand::createReg(RISCV::X0));
424
Inst.addOperand(Inst.getOperand(0));
425
uint32_t UImm6 =
426
fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
427
[[maybe_unused]] DecodeStatus Result =
428
decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
429
assert(Result == MCDisassembler::Success && "Invalid immediate");
430
return MCDisassembler::Success;
431
}
432
433
static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
434
uint64_t Address,
435
const MCDisassembler *Decoder) {
436
uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
437
uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5);
438
DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
439
DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
440
return MCDisassembler::Success;
441
}
442
443
static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
444
uint64_t Address,
445
const MCDisassembler *Decoder) {
446
uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
447
uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5);
448
DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
449
Inst.addOperand(Inst.getOperand(0));
450
DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
451
return MCDisassembler::Success;
452
}
453
454
static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
455
uint64_t Address,
456
const MCDisassembler *Decoder) {
457
uint32_t Rd1 = fieldFromInstruction(Insn, 7, 5);
458
uint32_t Rs1 = fieldFromInstruction(Insn, 15, 5);
459
uint32_t Rd2 = fieldFromInstruction(Insn, 20, 5);
460
uint32_t UImm2 = fieldFromInstruction(Insn, 25, 2);
461
DecodeGPRRegisterClass(Inst, Rd1, Address, Decoder);
462
DecodeGPRRegisterClass(Inst, Rd2, Address, Decoder);
463
DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
464
[[maybe_unused]] DecodeStatus Result =
465
decodeUImmOperand<2>(Inst, UImm2, Address, Decoder);
466
assert(Result == MCDisassembler::Success && "Invalid immediate");
467
468
// Disassemble the final operand which is implicit.
469
unsigned Opcode = Inst.getOpcode();
470
bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD ||
471
Opcode == RISCV::TH_SWD);
472
if (IsWordOp)
473
Inst.addOperand(MCOperand::createImm(3));
474
else
475
Inst.addOperand(MCOperand::createImm(4));
476
477
return MCDisassembler::Success;
478
}
479
480
static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
481
uint64_t Address, const void *Decoder) {
482
if (Imm <= 3)
483
return MCDisassembler::Fail;
484
Inst.addOperand(MCOperand::createImm(Imm));
485
return MCDisassembler::Success;
486
}
487
488
static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
489
const MCDisassembler *Decoder) {
490
uint32_t Rs1 = fieldFromInstruction(Insn, 0, 5);
491
uint32_t Rs2 = fieldFromInstruction(Insn, 5, 5);
492
DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
493
DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
494
return MCDisassembler::Success;
495
}
496
497
static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,
498
uint64_t Address, const void *Decoder) {
499
Inst.addOperand(MCOperand::createImm(Imm));
500
return MCDisassembler::Success;
501
}
502
503
// Add implied SP operand for C.*SP compressed instructions. The SP operand
504
// isn't explicitly encoded in the instruction.
505
void RISCVDisassembler::addSPOperands(MCInst &MI) const {
506
const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
507
for (unsigned i = 0; i < MCID.getNumOperands(); i++)
508
if (MCID.operands()[i].RegClass == RISCV::SPRegClassID)
509
MI.insert(MI.begin() + i, MCOperand::createReg(RISCV::X2));
510
}
511
512
#define TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, \
513
DESC, ADDITIONAL_OPERATION) \
514
do { \
515
if (FEATURE_CHECKS) { \
516
LLVM_DEBUG(dbgs() << "Trying " DESC ":\n"); \
517
DecodeStatus Result = \
518
decodeInstruction(DECODER_TABLE, MI, Insn, Address, this, STI); \
519
if (Result != MCDisassembler::Fail) { \
520
ADDITIONAL_OPERATION; \
521
return Result; \
522
} \
523
} \
524
} while (false)
525
#define TRY_TO_DECODE_AND_ADD_SP(FEATURE_CHECKS, DECODER_TABLE, DESC) \
526
TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \
527
addSPOperands(MI))
528
#define TRY_TO_DECODE(FEATURE_CHECKS, DECODER_TABLE, DESC) \
529
TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \
530
(void)nullptr)
531
#define TRY_TO_DECODE_FEATURE(FEATURE, DECODER_TABLE, DESC) \
532
TRY_TO_DECODE(STI.hasFeature(FEATURE), DECODER_TABLE, DESC)
533
534
DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
535
ArrayRef<uint8_t> Bytes,
536
uint64_t Address,
537
raw_ostream &CS) const {
538
if (Bytes.size() < 4) {
539
Size = 0;
540
return MCDisassembler::Fail;
541
}
542
Size = 4;
543
544
uint32_t Insn = support::endian::read32le(Bytes.data());
545
546
TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZdinx) &&
547
!STI.hasFeature(RISCV::Feature64Bit),
548
DecoderTableRV32Zdinx32,
549
"RV32Zdinx table (Double in Integer and rv32)");
550
TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZacas) &&
551
!STI.hasFeature(RISCV::Feature64Bit),
552
DecoderTableRV32Zacas32,
553
"RV32Zacas table (Compare-And-Swap and rv32)");
554
TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZfinx, DecoderTableRVZfinx32,
555
"RVZfinx table (Float in Integer)");
556
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXVentanaCondOps,
557
DecoderTableXVentana32, "Ventana custom opcode table");
558
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBa, DecoderTableXTHeadBa32,
559
"XTHeadBa custom opcode table");
560
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBb, DecoderTableXTHeadBb32,
561
"XTHeadBb custom opcode table");
562
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBs, DecoderTableXTHeadBs32,
563
"XTHeadBs custom opcode table");
564
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCondMov,
565
DecoderTableXTHeadCondMov32,
566
"XTHeadCondMov custom opcode table");
567
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCmo, DecoderTableXTHeadCmo32,
568
"XTHeadCmo custom opcode table");
569
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadFMemIdx,
570
DecoderTableXTHeadFMemIdx32,
571
"XTHeadFMemIdx custom opcode table");
572
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMac, DecoderTableXTHeadMac32,
573
"XTHeadMac custom opcode table");
574
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemIdx,
575
DecoderTableXTHeadMemIdx32,
576
"XTHeadMemIdx custom opcode table");
577
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemPair,
578
DecoderTableXTHeadMemPair32,
579
"XTHeadMemPair custom opcode table");
580
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadSync,
581
DecoderTableXTHeadSync32,
582
"XTHeadSync custom opcode table");
583
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadVdot,
584
DecoderTableXTHeadVdot32,
585
"XTHeadVdot custom opcode table");
586
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfvcp, DecoderTableXSfvcp32,
587
"SiFive VCIX custom opcode table");
588
TRY_TO_DECODE_FEATURE(
589
RISCV::FeatureVendorXSfvqmaccdod, DecoderTableXSfvqmaccdod32,
590
"SiFive Matrix Multiplication (2x8 and 8x2) Instruction opcode table");
591
TRY_TO_DECODE_FEATURE(
592
RISCV::FeatureVendorXSfvqmaccqoq, DecoderTableXSfvqmaccqoq32,
593
"SiFive Matrix Multiplication (4x8 and 8x4) Instruction opcode table");
594
TRY_TO_DECODE_FEATURE(
595
RISCV::FeatureVendorXSfvfwmaccqqq, DecoderTableXSfvfwmaccqqq32,
596
"SiFive Matrix Multiplication Instruction opcode table");
597
TRY_TO_DECODE_FEATURE(
598
RISCV::FeatureVendorXSfvfnrclipxfqf, DecoderTableXSfvfnrclipxfqf32,
599
"SiFive FP32-to-int8 Ranged Clip Instructions opcode table");
600
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecdiscarddlone,
601
DecoderTableXSiFivecdiscarddlone32,
602
"SiFive sf.cdiscard.d.l1 custom opcode table");
603
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecflushdlone,
604
DecoderTableXSiFivecflushdlone32,
605
"SiFive sf.cflush.d.l1 custom opcode table");
606
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfcease, DecoderTableXSfcease32,
607
"SiFive sf.cease custom opcode table");
608
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip,
609
DecoderTableXCVbitmanip32,
610
"CORE-V Bit Manipulation custom opcode table");
611
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVelw, DecoderTableXCVelw32,
612
"CORE-V Event load custom opcode table");
613
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32,
614
"CORE-V MAC custom opcode table");
615
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmem, DecoderTableXCVmem32,
616
"CORE-V MEM custom opcode table");
617
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCValu, DecoderTableXCValu32,
618
"CORE-V ALU custom opcode table");
619
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVsimd, DecoderTableXCVsimd32,
620
"CORE-V SIMD extensions custom opcode table");
621
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32,
622
"CORE-V Immediate Branching custom opcode table");
623
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
624
625
return MCDisassembler::Fail;
626
}
627
628
DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
629
ArrayRef<uint8_t> Bytes,
630
uint64_t Address,
631
raw_ostream &CS) const {
632
if (Bytes.size() < 2) {
633
Size = 0;
634
return MCDisassembler::Fail;
635
}
636
Size = 2;
637
638
uint32_t Insn = support::endian::read16le(Bytes.data());
639
TRY_TO_DECODE_AND_ADD_SP(!STI.hasFeature(RISCV::Feature64Bit),
640
DecoderTableRISCV32Only_16,
641
"RISCV32Only_16 table (16-bit Instruction)");
642
TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZicfiss, DecoderTableZicfiss16,
643
"RVZicfiss table (Shadow Stack)");
644
TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZcmt, DecoderTableRVZcmt16,
645
"Zcmt table (16-bit Table Jump Instructions)");
646
TRY_TO_DECODE_FEATURE(
647
RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16,
648
"Zcmp table (16-bit Push/Pop & Double Move Instructions)");
649
TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
650
DecoderTableXwchc16,
651
"WCH QingKe XW custom opcode table");
652
TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16,
653
"RISCV_C table (16-bit Instruction)");
654
655
return MCDisassembler::Fail;
656
}
657
658
DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
659
ArrayRef<uint8_t> Bytes,
660
uint64_t Address,
661
raw_ostream &CS) const {
662
// It's a 16 bit instruction if bit 0 and 1 are not 0b11.
663
if ((Bytes[0] & 0b11) != 0b11)
664
return getInstruction16(MI, Size, Bytes, Address, CS);
665
666
// It's a 32 bit instruction if bit 1:0 are 0b11(checked above) and bits 4:2
667
// are not 0b111.
668
if ((Bytes[0] & 0b1'1100) != 0b1'1100)
669
return getInstruction32(MI, Size, Bytes, Address, CS);
670
671
// 48-bit instructions are encoded as 0bxx011111.
672
if ((Bytes[0] & 0b11'1111) == 0b01'1111) {
673
Size = Bytes.size() >= 6 ? 6 : 0;
674
return MCDisassembler::Fail;
675
}
676
677
// 64-bit instructions are encoded as 0x0111111.
678
if ((Bytes[0] & 0b111'1111) == 0b011'1111) {
679
Size = Bytes.size() >= 8 ? 8 : 0;
680
return MCDisassembler::Fail;
681
}
682
683
// Remaining cases need to check a second byte.
684
if (Bytes.size() < 2) {
685
Size = 0;
686
return MCDisassembler::Fail;
687
}
688
689
// 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111.
690
// Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111.
691
unsigned nnn = (Bytes[1] >> 4) & 0b111;
692
if (nnn != 0b111) {
693
Size = 10 + (nnn * 2);
694
if (Bytes.size() < Size)
695
Size = 0;
696
return MCDisassembler::Fail;
697
}
698
699
// Remaining encodings are reserved for > 176-bit instructions.
700
Size = 0;
701
return MCDisassembler::Fail;
702
}
703
704