Files

754 lines
24 KiB
C

/* Capstone Disassembly Engine, http://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2023 */
/* Automatically translated source file from LLVM. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Only small edits allowed. */
/* For multiple similar edits, please create a Patch for the translator. */
/* Capstone's C++ file translator: */
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
//===-- RISCVDisassembler.cpp - Disassembler for RISC-V -------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the RISCVDisassembler class.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <capstone/platform.h>
#include "../../MCInst.h"
#include "../../MathExtras.h"
#include "../../MCInstPrinter.h"
#include "../../MCDisassembler.h"
#include "../../MCFixedLenDisassembler.h"
#include "../../cs_priv.h"
#include "../../utils.h"
#include "RISCVDisassemblerExtension.h"
#include "RISCVBaseInfo.h"
#include "RISCVMapping.h"
#define GET_SUBTARGETINFO_ENUM
#include "RISCVGenSubtargetInfo.inc"
#define GET_REGINFO_ENUM
#include "RISCVGenRegisterInfo.inc"
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_DESC
#include "RISCVGenInstrInfo.inc"
#define CONCAT(a, b) CONCAT_(a, b)
#define CONCAT_(a, b) a##_##b
#define DEBUG_TYPE "riscv-disassembler"
DecodeStatus RISCV_getInstruction(MCInst *Instr, uint16_t *Size,
const uint8_t *Bytes, size_t BytesLen,
uint64_t Address, SStream *CStream);
void addSPOperands(MCInst *MI);
;
// end anonymous namespace
static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
bool IsRVE = RISCV_getFeatureBits(Inst->csh->mode, RISCV_FeatureRVE);
if (RegNo >= 32 || (IsRVE && RegNo >= 16))
return MCDisassembler_Fail;
MCRegister Reg = RISCV_X0 + RegNo;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
MCRegister Reg = RISCV_X0 + RegNo;
if (Reg != RISCV_X1 && Reg != RISCV_X5)
return MCDisassembler_Fail;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32)
return MCDisassembler_Fail;
MCRegister Reg = RISCV_F0_H + RegNo;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32)
return MCDisassembler_Fail;
MCRegister Reg = RISCV_F0_F + RegNo;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeFPR32CRegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 8) {
return MCDisassembler_Fail;
}
MCRegister Reg = RISCV_F8_F + RegNo;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32)
return MCDisassembler_Fail;
MCRegister Reg = RISCV_F0_D + RegNo;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeFPR64CRegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 8) {
return MCDisassembler_Fail;
}
MCRegister Reg = RISCV_F8_D + RegNo;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo == 0) {
return MCDisassembler_Fail;
}
return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
}
static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst *Inst, uint64_t RegNo,
uint32_t Address,
const void *Decoder)
{
if (RegNo == 2) {
return MCDisassembler_Fail;
}
return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
}
static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 8)
return MCDisassembler_Fail;
MCRegister Reg = RISCV_X8 + RegNo;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32 || RegNo & 1)
return MCDisassembler_Fail;
MCRegister Reg = RISCV_X0 + RegNo;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeSR07RegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 8)
return MCDisassembler_Fail;
MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV_X8) :
(RegNo - 2 + RISCV_X18);
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeVRRegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address, const void *Decoder)
{
if (RegNo >= 32)
return MCDisassembler_Fail;
MCRegister Reg = RISCV_V0 + RegNo;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeVRM2RegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32 || RegNo % 2)
return MCDisassembler_Fail;
MCRegister Reg = MCRegisterInfo_getMatchingSuperReg(
Inst->MRI, RISCV_V0 + RegNo, RISCV_sub_vrm1_0,
MCRegisterInfo_getRegClass(Inst->MRI, RISCV_VRM2RegClassID));
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeVRM4RegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32 || RegNo % 4)
return MCDisassembler_Fail;
MCRegister Reg = MCRegisterInfo_getMatchingSuperReg(
Inst->MRI, RISCV_V0 + RegNo, RISCV_sub_vrm1_0,
MCRegisterInfo_getRegClass(Inst->MRI, RISCV_VRM4RegClassID));
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus DecodeVRM8RegisterClass(MCInst *Inst, uint32_t RegNo,
uint64_t Address,
const void *Decoder)
{
if (RegNo >= 32 || RegNo % 8)
return MCDisassembler_Fail;
MCRegister Reg = MCRegisterInfo_getMatchingSuperReg(
Inst->MRI, RISCV_V0 + RegNo, RISCV_sub_vrm1_0,
MCRegisterInfo_getRegClass(Inst->MRI, RISCV_VRM8RegClassID));
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
static DecodeStatus decodeVMaskReg(MCInst *Inst, uint64_t RegNo,
uint64_t Address, const void *Decoder)
{
if (RegNo > 2) {
return MCDisassembler_Fail;
}
MCRegister Reg = (RegNo == 0) ? RISCV_V0 : RISCV_NoRegister;
MCOperand_CreateReg0(Inst, (Reg));
return MCDisassembler_Success;
}
#define DEFINE_decodeUImmOperand(N) \
static DecodeStatus CONCAT(decodeUImmOperand, \
N)(MCInst * Inst, uint32_t Imm, \
int64_t Address, const void *Decoder) \
{ \
CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
MCOperand_CreateImm0(Inst, (Imm)); \
return MCDisassembler_Success; \
}
DEFINE_decodeUImmOperand(6);
DEFINE_decodeUImmOperand(2);
DEFINE_decodeUImmOperand(8);
DEFINE_decodeUImmOperand(9);
DEFINE_decodeUImmOperand(7);
DEFINE_decodeUImmOperand(4);
DEFINE_decodeUImmOperand(20);
DEFINE_decodeUImmOperand(5);
DEFINE_decodeUImmOperand(11);
DEFINE_decodeUImmOperand(10);
DEFINE_decodeUImmOperand(12);
DEFINE_decodeUImmOperand(3);
DEFINE_decodeUImmOperand(1);
#define DEFINE_decodeUImmNonZeroOperand(N) \
static DecodeStatus CONCAT(decodeUImmNonZeroOperand, \
N)(MCInst * Inst, uint32_t Imm, \
int64_t Address, const void *Decoder) \
{ \
if (Imm == 0) \
return MCDisassembler_Fail; \
return CONCAT(decodeUImmOperand, N)(Inst, Imm, Address, \
Decoder); \
}
DEFINE_decodeUImmNonZeroOperand(10);
#define DEFINE_decodeSImmOperand(N) \
static DecodeStatus CONCAT(decodeSImmOperand, \
N)(MCInst * Inst, uint32_t Imm, \
int64_t Address, const void *Decoder) \
{ \
CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
\
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
return MCDisassembler_Success; \
}
DEFINE_decodeSImmOperand(6);
DEFINE_decodeSImmOperand(12);
DEFINE_decodeSImmOperand(5);
DEFINE_decodeSImmOperand(10);
#define DEFINE_decodeSImmNonZeroOperand(N) \
static DecodeStatus CONCAT(decodeSImmNonZeroOperand, \
N)(MCInst * Inst, uint32_t Imm, \
int64_t Address, const void *Decoder) \
{ \
if (Imm == 0) \
return MCDisassembler_Fail; \
return CONCAT(decodeSImmOperand, N)(Inst, Imm, Address, \
Decoder); \
}
DEFINE_decodeSImmNonZeroOperand(6);
DEFINE_decodeSImmNonZeroOperand(10);
#define DEFINE_decodeSImmOperandAndLsl1(N) \
static DecodeStatus CONCAT(decodeSImmOperandAndLsl1, \
N)(MCInst * Inst, uint32_t Imm, \
int64_t Address, const void *Decoder) \
{ \
CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
\
MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 1), N))); \
return MCDisassembler_Success; \
}
DEFINE_decodeSImmOperandAndLsl1(12);
DEFINE_decodeSImmOperandAndLsl1(9);
DEFINE_decodeSImmOperandAndLsl1(13);
DEFINE_decodeSImmOperandAndLsl1(21);
static DecodeStatus decodeCLUIImmOperand(MCInst *Inst, uint32_t Imm,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(6, Imm) && "Invalid immediate");
if (Imm > 31) {
Imm = (SignExtend64((Imm), 6) & 0xfffff);
}
MCOperand_CreateImm0(Inst, (Imm));
return MCDisassembler_Success;
}
static DecodeStatus decodeFRMArg(MCInst *Inst, uint32_t Imm, int64_t Address,
const void *Decoder)
{
CS_ASSERT(isUIntN(3, Imm) && "Invalid immediate");
if (!RISCVFPRndMode_isValidRoundingMode(Imm))
return MCDisassembler_Fail;
MCOperand_CreateImm0(Inst, (Imm));
return MCDisassembler_Success;
}
static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst *Inst, uint32_t Insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus decodeRVCInstrRdSImm(MCInst *Inst, uint32_t Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst *Inst, uint32_t Insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus decodeRVCInstrRdRs2(MCInst *Inst, uint32_t Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst *Inst, uint32_t Insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus decodeXTHeadMemPair(MCInst *Inst, uint32_t Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus decodeZcmpRlist(MCInst *Inst, unsigned Imm,
uint64_t Address, const void *Decoder);
static DecodeStatus decodeRegReg(MCInst *Inst, uint32_t Insn, uint64_t Address,
const void *Decoder);
static DecodeStatus decodeZcmpSpimm(MCInst *Inst, unsigned Imm,
uint64_t Address, const void *Decoder);
static DecodeStatus decodeCSSPushPopchk(MCInst *Inst, uint32_t Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus decodeUImmLog2XLenOperand(MCInst *Inst, uint32_t Imm,
int64_t Address,
const void *Decoder)
{
CS_ASSERT(isUIntN(6, Imm) && "Invalid immediate");
if (!RISCV_getFeatureBits(Inst->csh->mode, RISCV_Feature64Bit) &&
!isUIntN(5, Imm))
return MCDisassembler_Fail;
MCOperand_CreateImm0(Inst, (Imm));
return MCDisassembler_Success;
}
static DecodeStatus decodeUImmLog2XLenNonZeroOperand(MCInst *Inst, uint32_t Imm,
int64_t Address,
const void *Decoder)
{
if (Imm == 0)
return MCDisassembler_Fail;
return decodeUImmLog2XLenOperand(Inst, Imm, Address, Decoder);
}
#include "RISCVGenDisassemblerTables.inc"
static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst *Inst, uint32_t Insn,
uint64_t Address,
const void *Decoder)
{
uint32_t Rd = fieldFromInstruction_4(Insn, 7, 5);
DecodeStatus Result =
DecodeGPRNoX0RegisterClass(Inst, Rd, Address, Decoder);
(void)Result;
CS_ASSERT(Result == MCDisassembler_Success && "Invalid register");
MCInst_addOperand2(Inst, (MCInst_getOperand(Inst, (0))));
MCOperand_CreateImm0(Inst, (0));
return MCDisassembler_Success;
}
static DecodeStatus decodeCSSPushPopchk(MCInst *Inst, uint32_t Insn,
uint64_t Address, const void *Decoder)
{
uint32_t Rs1 = fieldFromInstruction_4(Insn, 7, 5);
DecodeStatus Result =
DecodeGPRX1X5RegisterClass(Inst, Rs1, Address, Decoder);
(void)Result;
CS_ASSERT(Result == MCDisassembler_Success && "Invalid register");
return MCDisassembler_Success;
}
static DecodeStatus decodeRVCInstrRdSImm(MCInst *Inst, uint32_t Insn,
uint64_t Address, const void *Decoder)
{
MCOperand_CreateReg0(Inst, (RISCV_X0));
uint32_t SImm6 = fieldFromInstruction_4(Insn, 12, 1) << 5 |
fieldFromInstruction_4(Insn, 2, 5);
DecodeStatus Result =
CONCAT(decodeSImmOperand, 6)(Inst, SImm6, Address, Decoder);
(void)Result;
CS_ASSERT(Result == MCDisassembler_Success && "Invalid immediate");
return MCDisassembler_Success;
}
static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst *Inst, uint32_t Insn,
uint64_t Address,
const void *Decoder)
{
MCOperand_CreateReg0(Inst, (RISCV_X0));
MCInst_addOperand2(Inst, (MCInst_getOperand(Inst, (0))));
uint32_t UImm6 = fieldFromInstruction_4(Insn, 12, 1) << 5 |
fieldFromInstruction_4(Insn, 2, 5);
DecodeStatus Result =
CONCAT(decodeUImmOperand, 6)(Inst, UImm6, Address, Decoder);
(void)Result;
CS_ASSERT(Result == MCDisassembler_Success && "Invalid immediate");
return MCDisassembler_Success;
}
static DecodeStatus decodeRVCInstrRdRs2(MCInst *Inst, uint32_t Insn,
uint64_t Address, const void *Decoder)
{
uint32_t Rd = fieldFromInstruction_4(Insn, 7, 5);
uint32_t Rs2 = fieldFromInstruction_4(Insn, 2, 5);
DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
return MCDisassembler_Success;
}
static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst *Inst, uint32_t Insn,
uint64_t Address,
const void *Decoder)
{
uint32_t Rd = fieldFromInstruction_4(Insn, 7, 5);
uint32_t Rs2 = fieldFromInstruction_4(Insn, 2, 5);
DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
MCInst_addOperand2(Inst, (MCInst_getOperand(Inst, (0))));
DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
return MCDisassembler_Success;
}
static DecodeStatus decodeXTHeadMemPair(MCInst *Inst, uint32_t Insn,
uint64_t Address, const void *Decoder)
{
uint32_t Rd1 = fieldFromInstruction_4(Insn, 7, 5);
uint32_t Rs1 = fieldFromInstruction_4(Insn, 15, 5);
uint32_t Rd2 = fieldFromInstruction_4(Insn, 20, 5);
uint32_t UImm2 = fieldFromInstruction_4(Insn, 25, 2);
DecodeGPRRegisterClass(Inst, Rd1, Address, Decoder);
DecodeGPRRegisterClass(Inst, Rd2, Address, Decoder);
DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
DecodeStatus Result =
CONCAT(decodeUImmOperand, 2)(Inst, UImm2, Address, Decoder);
(void)Result;
CS_ASSERT(Result == MCDisassembler_Success && "Invalid immediate");
// Disassemble the final operand which is implicit.
unsigned Opcode = MCInst_getOpcode(Inst);
bool IsWordOp = (Opcode == RISCV_TH_LWD || Opcode == RISCV_TH_LWUD ||
Opcode == RISCV_TH_SWD);
if (IsWordOp)
MCOperand_CreateImm0(Inst, (3));
else
MCOperand_CreateImm0(Inst, (4));
return MCDisassembler_Success;
}
static DecodeStatus decodeZcmpRlist(MCInst *Inst, unsigned Imm,
uint64_t Address, const void *Decoder)
{
if (Imm <= 3)
return MCDisassembler_Fail;
MCOperand_CreateImm0(Inst, (Imm));
return MCDisassembler_Success;
}
static DecodeStatus decodeRegReg(MCInst *Inst, uint32_t Insn, uint64_t Address,
const void *Decoder)
{
uint32_t Rs1 = fieldFromInstruction_4(Insn, 0, 5);
uint32_t Rs2 = fieldFromInstruction_4(Insn, 5, 5);
DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
return MCDisassembler_Success;
}
static DecodeStatus decodeZcmpSpimm(MCInst *Inst, unsigned Imm,
uint64_t Address, const void *Decoder)
{
MCOperand_CreateImm0(Inst, (Imm));
return MCDisassembler_Success;
}
// Add implied SP operand for C.*SP compressed instructions. The SP operand
// isn't explicitly encoded in the instruction.
void addSPOperands(MCInst *MI)
{
const MCInstrDesc *MCID = MCInstrDesc_get(MCInst_getOpcode(MI),
RISCVDescs.Insts,
ARR_SIZE(RISCVDescs.Insts));
MCOperand SPReg;
SPReg.MachineOperandType = kRegister;
SPReg.Kind = kRegister;
SPReg.RegVal = RISCV_X2;
for (unsigned i = 0; i < MCID->NumOperands; i++)
if (MCID->OpInfo[i].RegClass == RISCV_SPRegClassID)
MCInst_insert0(MI, i, &SPReg);
}
DecodeStatus RISCV_getInstruction(MCInst *MI, uint16_t *Size,
const uint8_t *Bytes, size_t BytesLen,
uint64_t Address, SStream *CS)
{
// TODO: This will need modification when supporting instruction set
// extensions with instructions > 32-bits (up to 176 bits wide).
uint32_t Insn;
DecodeStatus Result;
#define TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION( \
width, FEATURE_CHECKS, DECODER_TABLE, DESC, ADDITIONAL_OPERATION) \
do { \
if (FEATURE_CHECKS) { \
Result = decodeInstruction_##width( \
DECODER_TABLE, MI, Insn, Address, NULL); \
if (Result != MCDisassembler_Fail) { \
ADDITIONAL_OPERATION; \
return Result; \
} \
} \
} while (false)
#define TRY_TO_DECODE_AND_ADD_SP(width, FEATURE_CHECKS, DECODER_TABLE, DESC) \
TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION( \
width, FEATURE_CHECKS, DECODER_TABLE, DESC, addSPOperands(MI))
#define TRY_TO_DECODE(width, FEATURE_CHECKS, DECODER_TABLE, DESC) \
TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION( \
width, FEATURE_CHECKS, DECODER_TABLE, DESC, (void)NULL)
#define TRY_TO_DECODE_FEATURE(width, FEATURE, DECODER_TABLE, DESC) \
TRY_TO_DECODE(width, RISCV_getFeatureBits(MI->csh->mode, FEATURE), \
DECODER_TABLE, DESC)
// It's a 32 bit instruction if bit 0 and 1 are 1.
if ((Bytes[0] & 0x3) == 0x3) {
if (BytesLen < 4) {
*Size = 0;
return MCDisassembler_Fail;
}
*Size = 4;
Insn = readBytes32(MI, Bytes);
TRY_TO_DECODE(4,
RISCV_getFeatureBits(MI->csh->mode,
RISCV_FeatureStdExtZdinx) &&
!RISCV_getFeatureBits(MI->csh->mode,
RISCV_Feature64Bit),
DecoderTableRV32Zdinx32,
"RV32Zdinx table (Double in Integer and rv32)");
TRY_TO_DECODE(4,
RISCV_getFeatureBits(MI->csh->mode,
RISCV_FeatureStdExtZacas) &&
!RISCV_getFeatureBits(MI->csh->mode,
RISCV_Feature64Bit),
DecoderTableRV32Zacas32,
"RV32Zacas table (Compare-And-Swap and rv32)");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureStdExtZfinx,
DecoderTableRVZfinx32,
"RVZfinx table (Float in Integer)");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXVentanaCondOps,
DecoderTableXVentana32,
"Ventana custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadBa,
DecoderTableXTHeadBa32,
"XTHeadBa custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadBb,
DecoderTableXTHeadBb32,
"XTHeadBb custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadBs,
DecoderTableXTHeadBs32,
"XTHeadBs custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadCondMov,
DecoderTableXTHeadCondMov32,
"XTHeadCondMov custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadCmo,
DecoderTableXTHeadCmo32,
"XTHeadCmo custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadFMemIdx,
DecoderTableXTHeadFMemIdx32,
"XTHeadFMemIdx custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadMac,
DecoderTableXTHeadMac32,
"XTHeadMac custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadMemIdx,
DecoderTableXTHeadMemIdx32,
"XTHeadMemIdx custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadMemPair,
DecoderTableXTHeadMemPair32,
"XTHeadMemPair custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadSync,
DecoderTableXTHeadSync32,
"XTHeadSync custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadVdot,
DecoderTableXTHeadVdot32,
"XTHeadVdot custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXSfvcp,
DecoderTableXSfvcp32,
"SiFive VCIX custom opcode table");
TRY_TO_DECODE_FEATURE(
4, RISCV_FeatureVendorXSfvqmaccdod,
DecoderTableXSfvqmaccdod32,
"SiFive Matrix Multiplication (2x8 and 8x2) Instruction opcode table");
TRY_TO_DECODE_FEATURE(
4, RISCV_FeatureVendorXSfvqmaccqoq,
DecoderTableXSfvqmaccqoq32,
"SiFive Matrix Multiplication (4x8 and 8x4) Instruction opcode table");
TRY_TO_DECODE_FEATURE(
4, RISCV_FeatureVendorXSfvfwmaccqqq,
DecoderTableXSfvfwmaccqqq32,
"SiFive Matrix Multiplication Instruction opcode table");
TRY_TO_DECODE_FEATURE(
4, RISCV_FeatureVendorXSfvfnrclipxfqf,
DecoderTableXSfvfnrclipxfqf32,
"SiFive FP32-to-int8 Ranged Clip Instructions opcode table");
TRY_TO_DECODE_FEATURE(
4, RISCV_FeatureVendorXCVbitmanip,
DecoderTableXCVbitmanip32,
"CORE-V Bit Manipulation custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXCVelw,
DecoderTableXCVelw32,
"CORE-V Event load custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXCVmac,
DecoderTableXCVmac32,
"CORE-V MAC custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXCVmem,
DecoderTableXCVmem32,
"CORE-V MEM custom opcode table");
TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXCValu,
DecoderTableXCValu32,
"CORE-V ALU custom opcode table");
TRY_TO_DECODE_FEATURE(
4, RISCV_FeatureVendorXCVsimd, DecoderTableXCVsimd32,
"CORE-V SIMD extensions custom opcode table");
TRY_TO_DECODE_FEATURE(
4, RISCV_FeatureVendorXCVbi, DecoderTableXCVbi32,
"CORE-V Immediate Branching custom opcode table");
TRY_TO_DECODE(4, true, DecoderTable32, "RISCV32 table");
return MCDisassembler_Fail;
}
if (BytesLen < 2) {
*Size = 0;
return MCDisassembler_Fail;
}
*Size = 2;
Insn = readBytes16(MI, Bytes);
TRY_TO_DECODE_AND_ADD_SP(
2, !RISCV_getFeatureBits(MI->csh->mode, RISCV_Feature64Bit),
DecoderTableRISCV32Only_16,
"RISCV32Only_16 table (16-bit Instruction)");
TRY_TO_DECODE_FEATURE(2, RISCV_FeatureStdExtZicfiss,
DecoderTableZicfiss16,
"RVZicfiss table (Shadow Stack)");
TRY_TO_DECODE_FEATURE(2, RISCV_FeatureStdExtZcmt, DecoderTableRVZcmt16,
"Zcmt table (16-bit Table Jump Instructions)");
TRY_TO_DECODE_FEATURE(
2, RISCV_FeatureStdExtZcmp, DecoderTableRVZcmp16,
"Zcmp table (16-bit Push/Pop & Double Move Instructions)");
TRY_TO_DECODE_AND_ADD_SP(2, true, DecoderTable16,
"RISCV_C table (16-bit Instruction)");
return MCDisassembler_Fail;
}
bool RISCV_LLVM_getInstruction(csh handle, const uint8_t *Bytes, size_t ByteLen,
MCInst *MI, uint16_t *Size, uint64_t Address,
void *Info)
{
RISCV_init_cs_detail(MI);
MI->MRI = (MCRegisterInfo *)Info;
return RISCV_getInstruction(MI, Size, Bytes, ByteLen, Address, NULL) !=
MCDisassembler_Fail;
}