Add access support for RISC-V (#2393)

* resolve conflict for loongarch and RISCV in Mapping.c and Mapping.h

* Use RISCV_get_detail for simplicity

Co-authored-by: Rot127 <45763064+Rot127@users.noreply.github.com>

* Use detail_is_set for simplicity

Co-authored-by: Rot127 <45763064+Rot127@users.noreply.github.com>

* Change comment style

Co-authored-by: Rot127 <45763064+Rot127@users.noreply.github.com>

* remove redundant add_str

* fix bug for RISCV_add_detail

* fix operands for csr instructions

* add python binding and tester for RISC-V

* add more test cases for RISC-V (M,A,F,D,C instructions)

* fix incorrect operand and access for sc.w and sc.d

* fix incorrect operand for fence and sfence.vma

* assert -> CS_ASSERT

* some instructions in test_riscv.c should be RISCV64

* add cs details test

* update python testers

---------

Co-authored-by: Rot127 <45763064+Rot127@users.noreply.github.com>
This commit is contained in:
wxrdnx 2024-07-09 22:36:39 -05:00 committed by GitHub
parent 9c5b48b57f
commit 404912f068
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 3157 additions and 34 deletions

View File

@ -572,6 +572,7 @@ if(CAPSTONE_RISCV_SUPPORT)
arch/RISCV/RISCVGenRegisterInfo.inc
arch/RISCV/RISCVGenSubtargetInfo.inc
arch/RISCV/RISCVMappingInsn.inc
arch/RISCV/RISCVMappingInsnOp.inc
)
set(TEST_SOURCES ${TEST_SOURCES} test_riscv.c)
endif()

View File

@ -338,6 +338,7 @@ DEFINE_get_detail_op(aarch64, AArch64);
DEFINE_get_detail_op(alpha, Alpha);
DEFINE_get_detail_op(hppa, HPPA);
DEFINE_get_detail_op(loongarch, LoongArch);
DEFINE_get_detail_op(riscv, RISCV);
/// Returns true if for this architecture the
/// alias operands should be filled.

View File

@ -138,6 +138,7 @@ DECL_get_detail_op(aarch64, AArch64);
DECL_get_detail_op(alpha, Alpha);
DECL_get_detail_op(hppa, HPPA);
DECL_get_detail_op(loongarch, LoongArch);
DECL_get_detail_op(riscv, RISCV);
/// Increments the detail->arch.op_count by one.
#define DEFINE_inc_detail_op_count(arch, ARCH) \
@ -167,6 +168,8 @@ DEFINE_inc_detail_op_count(hppa, HPPA);
DEFINE_dec_detail_op_count(hppa, HPPA);
DEFINE_inc_detail_op_count(loongarch, LoongArch);
DEFINE_dec_detail_op_count(loongarch, LoongArch);
DEFINE_inc_detail_op_count(riscv, RISCV);
DEFINE_dec_detail_op_count(riscv, RISCV);
/// Returns true if a memory operand is currently edited.
static inline bool doing_mem(const MCInst *MI)
@ -195,6 +198,7 @@ DEFINE_get_arch_detail(aarch64, AArch64);
DEFINE_get_arch_detail(alpha, Alpha);
DEFINE_get_arch_detail(hppa, HPPA);
DEFINE_get_arch_detail(loongarch, LoongArch);
DEFINE_get_arch_detail(riscv, RISCV);
static inline bool detail_is_set(const MCInst *MI)
{

View File

@ -23,7 +23,7 @@ static const insn_map insns[] = {
#include "AlphaGenCSMappingInsn.inc"
};
const map_insn_ops insn_operands[] = {
static const map_insn_ops insn_operands[] = {
#include "AlphaGenCSMappingInsnOp.inc"
};

View File

@ -26,6 +26,7 @@
#include "../../MCRegisterInfo.h"
#include "../../MCDisassembler.h"
#include "../../MathExtras.h"
#include "../../Mapping.h"
#include "RISCVBaseInfo.h"
#include "RISCVDisassembler.h"
@ -322,16 +323,36 @@ static void markLSInsn(MCInst *MI, uint32_t in)
st 0100011 = 0x23
F/D ld 0000111 = 0x07
st 0100111 = 0x27
st 0101111 = 0x2f
*/
#define MASK_LS_INSN 0x0000007f
uint32_t opcode = in & MASK_LS_INSN;
if (0 == (opcode ^ 0x03) || 0 == (opcode ^ 0x07) ||
0 == (opcode ^ 0x23) || 0 == (opcode ^ 0x27))
0 == (opcode ^ 0x23) || 0 == (opcode ^ 0x27) ||
0 == (opcode ^ 0x2f))
MI->flat_insn->detail->riscv.need_effective_addr = true;
#undef MASK_LS_INSN
return;
}
static void markCLSInsn(MCInst *MI, uint32_t in)
{
// Unfortunately there is no obvious pattern in terms of RISC-V C instructions
// Thus, we compare the instruction IDs to see if it is a load/store instruction
unsigned id = MCInst_getOpcode(MI);
if (id == RISCV_C_FLD || id == RISCV_C_LW ||
id == RISCV_C_FLW || id == RISCV_C_LD ||
id == RISCV_C_FSD || id == RISCV_C_SW ||
id == RISCV_C_FSW || id == RISCV_C_SD ||
id == RISCV_C_FLDSP || id == RISCV_C_LWSP ||
id == RISCV_C_FLWSP || id == RISCV_C_LDSP ||
id == RISCV_C_FSDSP || id == RISCV_C_SWSP ||
id == RISCV_C_FSWSP || id == RISCV_C_SDSP) {
RISCV_get_detail(MI)->need_effective_addr = true;
}
return;
}
static DecodeStatus RISCVDisassembler_getInstruction(int mode, MCInst *MI,
const uint8_t *code, size_t code_len,
uint16_t *Size, uint64_t Address,
@ -382,6 +403,12 @@ static DecodeStatus RISCVDisassembler_getInstruction(int mode, MCInst *MI,
init_MI_insn_detail(MI);
// Calling the auto-generated decoder function.
Result = decodeInstruction(DecoderTable16, MI, Inst, Address, MRI, mode);
// Now we need mark what instruction need fix effective address output.
// Note that we mark it AFTER the instruction is decoded
// This is because there is no obvious pattern in terms of RISC-V C instructions
// So we compare the instruction IDs one by one
if (detail_is_set(MI))
markCLSInsn(MI, Inst);
*Size = 2;
}

View File

@ -24,6 +24,7 @@
#include "../../SStream.h"
#include "../../MCRegisterInfo.h"
#include "../../utils.h"
#include "../../Mapping.h"
#include "RISCVMapping.h"
//#include "RISCVDisassembler.h"
@ -54,28 +55,180 @@ static const char *getRegisterName(unsigned RegNo, unsigned AltIdx);
static void fixDetailOfEffectiveAddr(MCInst *MI)
{
// Operands for load and store instructions in RISCV vary widely
unsigned id = MI->flat_insn->id;
unsigned reg = 0;
int64_t imm = 0;
uint8_t access = 0;
switch (id) {
case RISCV_INS_C_FLD:
case RISCV_INS_C_LW:
case RISCV_INS_C_FLW:
case RISCV_INS_C_LD:
case RISCV_INS_C_FSD:
case RISCV_INS_C_SW:
case RISCV_INS_C_FSW:
case RISCV_INS_C_SD:
case RISCV_INS_C_FLDSP:
case RISCV_INS_C_LWSP:
case RISCV_INS_C_FLWSP:
case RISCV_INS_C_LDSP:
case RISCV_INS_C_FSDSP:
case RISCV_INS_C_SWSP:
case RISCV_INS_C_FSWSP:
case RISCV_INS_C_SDSP:
case RISCV_INS_FLW:
case RISCV_INS_FSW:
case RISCV_INS_FLD:
case RISCV_INS_FSD:
case RISCV_INS_LB:
case RISCV_INS_LBU:
case RISCV_INS_LD:
case RISCV_INS_LH:
case RISCV_INS_LHU:
case RISCV_INS_LW:
case RISCV_INS_LWU:
case RISCV_INS_SB:
case RISCV_INS_SD:
case RISCV_INS_SH:
case RISCV_INS_SW: {
CS_ASSERT(3 == MI->flat_insn->detail->riscv.op_count);
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -3)->type);
CS_ASSERT(RISCV_OP_IMM == RISCV_get_detail_op(MI, -2)->type);
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -1)->type);
CS_ASSERT(3 == MI->flat_insn->detail->riscv.op_count);
CS_ASSERT(RISCV_OP_REG == MI->flat_insn->detail->riscv.operands[0].type);
imm = RISCV_get_detail_op(MI, -2)->imm;
reg = RISCV_get_detail_op(MI, -1)->reg;
access = RISCV_get_detail_op(MI, -1)->access;
if (RISCV_OP_IMM == MI->flat_insn->detail->riscv.operands[1].type) {
CS_ASSERT(RISCV_OP_REG == MI->flat_insn->detail->riscv.operands[2].type);
imm = MI->flat_insn->detail->riscv.operands[1].imm;
reg = MI->flat_insn->detail->riscv.operands[2].reg;
} else if (RISCV_OP_REG == MI->flat_insn->detail->riscv.operands[1].type) {
CS_ASSERT(RISCV_OP_IMM == MI->flat_insn->detail->riscv.operands[2].type);
reg = MI->flat_insn->detail->riscv.operands[1].reg;
imm = MI->flat_insn->detail->riscv.operands[2].imm;
RISCV_get_detail_op(MI, -2)->type = RISCV_OP_MEM;
RISCV_get_detail_op(MI, -2)->mem.base = reg;
RISCV_get_detail_op(MI, -2)->mem.disp = imm;
RISCV_get_detail_op(MI, -2)->access = access;
RISCV_dec_op_count(MI);
break;
}
case RISCV_INS_LR_W:
case RISCV_INS_LR_W_AQ:
case RISCV_INS_LR_W_AQ_RL:
case RISCV_INS_LR_W_RL:
case RISCV_INS_LR_D:
case RISCV_INS_LR_D_AQ:
case RISCV_INS_LR_D_AQ_RL:
case RISCV_INS_LR_D_RL: {
CS_ASSERT(2 == MI->flat_insn->detail->riscv.op_count);
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -1)->type);
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -2)->type);
reg = RISCV_get_detail_op(MI, -1)->reg;
RISCV_get_detail_op(MI, -1)->type = RISCV_OP_MEM;
RISCV_get_detail_op(MI, -1)->mem.base = reg;
RISCV_get_detail_op(MI, -1)->mem.disp = 0;
break;
}
case RISCV_INS_SC_W:
case RISCV_INS_SC_W_AQ:
case RISCV_INS_SC_W_AQ_RL:
case RISCV_INS_SC_W_RL:
case RISCV_INS_SC_D:
case RISCV_INS_SC_D_AQ:
case RISCV_INS_SC_D_AQ_RL:
case RISCV_INS_SC_D_RL:
case RISCV_INS_AMOADD_D:
case RISCV_INS_AMOADD_D_AQ:
case RISCV_INS_AMOADD_D_AQ_RL:
case RISCV_INS_AMOADD_D_RL:
case RISCV_INS_AMOADD_W:
case RISCV_INS_AMOADD_W_AQ:
case RISCV_INS_AMOADD_W_AQ_RL:
case RISCV_INS_AMOADD_W_RL:
case RISCV_INS_AMOAND_D:
case RISCV_INS_AMOAND_D_AQ:
case RISCV_INS_AMOAND_D_AQ_RL:
case RISCV_INS_AMOAND_D_RL:
case RISCV_INS_AMOAND_W:
case RISCV_INS_AMOAND_W_AQ:
case RISCV_INS_AMOAND_W_AQ_RL:
case RISCV_INS_AMOAND_W_RL:
case RISCV_INS_AMOMAXU_D:
case RISCV_INS_AMOMAXU_D_AQ:
case RISCV_INS_AMOMAXU_D_AQ_RL:
case RISCV_INS_AMOMAXU_D_RL:
case RISCV_INS_AMOMAXU_W:
case RISCV_INS_AMOMAXU_W_AQ:
case RISCV_INS_AMOMAXU_W_AQ_RL:
case RISCV_INS_AMOMAXU_W_RL:
case RISCV_INS_AMOMAX_D:
case RISCV_INS_AMOMAX_D_AQ:
case RISCV_INS_AMOMAX_D_AQ_RL:
case RISCV_INS_AMOMAX_D_RL:
case RISCV_INS_AMOMAX_W:
case RISCV_INS_AMOMAX_W_AQ:
case RISCV_INS_AMOMAX_W_AQ_RL:
case RISCV_INS_AMOMAX_W_RL:
case RISCV_INS_AMOMINU_D:
case RISCV_INS_AMOMINU_D_AQ:
case RISCV_INS_AMOMINU_D_AQ_RL:
case RISCV_INS_AMOMINU_D_RL:
case RISCV_INS_AMOMINU_W:
case RISCV_INS_AMOMINU_W_AQ:
case RISCV_INS_AMOMINU_W_AQ_RL:
case RISCV_INS_AMOMINU_W_RL:
case RISCV_INS_AMOMIN_D:
case RISCV_INS_AMOMIN_D_AQ:
case RISCV_INS_AMOMIN_D_AQ_RL:
case RISCV_INS_AMOMIN_D_RL:
case RISCV_INS_AMOMIN_W:
case RISCV_INS_AMOMIN_W_AQ:
case RISCV_INS_AMOMIN_W_AQ_RL:
case RISCV_INS_AMOMIN_W_RL:
case RISCV_INS_AMOOR_D:
case RISCV_INS_AMOOR_D_AQ:
case RISCV_INS_AMOOR_D_AQ_RL:
case RISCV_INS_AMOOR_D_RL:
case RISCV_INS_AMOOR_W:
case RISCV_INS_AMOOR_W_AQ:
case RISCV_INS_AMOOR_W_AQ_RL:
case RISCV_INS_AMOOR_W_RL:
case RISCV_INS_AMOSWAP_D:
case RISCV_INS_AMOSWAP_D_AQ:
case RISCV_INS_AMOSWAP_D_AQ_RL:
case RISCV_INS_AMOSWAP_D_RL:
case RISCV_INS_AMOSWAP_W:
case RISCV_INS_AMOSWAP_W_AQ:
case RISCV_INS_AMOSWAP_W_AQ_RL:
case RISCV_INS_AMOSWAP_W_RL:
case RISCV_INS_AMOXOR_D:
case RISCV_INS_AMOXOR_D_AQ:
case RISCV_INS_AMOXOR_D_AQ_RL:
case RISCV_INS_AMOXOR_D_RL:
case RISCV_INS_AMOXOR_W:
case RISCV_INS_AMOXOR_W_AQ:
case RISCV_INS_AMOXOR_W_AQ_RL:
case RISCV_INS_AMOXOR_W_RL: {
CS_ASSERT(3 == MI->flat_insn->detail->riscv.op_count);
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -3)->type);
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -2)->type);
CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -1)->type);
reg = RISCV_get_detail_op(MI, -1)->reg;
RISCV_get_detail_op(MI, -1)->type = RISCV_OP_MEM;
RISCV_get_detail_op(MI, -1)->mem.base = reg;
RISCV_get_detail_op(MI, -1)->mem.disp = 0;
break;
}
default: {
CS_ASSERT(0 && "id is not a RISC-V memory instruction");
break;
}
}
// set up effective address.
MI->flat_insn->detail->riscv.operands[1].type = RISCV_OP_MEM;
MI->flat_insn->detail->riscv.op_count--;
MI->flat_insn->detail->riscv.operands[1].mem.base = reg;
MI->flat_insn->detail->riscv.operands[1].mem.disp = imm;
return;
}
@ -118,16 +271,13 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
unsigned reg;
int64_t Imm = 0;
RISCV_add_cs_detail(MI, OpNo);
MCOperand *MO = MCInst_getOperand(MI, OpNo);
if (MCOperand_isReg(MO)) {
reg = MCOperand_getReg(MO);
printRegName(O, reg);
if (MI->csh->detail_opt) {
MI->flat_insn->detail->riscv.operands[MI->flat_insn->detail->riscv.op_count].type = RISCV_OP_REG;
MI->flat_insn->detail->riscv.operands[MI->flat_insn->detail->riscv.op_count].reg = reg;
MI->flat_insn->detail->riscv.op_count++;
}
} else {
CS_ASSERT(MCOperand_isImm(MO) && "Unknown operand kind in printOperand");
Imm = MCOperand_getImm(MO);
@ -142,12 +292,6 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
else
SStream_concat(O, "-%" PRIu64, -Imm);
}
if (MI->csh->detail_opt) {
MI->flat_insn->detail->riscv.operands[MI->flat_insn->detail->riscv.op_count].type = RISCV_OP_IMM;
MI->flat_insn->detail->riscv.operands[MI->flat_insn->detail->riscv.op_count].imm = Imm;
MI->flat_insn->detail->riscv.op_count++;
}
}
//CS_ASSERT(MO.isExpr() && "Unknown operand kind in printOperand");

View File

@ -6,6 +6,7 @@
#include "../../Mapping.h"
#include "../../utils.h"
#include "../../cs_simple_types.h"
#include "RISCVMapping.h"
#include "RISCVInstPrinter.h"
@ -140,6 +141,37 @@ static const insn_map insns[] = {
#include "RISCVMappingInsn.inc"
};
#ifndef CAPSTONE_DIET
static const map_insn_ops insn_operands[] = {
#include "RISCVMappingInsnOp.inc"
};
#endif
void RISCV_add_cs_detail(MCInst *MI, unsigned OpNum) {
if (!detail_is_set(MI))
return;
cs_op_type op_type = map_get_op_type(MI, OpNum);
if (op_type == CS_OP_IMM) {
RISCV_get_detail_op(MI, 0)->type = RISCV_OP_IMM;
RISCV_get_detail_op(MI, 0)->imm = MCInst_getOpVal(MI, OpNum);
RISCV_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
RISCV_inc_op_count(MI);
}
else if (op_type == CS_OP_REG) {
RISCV_get_detail_op(MI, 0)->type = RISCV_OP_REG;
RISCV_get_detail_op(MI, 0)->reg = MCInst_getOpVal(MI, OpNum);
RISCV_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
RISCV_inc_op_count(MI);
}
else {
CS_ASSERT(0 && "Op type not handled.");
}
}
// given internal insn id, return public instruction info
void RISCV_get_insn_id(cs_struct * h, cs_insn * insn, unsigned int id)
{

View File

@ -13,6 +13,8 @@ const char *RISCV_group_name(csh handle, unsigned int id);
const char *RISCV_reg_name(csh handle, unsigned int reg);
void RISCV_add_cs_detail(MCInst *MI, unsigned OpNum);
// map instruction name to instruction ID
riscv_reg RISCV_map_insn(const char *name);

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@ class RISCVOp(ctypes.Structure):
_fields_ = (
('type', ctypes.c_uint),
('value', RISCVOpValue),
('access', ctypes.c_uint8),
)
@property

View File

@ -6,12 +6,14 @@ from capstone import *
from capstone.riscv import *
from xprint import to_x, to_hex
RISCV_CODE32 = b"\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00"
RISCV_CODE64 = b"\x13\x04\xa8\x7a"
RISCV_CODE32 = b"\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00\x73\x15\x04\xb0\xf3\x56\x00\x10\x33\x05\x7b\x03\xb3\x45\x9c\x03\x33\x66\xbd\x03\x2f\xa4\x02\x10\xaf\x23\x65\x18\x2f\x27\x2f\x01\x43\xf0\x20\x18\xd3\x72\x73\x00\x53\xf4\x04\x58\x53\x85\xc5\x28\x53\x2e\xde\xa1\xd3\x84\x05\xf0\x53\x06\x05\xe0\x53\x75\x00\xc0\xd3\xf0\x05\xd0\xd3\x15\x08\xe0\x87\xaa\x75\x00\x27\x27\x66\x01\x43\xf0\x20\x1a\xd3\x72\x73\x02\x53\xf4\x04\x5a\x53\x85\xc5\x2a\x53\x2e\xde\xa3"
RISCV_CODE64 = b"\x13\x04\xa8\x7a\xbb\x07\x9c\x02\xbb\x40\x5d\x02\x3b\x63\xb7\x03\x2f\xb4\x02\x10\xaf\x33\x65\x18\x2f\x37\x2f\x01\x53\x75\x20\xc0\xd3\xf0\x25\xd0\xd3\x84\x05\xf2\x53\x06\x05\xe2\x53\x75\x00\xc2\xd3\x80\x05\xd2\xd3\x15\x08\xe2\x87\xba\x75\x00\x27\x37\x66\x01"
RISCV_CODEC = b"\xe8\x1f\x7d\x61\x80\x25\x00\x46\x88\xa2\x04\xcb\x55\x13\xf2\x93\x5d\x45\x19\x80\x15\x68\x2a\xa4\x62\x24\xa6\xff\x2a\x65\x76\x86\x65\xdd\x01\x00\xfd\xaf\x82\x82\x11\x20\x82\x94"
all_tests = (
(CS_ARCH_RISCV, CS_MODE_RISCV32, RISCV_CODE32, "riscv32"),
(CS_ARCH_RISCV, CS_MODE_RISCV64, RISCV_CODE64, "riscv64"),
(CS_ARCH_RISCV, CS_MODE_RISCVC, RISCV_CODEC, "riscvc"),
)
@ -39,6 +41,14 @@ def print_insn_detail(insn):
if i.mem.disp != 0:
print("\t\t\toperands[%u].mem.disp: 0x%s" \
% (c, to_x(i.mem.disp)))
if i.access == CS_AC_READ:
print("\t\toperands[%u].access: READ" % (c))
elif i.access == CS_AC_WRITE:
print("\t\toperands[%u].access: WRITE" % (c))
elif i.access == CS_AC_READ | CS_AC_WRITE:
print("\t\toperands[%u].access: READ | WRITE" % (c))
c += 1
if len(insn.groups) > 0:

View File

@ -39,6 +39,20 @@ void print_insn_detail_riscv(csh handle, cs_insn *ins)
break;
}
switch(op->access) {
default:
break;
case CS_AC_READ:
printf("\t\toperands[%u].access: READ\n", i);
break;
case CS_AC_WRITE:
printf("\t\toperands[%u].access: WRITE\n", i);
break;
case CS_AC_READ | CS_AC_WRITE:
printf("\t\toperands[%u].access: READ | WRITE\n", i);
break;
}
}
printf("\n");

View File

@ -46,6 +46,7 @@ typedef struct cs_riscv_op {
int64_t imm; // immediate value for IMM operand
riscv_op_mem mem; // base/disp value for MEM operand
};
uint8_t access; ///< How is this operand accessed? (READ, WRITE or READ|WRITE)
} cs_riscv_op;
// Instruction structure

View File

@ -40,6 +40,20 @@ char *get_detail_riscv(csh *handle, cs_mode mode, cs_insn *ins)
add_str(&result, " ; operands[%u].mem.disp: 0x%x", i, op->mem.disp);
break;
}
switch(op->access) {
default:
break;
case CS_AC_READ:
add_str(&result, " ; operands[%u].access: READ", i);
break;
case CS_AC_WRITE:
add_str(&result, " ; operands[%u].access: WRITE", i);
break;
case CS_AC_READ | CS_AC_WRITE:
add_str(&result, " ; operands[%u].access: READ | WRITE", i);
break;
}
}
return result;

View File

@ -204,6 +204,418 @@
!# CS_ARCH_ARM, CS_MODE_ARM, CS_OPT_DETAIL
0xef,0xf3,0x11,0x85 == ldrhi pc, [r1, #-0x3ef] ; op_count: 2 ; operands[0].type: REG = r15 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = r1 ; operands[1].mem.disp: 0x3ef ; operands[1].access: READ ; Code condition: 8 ; Registers read: cpsr r1 ; Registers modified: r15 ; Groups: IsARM jump
!# issue 0 RISCV operand groups 0x37,0x34,0x00,0x00 == lui s0, 3
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x37,0x34,0x00,0x00 == lui s0, 3 ; op_count: 2 ; operands[0].type: REG = s0 ; operands[0].access: WRITE ; operands[1].type: IMM = 0x3 ; operands[1].access: READ
!# issue 0 RISCV operand groups 0x97,0x82,0x00,0x00 == auipc t0, 8
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x97,0x82,0x00,0x00 == auipc t0, 8 ; op_count: 2 ; operands[0].type: REG = t0 ; operands[0].access: WRITE ; operands[1].type: IMM = 0x8 ; operands[1].access: READ
!# issue 0 RISCV operand groups 0xef,0x00,0x80,0x00 == jal 8
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xef,0x00,0x80,0x00 == jal 8 ; op_count: 1 ; operands[0].type: IMM = 0x8 ; operands[0].access: READ ; Groups: call
!# issue 0 RISCV operand groups 0xef,0xf0,0x1f,0xff == jal -0x10
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xef,0xf0,0x1f,0xff == jal -0x10 ; op_count: 1 ; operands[0].type: IMM = 0xfffffff0 ; operands[0].access: READ ; Groups: call
!# issue 0 RISCV operand groups 0xe7,0x00,0x45,0x00 == jalr ra, a0, 4
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xe7,0x00,0x45,0x00 == jalr ra, a0, 4 ; op_count: 3 ; operands[0].type: REG = ra ; operands[0].access: WRITE ; operands[1].type: REG = a0 ; operands[1].access: READ ; operands[2].type: IMM = 0x4 ; operands[2].access: READ ; Groups: call
!# issue 0 RISCV operand groups 0xe7,0x00,0xc0,0xff == jalr ra, zero, -4
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xe7,0x00,0xc0,0xff == jalr ra, zero, -4 ; op_count: 3 ; operands[0].type: REG = ra ; operands[0].access: WRITE ; operands[1].type: REG = zero ; operands[1].access: READ ; operands[2].type: IMM = 0xfffffffc ; operands[2].access: READ ; Groups: call
!# issue 0 RISCV operand groups 0x63,0x05,0x41,0x00 == beq sp, tp, 0xa
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x63,0x05,0x41,0x00 == beq sp, tp, 0xa ; op_count: 3 ; operands[0].type: REG = sp ; operands[0].access: READ ; operands[1].type: REG = tp ; operands[1].access: READ ; operands[2].type: IMM = 0xa ; operands[2].access: READ ; Groups: branch_relative jump
!# issue 0 RISCV operand groups 0xe3,0x9d,0x61,0xfe == bne gp, t1, -6
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xe3,0x9d,0x61,0xfe == bne gp, t1, -6 ; op_count: 3 ; operands[0].type: REG = gp ; operands[0].access: READ ; operands[1].type: REG = t1 ; operands[1].access: READ ; operands[2].type: IMM = 0xfffffffa ; operands[2].access: READ ; Groups: branch_relative jump
!# issue 0 RISCV operand groups 0x63,0xca,0x93,0x00 == blt t2, s1, 0x14
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x63,0xca,0x93,0x00 == blt t2, s1, 0x14 ; op_count: 3 ; operands[0].type: REG = t2 ; operands[0].access: READ ; operands[1].type: REG = s1 ; operands[1].access: READ ; operands[2].type: IMM = 0x14 ; operands[2].access: READ ; Groups: branch_relative jump
!# issue 0 RISCV operand groups 0x63,0x53,0xb5,0x00 == bge a0, a1, 6
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x63,0x53,0xb5,0x00 == bge a0, a1, 6 ; op_count: 3 ; operands[0].type: REG = a0 ; operands[0].access: READ ; operands[1].type: REG = a1 ; operands[1].access: READ ; operands[2].type: IMM = 0x6 ; operands[2].access: READ ; Groups: branch_relative jump
!# issue 0 RISCV operand groups 0x63,0x65,0xd6,0x00 == bltu a2, a3, 0xa
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x63,0x65,0xd6,0x00 == bltu a2, a3, 0xa ; op_count: 3 ; operands[0].type: REG = a2 ; operands[0].access: READ ; operands[1].type: REG = a3 ; operands[1].access: READ ; operands[2].type: IMM = 0xa ; operands[2].access: READ ; Groups: branch_relative jump
!# issue 0 RISCV operand groups 0x63,0x76,0xf7,0x00 == bgeu a4, a5, 0xc
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x63,0x76,0xf7,0x00 == bgeu a4, a5, 0xc ; op_count: 3 ; operands[0].type: REG = a4 ; operands[0].access: READ ; operands[1].type: REG = a5 ; operands[1].access: READ ; operands[2].type: IMM = 0xc ; operands[2].access: READ ; Groups: branch_relative jump
!# issue 0 RISCV operand groups 0x03,0x88,0x18,0x00 == lb a6, 1(a7)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x03,0x88,0x18,0x00 == lb a6, 1(a7) ; op_count: 2 ; operands[0].type: REG = a6 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = a7 ; operands[1].mem.disp: 0x1 ; operands[1].access: READ
!# issue 0 RISCV operand groups 0x03,0x99,0x49,0x00 == lh s2, 4(s3)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x03,0x99,0x49,0x00 == lh s2, 4(s3) ; op_count: 2 ; operands[0].type: REG = s2 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = s3 ; operands[1].mem.disp: 0x4 ; operands[1].access: READ
!# issue 0 RISCV operand groups 0x03,0xaa,0x6a,0x00 == lw s4, 6(s5)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x03,0xaa,0x6a,0x00 == lw s4, 6(s5) ; op_count: 2 ; operands[0].type: REG = s4 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = s5 ; operands[1].mem.disp: 0x6 ; operands[1].access: READ
!# issue 0 RISCV operand groups 0x03,0xcb,0x2b,0x01 == lbu s6, 0x12(s7)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x03,0xcb,0x2b,0x01 == lbu s6, 0x12(s7) ; op_count: 2 ; operands[0].type: REG = s6 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = s7 ; operands[1].mem.disp: 0x12 ; operands[1].access: READ
!# issue 0 RISCV operand groups 0x03,0xdc,0x8c,0x01 == lhu s8, 0x18(s9)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x03,0xdc,0x8c,0x01 == lhu s8, 0x18(s9) ; op_count: 2 ; operands[0].type: REG = s8 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = s9 ; operands[1].mem.disp: 0x18 ; operands[1].access: READ
!# issue 0 RISCV operand groups 0x23,0x86,0xad,0x03 == sb s10, 0x2c(s11)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x23,0x86,0xad,0x03 == sb s10, 0x2c(s11) ; op_count: 2 ; operands[0].type: REG = s10 ; operands[0].access: READ ; operands[1].type: MEM ; operands[1].mem.base: REG = s11 ; operands[1].mem.disp: 0x2c ; operands[1].access: WRITE
!# issue 0 RISCV operand groups 0x23,0x9a,0xce,0x03 == sh t3, 0x34(t4)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x23,0x9a,0xce,0x03 == sh t3, 0x34(t4) ; op_count: 2 ; operands[0].type: REG = t3 ; operands[0].access: READ ; operands[1].type: MEM ; operands[1].mem.base: REG = t4 ; operands[1].mem.disp: 0x34 ; operands[1].access: WRITE
!# issue 0 RISCV operand groups 0x23,0x8f,0xef,0x01 == sb t5, 0x1e(t6)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x23,0x8f,0xef,0x01 == sb t5, 0x1e(t6) ; op_count: 2 ; operands[0].type: REG = t5 ; operands[0].access: READ ; operands[1].type: MEM ; operands[1].mem.base: REG = t6 ; operands[1].mem.disp: 0x1e ; operands[1].access: WRITE
!# issue 0 RISCV operand groups 0x93,0x00,0xe0,0x00 == addi ra, zero, 0xe
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x93,0x00,0xe0,0x00 == addi ra, zero, 0xe ; op_count: 3 ; operands[0].type: REG = ra ; operands[0].access: WRITE ; operands[1].type: REG = zero ; operands[1].access: READ ; operands[2].type: IMM = 0xe ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x13,0xa1,0x01,0x01 == slti sp, gp, 0x10
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x13,0xa1,0x01,0x01 == slti sp, gp, 0x10 ; op_count: 3 ; operands[0].type: REG = sp ; operands[0].access: WRITE ; operands[1].type: REG = gp ; operands[1].access: READ ; operands[2].type: IMM = 0x10 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x13,0xb2,0x02,0x7d == sltiu tp, t0, 0x7d0
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x13,0xb2,0x02,0x7d == sltiu tp, t0, 0x7d0 ; op_count: 3 ; operands[0].type: REG = tp ; operands[0].access: WRITE ; operands[1].type: REG = t0 ; operands[1].access: READ ; operands[2].type: IMM = 0x7d0 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x13,0xc3,0x03,0xdd == xori t1, t2, -0x230
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x13,0xc3,0x03,0xdd == xori t1, t2, -0x230 ; op_count: 3 ; operands[0].type: REG = t1 ; operands[0].access: WRITE ; operands[1].type: REG = t2 ; operands[1].access: READ ; operands[2].type: IMM = 0xfffffdd0 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x13,0xe4,0xc4,0x12 == ori s0, s1, 0x12c
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x13,0xe4,0xc4,0x12 == ori s0, s1, 0x12c ; op_count: 3 ; operands[0].type: REG = s0 ; operands[0].access: WRITE ; operands[1].type: REG = s1 ; operands[1].access: READ ; operands[2].type: IMM = 0x12c ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x13,0xf5,0x85,0x0c == andi a0, a1, 0xc8
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x13,0xf5,0x85,0x0c == andi a0, a1, 0xc8 ; op_count: 3 ; operands[0].type: REG = a0 ; operands[0].access: WRITE ; operands[1].type: REG = a1 ; operands[1].access: READ ; operands[2].type: IMM = 0xc8 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x13,0x96,0xe6,0x01 == slli a2, a3, 0x1e
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x13,0x96,0xe6,0x01 == slli a2, a3, 0x1e ; op_count: 3 ; operands[0].type: REG = a2 ; operands[0].access: WRITE ; operands[1].type: REG = a3 ; operands[1].access: READ ; operands[2].type: IMM = 0x1e ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x13,0xd7,0x97,0x01 == srli a4, a5, 0x19
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x13,0xd7,0x97,0x01 == srli a4, a5, 0x19 ; op_count: 3 ; operands[0].type: REG = a4 ; operands[0].access: WRITE ; operands[1].type: REG = a5 ; operands[1].access: READ ; operands[2].type: IMM = 0x19 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x13,0xd8,0xf8,0x40 == srai a6, a7, 0xf
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x13,0xd8,0xf8,0x40 == srai a6, a7, 0xf ; op_count: 3 ; operands[0].type: REG = a6 ; operands[0].access: WRITE ; operands[1].type: REG = a7 ; operands[1].access: READ ; operands[2].type: IMM = 0xf ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x33,0x89,0x49,0x01 == add s2, s3, s4
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x33,0x89,0x49,0x01 == add s2, s3, s4 ; op_count: 3 ; operands[0].type: REG = s2 ; operands[0].access: WRITE ; operands[1].type: REG = s3 ; operands[1].access: READ ; operands[2].type: REG = s4 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0xb3,0x0a,0x7b,0x41 == sub s5, s6, s7
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xb3,0x0a,0x7b,0x41 == sub s5, s6, s7 ; op_count: 3 ; operands[0].type: REG = s5 ; operands[0].access: WRITE ; operands[1].type: REG = s6 ; operands[1].access: READ ; operands[2].type: REG = s7 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x33,0xac,0xac,0x01 == slt s8, s9, s10
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x33,0xac,0xac,0x01 == slt s8, s9, s10 ; op_count: 3 ; operands[0].type: REG = s8 ; operands[0].access: WRITE ; operands[1].type: REG = s9 ; operands[1].access: READ ; operands[2].type: REG = s10 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0xb3,0x3d,0xde,0x01 == sltu s11, t3, t4
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xb3,0x3d,0xde,0x01 == sltu s11, t3, t4 ; op_count: 3 ; operands[0].type: REG = s11 ; operands[0].access: WRITE ; operands[1].type: REG = t3 ; operands[1].access: READ ; operands[2].type: REG = t4 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x33,0xd2,0x62,0x40 == sra tp, t0, t1
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x33,0xd2,0x62,0x40 == sra tp, t0, t1 ; op_count: 3 ; operands[0].type: REG = tp ; operands[0].access: WRITE ; operands[1].type: REG = t0 ; operands[1].access: READ ; operands[2].type: REG = t1 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0xb3,0x43,0x94,0x00 == xor t2, s0, s1
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xb3,0x43,0x94,0x00 == xor t2, s0, s1 ; op_count: 3 ; operands[0].type: REG = t2 ; operands[0].access: WRITE ; operands[1].type: REG = s0 ; operands[1].access: READ ; operands[2].type: REG = s1 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x33,0xe5,0xc5,0x00 == or a0, a1, a2
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x33,0xe5,0xc5,0x00 == or a0, a1, a2 ; op_count: 3 ; operands[0].type: REG = a0 ; operands[0].access: WRITE ; operands[1].type: REG = a1 ; operands[1].access: READ ; operands[2].type: REG = a2 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0xb3,0x76,0xf7,0x00 == and a3, a4, a5
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xb3,0x76,0xf7,0x00 == and a3, a4, a5 ; op_count: 3 ; operands[0].type: REG = a3 ; operands[0].access: WRITE ; operands[1].type: REG = a4 ; operands[1].access: READ ; operands[2].type: REG = a5 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0xb3,0x54,0x39,0x01 == srl s1, s2, s3
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xb3,0x54,0x39,0x01 == srl s1, s2, s3 ; op_count: 3 ; operands[0].type: REG = s1 ; operands[0].access: WRITE ; operands[1].type: REG = s2 ; operands[1].access: READ ; operands[2].type: REG = s3 ; operands[2].access: READ
!# issue 0 RISCV operand groups 0xb3,0x50,0x31,0x00 == srl ra, sp, gp
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xb3,0x50,0x31,0x00 == srl ra, sp, gp ; op_count: 3 ; operands[0].type: REG = ra ; operands[0].access: WRITE ; operands[1].type: REG = sp ; operands[1].access: READ ; operands[2].type: REG = gp ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x33,0x9f,0x0f,0x00 == sll t5, t6, zero
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x33,0x9f,0x0f,0x00 == sll t5, t6, zero ; op_count: 3 ; operands[0].type: REG = t5 ; operands[0].access: WRITE ; operands[1].type: REG = t6 ; operands[1].access: READ ; operands[2].type: REG = zero ; operands[2].access: READ
!# issue 0 RISCV operand groups 0x73,0x15,0x04,0xb0 == csrrw a0, mcycle, s0
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x73,0x15,0x04,0xb0 == csrrw a0, mcycle, s0 ; op_count: 2 ; operands[0].type: REG = a0 ; operands[0].access: WRITE ; operands[1].type: REG = s0 ; operands[1].access: READ
!# issue 0 RISCV operand groups 0xf3,0x56,0x00,0x10 == csrrwi a3, sstatus, 0
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xf3,0x56,0x00,0x10 == csrrwi a3, sstatus, 0 ; op_count: 2 ; operands[0].type: REG = a3 ; operands[0].access: WRITE ; operands[1].type: IMM = 0x0 ; operands[1].access: READ
!# issue 0 RISCV operand groups 0x33,0x05,0x7b,0x03 == mul a0, s6, s7
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x33,0x05,0x7b,0x03 == mul a0, s6, s7 ; op_count: 3 ; operands[0].type: REG = a0 ; operands[0].access: WRITE ; operands[1].type: REG = s6 ; operands[1].access: READ ; operands[2].type: REG = s7 ; operands[2].access: READ ; Groups: hasStdExtM
!# issue 0 RISCV operand groups 0xb3,0x45,0x9c,0x03 == div a1, s8, s9
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xb3,0x45,0x9c,0x03 == div a1, s8, s9 ; op_count: 3 ; operands[0].type: REG = a1 ; operands[0].access: WRITE ; operands[1].type: REG = s8 ; operands[1].access: READ ; operands[2].type: REG = s9 ; operands[2].access: READ ; Groups: hasStdExtM
!# issue 0 RISCV operand groups 0x33,0x66,0xbd,0x03 == rem a2, s10, s11
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x33,0x66,0xbd,0x03 == rem a2, s10, s11 ; op_count: 3 ; operands[0].type: REG = a2 ; operands[0].access: WRITE ; operands[1].type: REG = s10 ; operands[1].access: READ ; operands[2].type: REG = s11 ; operands[2].access: READ ; Groups: hasStdExtM
!# issue 0 RISCV operand groups 0x2f,0xa4,0x02,0x10 == lr.w s0, (t0)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x2f,0xa4,0x02,0x10 == lr.w s0, (t0) ; op_count: 2 ; operands[0].type: REG = s0 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = t0 ; operands[1].access: READ ; Groups: hasStdExtA
!# issue 0 RISCV operand groups 0xaf,0x23,0x65,0x18 == sc.w t2, t1, (a0)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xaf,0x23,0x65,0x18 == sc.w t2, t1, (a0) ; op_count: 3 ; operands[0].type: REG = t2 ; operands[0].access: WRITE ; operands[1].type: REG = t1 ; operands[1].access: READ ; operands[2].type: MEM ; operands[2].mem.base: REG = a0 ; operands[2].access: WRITE ; Groups: hasStdExtA
!# issue 0 RISCV operand groups 0x2f,0x27,0x2f,0x01 == amoadd.w a4, s2, (t5)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x2f,0x27,0x2f,0x01 == amoadd.w a4, s2, (t5) ; op_count: 3 ; operands[0].type: REG = a4 ; operands[0].access: WRITE ; operands[1].type: REG = s2 ; operands[1].access: READ ; operands[2].type: MEM ; operands[2].mem.base: REG = t5 ; operands[2].access: READ | WRITE ; Groups: hasStdExtA
!# issue 0 RISCV operand groups 0x43,0xf0,0x20,0x18 == fmadd.s ft0, ft1, ft2, ft3
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x43,0xf0,0x20,0x18 == fmadd.s ft0, ft1, ft2, ft3 ; op_count: 4 ; operands[0].type: REG = ft0 ; operands[0].access: WRITE ; operands[1].type: REG = ft1 ; operands[1].access: READ ; operands[2].type: REG = ft2 ; operands[2].access: READ ; operands[3].type: REG = ft3 ; operands[3].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0xd3,0x72,0x73,0x00 == fadd.s ft5, ft6, ft7
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xd3,0x72,0x73,0x00 == fadd.s ft5, ft6, ft7 ; op_count: 3 ; operands[0].type: REG = ft5 ; operands[0].access: WRITE ; operands[1].type: REG = ft6 ; operands[1].access: READ ; operands[2].type: REG = ft7 ; operands[2].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0x53,0xf4,0x04,0x58 == fsqrt.s fs0, fs1
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x53,0xf4,0x04,0x58 == fsqrt.s fs0, fs1 ; op_count: 2 ; operands[0].type: REG = fs0 ; operands[0].access: WRITE ; operands[1].type: REG = fs1 ; operands[1].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0x53,0x85,0xc5,0x28 == fmin.s fa0, fa1, fa2
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x53,0x85,0xc5,0x28 == fmin.s fa0, fa1, fa2 ; op_count: 3 ; operands[0].type: REG = fa0 ; operands[0].access: WRITE ; operands[1].type: REG = fa1 ; operands[1].access: READ ; operands[2].type: REG = fa2 ; operands[2].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0x53,0x2e,0xde,0xa1 == feq.s t3, ft8, ft9
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x53,0x2e,0xde,0xa1 == feq.s t3, ft8, ft9 ; op_count: 3 ; operands[0].type: REG = t3 ; operands[0].access: WRITE ; operands[1].type: REG = ft8 ; operands[1].access: READ ; operands[2].type: REG = ft9 ; operands[2].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0xd3,0x84,0x05,0xf0 == fmv.w.x fs1, a1
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xd3,0x84,0x05,0xf0 == fmv.w.x fs1, a1 ; op_count: 2 ; operands[0].type: REG = fs1 ; operands[0].access: WRITE ; operands[1].type: REG = a1 ; operands[1].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0x53,0x06,0x05,0xe0 == fmv.x.w a2, fa0
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x53,0x06,0x05,0xe0 == fmv.x.w a2, fa0 ; op_count: 2 ; operands[0].type: REG = a2 ; operands[0].access: WRITE ; operands[1].type: REG = fa0 ; operands[1].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0x53,0x75,0x00,0xc0 == fcvt.w.s a0, ft0
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x53,0x75,0x00,0xc0 == fcvt.w.s a0, ft0 ; op_count: 2 ; operands[0].type: REG = a0 ; operands[0].access: WRITE ; operands[1].type: REG = ft0 ; operands[1].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0xd3,0xf0,0x05,0xd0 == fcvt.s.w ft1, a1
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xd3,0xf0,0x05,0xd0 == fcvt.s.w ft1, a1 ; op_count: 2 ; operands[0].type: REG = ft1 ; operands[0].access: WRITE ; operands[1].type: REG = a1 ; operands[1].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0xd3,0x15,0x08,0xe0 == fclass.s a1, fa6
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xd3,0x15,0x08,0xe0 == fclass.s a1, fa6 ; op_count: 2 ; operands[0].type: REG = a1 ; operands[0].access: WRITE ; operands[1].type: REG = fa6 ; operands[1].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0x87,0xaa,0x75,0x00 == flw fs5, 7(a1)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x87,0xaa,0x75,0x00 == flw fs5, 7(a1) ; op_count: 2 ; operands[0].type: REG = fs5 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = a1 ; operands[1].mem.disp: 0x7 ; operands[1].access: READ ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0x27,0x27,0x66,0x01 == fsw fs6, 0xe(a2)
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x27,0x27,0x66,0x01 == fsw fs6, 0xe(a2) ; op_count: 2 ; operands[0].type: REG = fs6 ; operands[0].access: READ ; operands[1].type: MEM ; operands[1].mem.base: REG = a2 ; operands[1].mem.disp: 0xe ; operands[1].access: WRITE ; Groups: hasStdExtF
!# issue 0 RISCV operand groups 0x43,0xf0,0x20,0x1a == fmadd.d ft0, ft1, ft2, ft3
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x43,0xf0,0x20,0x1a == fmadd.d ft0, ft1, ft2, ft3 ; op_count: 4 ; operands[0].type: REG = ft0 ; operands[0].access: WRITE ; operands[1].type: REG = ft1 ; operands[1].access: READ ; operands[2].type: REG = ft2 ; operands[2].access: READ ; operands[3].type: REG = ft3 ; operands[3].access: READ ; Groups: hasStdExtD
!# issue 0 RISCV operand groups 0xd3,0x72,0x73,0x02 == fadd.d ft5, ft6, ft7
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0xd3,0x72,0x73,0x02 == fadd.d ft5, ft6, ft7 ; op_count: 3 ; operands[0].type: REG = ft5 ; operands[0].access: WRITE ; operands[1].type: REG = ft6 ; operands[1].access: READ ; operands[2].type: REG = ft7 ; operands[2].access: READ ; Groups: hasStdExtD
!# issue 0 RISCV operand groups 0x53,0xf4,0x04,0x5a == fsqrt.d fs0, fs1
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x53,0xf4,0x04,0x5a == fsqrt.d fs0, fs1 ; op_count: 2 ; operands[0].type: REG = fs0 ; operands[0].access: WRITE ; operands[1].type: REG = fs1 ; operands[1].access: READ ; Groups: hasStdExtD
!# issue 0 RISCV operand groups 0x53,0x85,0xc5,0x2a == fmin.d fa0, fa1, fa2
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x53,0x85,0xc5,0x2a == fmin.d fa0, fa1, fa2 ; op_count: 3 ; operands[0].type: REG = fa0 ; operands[0].access: WRITE ; operands[1].type: REG = fa1 ; operands[1].access: READ ; operands[2].type: REG = fa2 ; operands[2].access: READ ; Groups: hasStdExtD
!# issue 0 RISCV operand groups 0x53,0x2e,0xde,0xa3 == feq.d t3, ft8, ft9
!# CS_ARCH_RISCV, CS_MODE_RISCV32, CS_OPT_DETAIL
0x53,0x2e,0xde,0xa3 == feq.d t3, ft8, ft9 ; op_count: 3 ; operands[0].type: REG = t3 ; operands[0].access: WRITE ; operands[1].type: REG = ft8 ; operands[1].access: READ ; operands[2].type: REG = ft9 ; operands[2].access: READ ; Groups: hasStdExtD
!# issue 0 RISCV operand groups 0x13,0x04,0xa8,0x7a == addi s0, a6, 0x7aa
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0x13,0x04,0xa8,0x7a == addi s0, a6, 0x7aa ; op_count: 3 ; operands[0].type: REG = s0 ; operands[0].access: WRITE ; operands[1].type: REG = a6 ; operands[1].access: READ ; operands[2].type: IMM = 0x7aa ; operands[2].access: READ
!# issue 0 RISCV operand groups 0xbb,0x07,0x9c,0x02 == mulw a5, s8, s1
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0xbb,0x07,0x9c,0x02 == mulw a5, s8, s1 ; op_count: 3 ; operands[0].type: REG = a5 ; operands[0].access: WRITE ; operands[1].type: REG = s8 ; operands[1].access: READ ; operands[2].type: REG = s1 ; operands[2].access: READ ; Groups: hasStdExtM isrv64
!# issue 0 RISCV operand groups 0xbb,0x40,0x5d,0x02 == divw ra, s10, t0
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0xbb,0x40,0x5d,0x02 == divw ra, s10, t0 ; op_count: 3 ; operands[0].type: REG = ra ; operands[0].access: WRITE ; operands[1].type: REG = s10 ; operands[1].access: READ ; operands[2].type: REG = t0 ; operands[2].access: READ ; Groups: hasStdExtM isrv64
!# issue 0 RISCV operand groups 0x3b,0x63,0xb7,0x03 == remw t1, a4, s11
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0x3b,0x63,0xb7,0x03 == remw t1, a4, s11 ; op_count: 3 ; operands[0].type: REG = t1 ; operands[0].access: WRITE ; operands[1].type: REG = a4 ; operands[1].access: READ ; operands[2].type: REG = s11 ; operands[2].access: READ ; Groups: hasStdExtM isrv64
!# issue 0 RISCV operand groups 0x2f,0xb4,0x02,0x10 == lr.d s0, (t0)
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0x2f,0xb4,0x02,0x10 == lr.d s0, (t0) ; op_count: 2 ; operands[0].type: REG = s0 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = t0 ; operands[1].access: READ ; Groups: hasStdExtA isrv64
!# issue 0 RISCV operand groups 0xaf,0x33,0x65,0x18 == sc.d t2, t1, (a0)
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0xaf,0x33,0x65,0x18 == sc.d t2, t1, (a0) ; op_count: 3 ; operands[0].type: REG = t2 ; operands[0].access: WRITE ; operands[1].type: REG = t1 ; operands[1].access: READ ; operands[2].type: MEM ; operands[2].mem.base: REG = a0 ; operands[2].access: WRITE ; Groups: hasStdExtA isrv64
!# issue 0 RISCV operand groups 0x2f,0x37,0x2f,0x01 == amoadd.d a4, s2, (t5)
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0x2f,0x37,0x2f,0x01 == amoadd.d a4, s2, (t5) ; op_count: 3 ; operands[0].type: REG = a4 ; operands[0].access: WRITE ; operands[1].type: REG = s2 ; operands[1].access: READ ; operands[2].type: MEM ; operands[2].mem.base: REG = t5 ; operands[2].access: READ | WRITE ; Groups: hasStdExtA isrv64
!# issue 0 RISCV operand groups 0x53,0x75,0x20,0xc0 == fcvt.l.s a0, ft0
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0x53,0x75,0x20,0xc0 == fcvt.l.s a0, ft0 ; op_count: 2 ; operands[0].type: REG = a0 ; operands[0].access: WRITE ; operands[1].type: REG = ft0 ; operands[1].access: READ ; Groups: hasStdExtF isrv64
!# issue 0 RISCV operand groups 0xd3,0xf0,0x25,0xd0 == fcvt.s.l ft1, a1
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0xd3,0xf0,0x25,0xd0 == fcvt.s.l ft1, a1 ; op_count: 2 ; operands[0].type: REG = ft1 ; operands[0].access: WRITE ; operands[1].type: REG = a1 ; operands[1].access: READ ; Groups: hasStdExtF isrv64
!# issue 0 RISCV operand groups 0xd3,0x84,0x05,0xf2 == fmv.d.x fs1, a1
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0xd3,0x84,0x05,0xf2 == fmv.d.x fs1, a1 ; op_count: 2 ; operands[0].type: REG = fs1 ; operands[0].access: WRITE ; operands[1].type: REG = a1 ; operands[1].access: READ ; Groups: hasStdExtD isrv64
!# issue 0 RISCV operand groups 0x53,0x06,0x05,0xe2 == fmv.x.d a2, fa0
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0x53,0x06,0x05,0xe2 == fmv.x.d a2, fa0 ; op_count: 2 ; operands[0].type: REG = a2 ; operands[0].access: WRITE ; operands[1].type: REG = fa0 ; operands[1].access: READ ; Groups: hasStdExtD isrv64
!# issue 0 RISCV operand groups 0x53,0x75,0x00,0xc2 == fcvt.w.d a0, ft0
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0x53,0x75,0x00,0xc2 == fcvt.w.d a0, ft0 ; op_count: 2 ; operands[0].type: REG = a0 ; operands[0].access: WRITE ; operands[1].type: REG = ft0 ; operands[1].access: READ ; Groups: hasStdExtD
!# issue 0 RISCV operand groups 0xd3,0x80,0x05,0xd2 == fcvt.d.w ft1, a1
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0xd3,0x80,0x05,0xd2 == fcvt.d.w ft1, a1 ; op_count: 2 ; operands[0].type: REG = ft1 ; operands[0].access: WRITE ; operands[1].type: REG = a1 ; operands[1].access: READ ; Groups: hasStdExtD
!# issue 0 RISCV operand groups 0xd3,0x15,0x08,0xe2 == fclass.d a1, fa6
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0xd3,0x15,0x08,0xe2 == fclass.d a1, fa6 ; op_count: 2 ; operands[0].type: REG = a1 ; operands[0].access: WRITE ; operands[1].type: REG = fa6 ; operands[1].access: READ ; Groups: hasStdExtD
!# issue 0 RISCV operand groups 0x87,0xba,0x75,0x00 == fld fs5, 7(a1)
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0x87,0xba,0x75,0x00 == fld fs5, 7(a1) ; op_count: 2 ; operands[0].type: REG = fs5 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = a1 ; operands[1].mem.disp: 0x7 ; operands[1].access: READ ; Groups: hasStdExtD
!# issue 0 RISCV operand groups 0x27,0x37,0x66,0x01 == fsd fs6, 0xe(a2)
!# CS_ARCH_RISCV, CS_MODE_RISCV64, CS_OPT_DETAIL
0x27,0x37,0x66,0x01 == fsd fs6, 0xe(a2) ; op_count: 2 ; operands[0].type: REG = fs6 ; operands[0].access: READ ; operands[1].type: MEM ; operands[1].mem.base: REG = a2 ; operands[1].mem.disp: 0xe ; operands[1].access: WRITE ; Groups: hasStdExtD
!# issue 0 RISCV operand groups 0xe8,0x1f == c.addi4spn a0, sp, 0x3fc
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0xe8,0x1f == c.addi4spn a0, sp, 0x3fc ; op_count: 3 ; operands[0].type: REG = a0 ; operands[0].access: WRITE ; operands[1].type: REG = sp ; operands[1].access: READ ; operands[2].type: IMM = 0x3fc ; operands[2].access: READ ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0x7d,0x61 == c.addi16sp sp, 0x1f0
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x7d,0x61 == c.addi16sp sp, 0x1f0 ; op_count: 2 ; operands[0].type: REG = sp ; operands[0].access: READ | WRITE ; operands[1].type: IMM = 0x1f0 ; operands[1].access: READ ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0x80,0x25 == c.fld fs0, 8(a1)
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x80,0x25 == c.fld fs0, 8(a1) ; op_count: 2 ; operands[0].type: REG = fs0 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = a1 ; operands[1].mem.disp: 0x8 ; operands[1].access: READ ; Groups: hasStdExtC hasStdExtD
!# issue 0 RISCV operand groups 0x00,0x46 == c.lw s0, 8(a2)
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x00,0x46 == c.lw s0, 8(a2) ; op_count: 2 ; operands[0].type: REG = s0 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = a2 ; operands[1].mem.disp: 0x8 ; operands[1].access: READ ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0x88,0xa2 == c.fsd fa0, 0(a3)
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x88,0xa2 == c.fsd fa0, 0(a3) ; op_count: 2 ; operands[0].type: REG = fa0 ; operands[0].access: READ ; operands[1].type: MEM ; operands[1].mem.base: REG = a3 ; operands[1].access: WRITE ; Groups: hasStdExtC hasStdExtD
!# issue 0 RISCV operand groups 0x04,0xcb == c.sw s1, 0x10(a4)
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x04,0xcb == c.sw s1, 0x10(a4) ; op_count: 2 ; operands[0].type: REG = s1 ; operands[0].access: READ ; operands[1].type: MEM ; operands[1].mem.base: REG = a4 ; operands[1].mem.disp: 0x10 ; operands[1].access: WRITE ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0x55,0x13 == c.addi t1, -0xb
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x55,0x13 == c.addi t1, -0xb ; op_count: 2 ; operands[0].type: REG = t1 ; operands[0].access: READ | WRITE ; operands[1].type: IMM = 0xfffffff5 ; operands[1].access: READ ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0xf2,0x93 == c.add t2, t3
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0xf2,0x93 == c.add t2, t3 ; op_count: 2 ; operands[0].type: REG = t2 ; operands[0].access: READ | WRITE ; operands[1].type: REG = t3 ; operands[1].access: READ ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0x5d,0x45 == c.li a0, 0x17
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x5d,0x45 == c.li a0, 0x17 ; op_count: 2 ; operands[0].type: REG = a0 ; operands[0].access: WRITE ; operands[1].type: IMM = 0x17 ; operands[1].access: READ ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0x19,0x80 == c.srli s0, 6
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x19,0x80 == c.srli s0, 6 ; op_count: 2 ; operands[0].type: REG = s0 ; operands[0].access: READ | WRITE ; operands[1].type: IMM = 0x6 ; operands[1].access: READ ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0x15,0x68 == c.lui a6, 5
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x15,0x68 == c.lui a6, 5 ; op_count: 2 ; operands[0].type: REG = a6 ; operands[0].access: WRITE ; operands[1].type: IMM = 0x5 ; operands[1].access: READ ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0x2a,0xa4 == c.fsdsp fa0, 8(sp)
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x2a,0xa4 == c.fsdsp fa0, 8(sp) ; op_count: 2 ; operands[0].type: REG = fa0 ; operands[0].access: READ ; operands[1].type: MEM ; operands[1].mem.base: REG = sp ; operands[1].mem.disp: 0x8 ; operands[1].access: WRITE ; Groups: hasStdExtC hasStdExtD
!# issue 0 RISCV operand groups 0x62,0x24 == c.fldsp fs0, 0x18(sp)
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x62,0x24 == c.fldsp fs0, 0x18(sp) ; op_count: 2 ; operands[0].type: REG = fs0 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = sp ; operands[1].mem.disp: 0x18 ; operands[1].access: READ ; Groups: hasStdExtC hasStdExtD
!# issue 0 RISCV operand groups 0xa6,0xff == c.fswsp fs1, 0xfc(sp)
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0xa6,0xff == c.fswsp fs1, 0xfc(sp) ; op_count: 3 ; operands[0].type: REG = fs1 ; operands[0].access: READ ; operands[1].type: IMM = 0xfc ; operands[1].access: READ ; operands[2].type: REG = sp ; operands[2].access: WRITE ; Groups: hasStdExtC hasStdExtF isrv32
!# issue 0 RISCV operand groups 0x2a,0x65 == c.flwsp fa0, 0x88(sp)
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x2a,0x65 == c.flwsp fa0, 0x88(sp) ; op_count: 3 ; operands[0].type: REG = fa0 ; operands[0].access: WRITE ; operands[1].type: IMM = 0x88 ; operands[1].access: READ ; operands[2].type: REG = sp ; operands[2].access: READ ; Groups: hasStdExtC hasStdExtF isrv32
!# issue 0 RISCV operand groups 0x76,0x86 == c.mv a2, t4
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x76,0x86 == c.mv a2, t4 ; op_count: 2 ; operands[0].type: REG = a2 ; operands[0].access: WRITE ; operands[1].type: REG = t4 ; operands[1].access: READ ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0x65,0xdd == c.beqz a0, -8
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x65,0xdd == c.beqz a0, -8 ; op_count: 2 ; operands[0].type: REG = a0 ; operands[0].access: READ ; operands[1].type: IMM = 0xfffffff8 ; operands[1].access: READ ; Groups: hasStdExtC branch_relative jump
!# issue 0 RISCV operand groups 0x01,0x00 == c.nop
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x01,0x00 == c.nop ; Groups: hasStdExtC
!# issue 0 RISCV operand groups 0xfd,0xaf == c.j 0x7fe
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0xfd,0xaf == c.j 0x7fe ; op_count: 1 ; operands[0].type: IMM = 0x7fe ; operands[0].access: READ ; Groups: hasStdExtC jump
!# issue 0 RISCV operand groups 0x82,0x82 == c.jr t0
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x82,0x82 == c.jr t0 ; op_count: 1 ; operands[0].type: REG = t0 ; operands[0].access: READ ; Groups: hasStdExtC jump
!# issue 0 RISCV operand groups 0x11,0x20 == c.jal 4
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x11,0x20 == c.jal 4 ; op_count: 1 ; operands[0].type: IMM = 0x4 ; operands[0].access: READ ; Groups: hasStdExtC isrv32 call
!# issue 0 RISCV operand groups 0x82,0x94 == c.jalr s1
!# CS_ARCH_RISCV, CS_MODE_RISCVC, CS_OPT_DETAIL
0x82,0x94 == c.jalr s1 ; op_count: 1 ; operands[0].type: REG = s1 ; operands[0].access: READ ; Groups: hasStdExtC call
!# issue 2285 AArch64 operands
!# CS_ARCH_AARCH64, CS_MODE_ARM, CS_OPT_DETAIL
0xc0,0x08,0x9f,0xe0 == ld1w {za0h.s[w12, 0]}, p2/z, [x6] ; op_count: 3 ; operands[0].type: SME_MATRIX ; operands[0].sme.type: 2 ; operands[0].sme.tile: za0.s ; operands[0].sme.slice_reg: w12 ; operands[0].sme.slice_offset: 0 ; operands[0].sme.is_vertical: false ; operands[0].access: WRITE ; operands[0].vas: 0x20 ; operands[1].type: PREDICATE ; operands[1].pred.reg: p2 ; operands[1].access: READ ; operands[2].type: MEM ; operands[2].mem.base: REG = x6 ; operands[2].access: READ ; Registers read: w12 p2 x6 ; Registers modified: za0.s ; Groups: HasSME

View File

@ -65,6 +65,20 @@ static void print_insn_detail(cs_insn *ins)
break;
}
switch(op->access) {
default:
break;
case CS_AC_READ:
printf("\t\toperands[%u].access: READ\n", i);
break;
case CS_AC_WRITE:
printf("\t\toperands[%u].access: WRITE\n", i);
break;
case CS_AC_READ | CS_AC_WRITE:
printf("\t\toperands[%u].access: READ | WRITE\n", i);
break;
}
}
//print the groups this instruction belongs to
@ -81,8 +95,9 @@ static void print_insn_detail(cs_insn *ins)
static void test()
{
#define RISCV_CODE32 "\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00"
#define RISCV_CODE64 "\x13\x04\xa8\x7a" // aaa80413
#define RISCV_CODE32 "\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00\x73\x15\x04\xb0\xf3\x56\x00\x10\x33\x05\x7b\x03\xb3\x45\x9c\x03\x33\x66\xbd\x03\x2f\xa4\x02\x10\xaf\x23\x65\x18\x2f\x27\x2f\x01\x43\xf0\x20\x18\xd3\x72\x73\x00\x53\xf4\x04\x58\x53\x85\xc5\x28\x53\x2e\xde\xa1\xd3\x84\x05\xf0\x53\x06\x05\xe0\x53\x75\x00\xc0\xd3\xf0\x05\xd0\xd3\x15\x08\xe0\x87\xaa\x75\x00\x27\x27\x66\x01\x43\xf0\x20\x1a\xd3\x72\x73\x02\x53\xf4\x04\x5a\x53\x85\xc5\x2a\x53\x2e\xde\xa3"
#define RISCV_CODE64 "\x13\x04\xa8\x7a\xbb\x07\x9c\x02\xbb\x40\x5d\x02\x3b\x63\xb7\x03\x2f\xb4\x02\x10\xaf\x33\x65\x18\x2f\x37\x2f\x01\x53\x75\x20\xc0\xd3\xf0\x25\xd0\xd3\x84\x05\xf2\x53\x06\x05\xe2\x53\x75\x00\xc2\xd3\x80\x05\xd2\xd3\x15\x08\xe2\x87\xba\x75\x00\x27\x37\x66\x01"
#define RISCV_CODEC "\xe8\x1f\x7d\x61\x80\x25\x00\x46\x88\xa2\x04\xcb\x55\x13\xf2\x93\x5d\x45\x19\x80\x15\x68\x2a\xa4\x62\x24\xa6\xff\x2a\x65\x76\x86\x65\xdd\x01\x00\xfd\xaf\x82\x82\x11\x20\x82\x94"
struct platform platforms[] = {
{
CS_ARCH_RISCV,
@ -97,6 +112,13 @@ static void test()
(unsigned char *)RISCV_CODE64,
sizeof(RISCV_CODE64) - 1,
"riscv64"
},
{
CS_ARCH_RISCV,
CS_MODE_RISCVC,
(unsigned char *)RISCV_CODEC,
sizeof(RISCV_CODEC) - 1,
"riscvc"
}
};