From 5fb83ca7e227738fa4e1cd844e28b1721d1fe3eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Mon, 19 Jan 2026 00:45:01 +0200 Subject: [PATCH 1/3] remove GNU plugin and remove the pseudo-assembly test --- librz/arch/isa_gnu/riscv/riscv-opc.c | 688 --- librz/arch/isa_gnu/riscv/riscv-opc.h | 1266 ------ librz/arch/isa_gnu/riscv/riscv.c | 333 -- librz/arch/isa_gnu/riscv/riscv.h | 353 -- librz/arch/isa_gnu/riscv/riscv_inc.h | 11 - librz/arch/meson.build | 3 +- .../arch/p_gnu/analysis/analysis_riscv_gnu.c | 940 ---- librz/arch/p_gnu/arch_riscv.c | 15 - librz/arch/p_gnu/asm/asm_riscv_gnu.c | 21 - librz/arch/p_gnu/parse/parse_riscv_gnu.c | 226 - test/db/analysis/riscv | 4043 ++++++++++++++++- 11 files changed, 4039 insertions(+), 3860 deletions(-) delete mode 100644 librz/arch/isa_gnu/riscv/riscv-opc.c delete mode 100644 librz/arch/isa_gnu/riscv/riscv-opc.h delete mode 100644 librz/arch/isa_gnu/riscv/riscv.c delete mode 100644 librz/arch/isa_gnu/riscv/riscv.h delete mode 100644 librz/arch/isa_gnu/riscv/riscv_inc.h delete mode 100644 librz/arch/p_gnu/analysis/analysis_riscv_gnu.c delete mode 100644 librz/arch/p_gnu/arch_riscv.c delete mode 100644 librz/arch/p_gnu/asm/asm_riscv_gnu.c delete mode 100644 librz/arch/p_gnu/parse/parse_riscv_gnu.c diff --git a/librz/arch/isa_gnu/riscv/riscv-opc.c b/librz/arch/isa_gnu/riscv/riscv-opc.c deleted file mode 100644 index 707028d6cbd..00000000000 --- a/librz/arch/isa_gnu/riscv/riscv-opc.c +++ /dev/null @@ -1,688 +0,0 @@ -// SPDX-FileCopyrightText: 2011-2015 Free Software Foundation, Inc. -// SPDX-License-Identifier: GPL-3.0-or-later - -/* RISC-V opcode list - Copyright 2011-2015 Free Software Foundation, Inc. - - Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. - Based on MIPS target. - - This file is part of the GNU opcodes library. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - It is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING3. If not, - see . */ - -#include "riscv.h" -#include - -/* Register names used by gas and objdump. */ - -static const char * const riscv_gpr_names_numeric[NGPR] = -{ - "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", - "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", - "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", - "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31" -}; - -static const char * const riscv_gpr_names_abi[NGPR] = { - "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", - "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", - "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", - "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6" -}; - -static const char * const riscv_fpr_names_numeric[NFPR] = -{ - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" -}; - -static const char * const riscv_fpr_names_abi[NFPR] = { - "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", - "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", - "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", - "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11" -}; - -/* The order of overloaded instructions matters. Label arguments and - register arguments look the same. Instructions that can have either - for arguments must apear in the correct order in this table for the - assembler to pick the right one. In other words, entries with - immediate operands must apear after the same instruction with - registers. - - Because of the lookup algorithm used, entries with the same opcode - name must be contiguous. */ - -#define MASK_RS1 (OP_MASK_RS1 << OP_SH_RS1) -#define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2) -#define MASK_RD (OP_MASK_RD << OP_SH_RD) -#define MASK_CRS2 (OP_MASK_CRS2 << OP_SH_CRS2) -#define MASK_IMM ENCODE_ITYPE_IMM (-1U) -#define MASK_RVC_IMM ENCODE_RVC_IMM (-1U) -#define MASK_UIMM ENCODE_UTYPE_IMM (-1U) -#define MASK_RM (OP_MASK_RM << OP_SH_RM) -#define MASK_PRED (OP_MASK_PRED << OP_SH_PRED) -#define MASK_SUCC (OP_MASK_SUCC << OP_SH_SUCC) -#define MASK_AQ (OP_MASK_AQ << OP_SH_AQ) -#define MASK_RL (OP_MASK_RL << OP_SH_RL) -#define MASK_AQRL (MASK_AQ | MASK_RL) - -static int match_opcode(const struct riscv_opcode *op, insn_t insn) -{ - return ((insn ^ op->match) & op->mask) == 0; -} - -static int match_never(const struct riscv_opcode *op, insn_t insn) -{ - return 0; -} - -static int match_rs1_eq_rs2(const struct riscv_opcode *op, insn_t insn) -{ - int rs1 = (insn & MASK_RS1) >> OP_SH_RS1; - int rs2 = (insn & MASK_RS2) >> OP_SH_RS2; - return match_opcode (op, insn) && rs1 == rs2; -} - -static int match_rd_nonzero(const struct riscv_opcode *op, insn_t insn) -{ - return match_opcode (op, insn) && ((insn & MASK_RD) != 0); -} - -static int match_c_add(const struct riscv_opcode *op, insn_t insn) -{ - return match_rd_nonzero (op, insn) && ((insn & MASK_CRS2) != 0); -} - -static int match_c_lui(const struct riscv_opcode *op, insn_t insn) -{ - return match_rd_nonzero (op, insn) && (((insn & MASK_RD) >> OP_SH_RD) != 2); -} - -static const struct riscv_opcode riscv_builtin_opcodes[] = -{ -/* name, isa, operands, match, mask, match_func, pinfo. */ -{"illegal", "C", "", 0, 0xffffU, match_opcode, 0 }, -{"unimp", "I", "", MATCH_CSRRW | (CSR_CYCLE << OP_SH_CSR), 0xffffffffU, match_opcode, 0 }, /* csrw cycle, x0 */ -{"ebreak", "C", "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, INSN_ALIAS }, -{"ebreak", "I", "", MATCH_EBREAK, MASK_EBREAK, match_opcode, 0 }, -{"sbreak", "C", "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, INSN_ALIAS }, -{"sbreak", "I", "", MATCH_EBREAK, MASK_EBREAK, match_opcode, INSN_ALIAS }, -{"ret", "C", "", MATCH_C_JR | (X_RA << OP_SH_RD), MASK_C_JR | MASK_RD, match_opcode, INSN_ALIAS }, -{"ret", "I", "", MATCH_JALR | (X_RA << OP_SH_RS1), MASK_JALR | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS }, -{"jr", "C", "d", MATCH_C_JR, MASK_C_JR, match_rd_nonzero, INSN_ALIAS }, -{"jr", "I", "s", MATCH_JALR, MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS }, -{"jr", "I", "o(s)", MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS }, -{"jr", "I", "s,j", MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS }, -{"jalr", "C", "d", MATCH_C_JALR, MASK_C_JALR, match_rd_nonzero, INSN_ALIAS }, -{"jalr", "I", "s", MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS }, -{"jalr", "I", "o(s)", MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS }, -{"jalr", "I", "s,j", MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS }, -{"jalr", "I", "d,s", MATCH_JALR, MASK_JALR | MASK_IMM, match_opcode, INSN_ALIAS }, -{"jalr", "I", "d,o(s)", MATCH_JALR, MASK_JALR, match_opcode, 0 }, -{"jalr", "I", "d,s,j", MATCH_JALR, MASK_JALR, match_opcode, 0 }, -{"j", "C", "Ca", MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS }, -{"j", "I", "a", MATCH_JAL, MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS }, -{"jal", "I", "d,a", MATCH_JAL, MASK_JAL, match_opcode, 0 }, -{"jal", "32C", "Ca", MATCH_C_JAL, MASK_C_JAL, match_opcode, INSN_ALIAS }, -{"jal", "I", "a", MATCH_JAL | (X_RA << OP_SH_RD), MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS }, -{"call", "I", "d,c", (X_T1 << OP_SH_RS1), (int) M_CALL, match_never, INSN_MACRO }, -{"call", "I", "c", (X_T1 << OP_SH_RS1) | (X_RA << OP_SH_RD), (int) M_CALL, match_never, INSN_MACRO }, -{"tail", "I", "c", (X_T1 << OP_SH_RS1), (int) M_CALL, match_never, INSN_MACRO }, -{"jump", "I", "c,s", 0, (int) M_CALL, match_never, INSN_MACRO }, -{"nop", "C", "", MATCH_C_ADDI, 0xffff, match_opcode, INSN_ALIAS }, -{"nop", "I", "", MATCH_ADDI, MASK_ADDI | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS }, -{"lui", "C", "d,Cu", MATCH_C_LUI, MASK_C_LUI, match_c_lui, INSN_ALIAS }, -{"lui", "I", "d,u", MATCH_LUI, MASK_LUI, match_opcode, 0 }, -{"li", "C", "d,Cv", MATCH_C_LUI, MASK_C_LUI, match_c_lui, INSN_ALIAS }, -{"li", "C", "d,Cj", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, INSN_ALIAS }, -{"li", "C", "d,0", MATCH_C_LI, MASK_C_LI | MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS }, -{"li", "I", "d,j", MATCH_ADDI, MASK_ADDI | MASK_RS1, match_opcode, INSN_ALIAS }, /* addi */ -{"li", "I", "d,I", 0, (int) M_LI, match_never, INSN_MACRO }, -{"mv", "C", "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS }, -{"mv", "I", "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS }, -{"move", "C", "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS }, -{"move", "I", "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS }, -{"andi", "C", "Cs,Cw,Cj", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS }, -{"andi", "I", "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, 0 }, -{"and", "C", "Cs,Cw,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS }, -{"and", "C", "Cs,Ct,Cw", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS }, -{"and", "C", "Cs,Cw,Cj", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS }, -{"and", "I", "d,s,t", MATCH_AND, MASK_AND, match_opcode, 0 }, -{"and", "I", "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, INSN_ALIAS }, -{"beqz", "C", "Cs,Cp", MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, INSN_ALIAS }, -{"beqz", "I", "s,p", MATCH_BEQ, MASK_BEQ | MASK_RS2, match_opcode, INSN_ALIAS }, -{"beq", "I", "s,t,p", MATCH_BEQ, MASK_BEQ, match_opcode, 0 }, -{"blez", "I", "t,p", MATCH_BGE, MASK_BGE | MASK_RS1, match_opcode, INSN_ALIAS }, -{"bgez", "I", "s,p", MATCH_BGE, MASK_BGE | MASK_RS2, match_opcode, INSN_ALIAS }, -{"ble", "I", "t,s,p", MATCH_BGE, MASK_BGE, match_opcode, INSN_ALIAS }, -{"bleu", "I", "t,s,p", MATCH_BGEU, MASK_BGEU, match_opcode, INSN_ALIAS }, -{"bge", "I", "s,t,p", MATCH_BGE, MASK_BGE, match_opcode, 0 }, -{"bgeu", "I", "s,t,p", MATCH_BGEU, MASK_BGEU, match_opcode, 0 }, -{"bltz", "I", "s,p", MATCH_BLT, MASK_BLT | MASK_RS2, match_opcode, INSN_ALIAS }, -{"bgtz", "I", "t,p", MATCH_BLT, MASK_BLT | MASK_RS1, match_opcode, INSN_ALIAS }, -{"blt", "I", "s,t,p", MATCH_BLT, MASK_BLT, match_opcode, 0 }, -{"bltu", "I", "s,t,p", MATCH_BLTU, MASK_BLTU, match_opcode, 0 }, -{"bgt", "I", "t,s,p", MATCH_BLT, MASK_BLT, match_opcode, INSN_ALIAS }, -{"bgtu", "I", "t,s,p", MATCH_BLTU, MASK_BLTU, match_opcode, INSN_ALIAS }, -{"bnez", "C", "Cs,Cp", MATCH_C_BNEZ, MASK_C_BNEZ, match_opcode, INSN_ALIAS }, -{"bnez", "I", "s,p", MATCH_BNE, MASK_BNE | MASK_RS2, match_opcode, INSN_ALIAS }, -{"bne", "I", "s,t,p", MATCH_BNE, MASK_BNE, match_opcode, 0 }, -{"addi", "C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_opcode, INSN_ALIAS }, -{"addi", "C", "d,CU,Cj", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS }, -{"addi", "C", "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_opcode, INSN_ALIAS }, -{"addi", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, 0 }, -{"add", "C", "d,CU,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS }, -{"add", "C", "d,CV,CU", MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS }, -{"add", "C", "d,CU,Cj", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS }, -{"add", "C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_opcode, INSN_ALIAS }, -{"add", "C", "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_opcode, INSN_ALIAS }, -{"add", "I", "d,s,t", MATCH_ADD, MASK_ADD, match_opcode, 0 }, -{"add", "I", "d,s,t,0",MATCH_ADD, MASK_ADD, match_opcode, 0 }, -{"add", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, INSN_ALIAS }, -{"la", "I", "d,A", 0, (int) M_LA, match_never, INSN_MACRO }, -{"lla", "I", "d,A", 0, (int) M_LLA, match_never, INSN_MACRO }, -{"la.tls.gd", "I", "d,A", 0, (int) M_LA_TLS_GD, match_never, INSN_MACRO }, -{"la.tls.ie", "I", "d,A", 0, (int) M_LA_TLS_IE, match_never, INSN_MACRO }, -{"neg", "I", "d,t", MATCH_SUB, MASK_SUB | MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0 */ -{"slli", "C", "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, INSN_ALIAS }, -{"slli", "I", "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, 0 }, -{"sll", "C", "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, INSN_ALIAS }, -{"sll", "I", "d,s,t", MATCH_SLL, MASK_SLL, match_opcode, 0 }, -{"sll", "I", "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, INSN_ALIAS }, -{"srli", "C", "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_rd_nonzero, INSN_ALIAS }, -{"srli", "I", "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, 0 }, -{"srl", "C", "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_rd_nonzero, INSN_ALIAS }, -{"srl", "I", "d,s,t", MATCH_SRL, MASK_SRL, match_opcode, 0 }, -{"srl", "I", "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, INSN_ALIAS }, -{"srai", "C", "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_rd_nonzero, INSN_ALIAS }, -{"srai", "I", "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, 0 }, -{"sra", "C", "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_rd_nonzero, INSN_ALIAS }, -{"sra", "I", "d,s,t", MATCH_SRA, MASK_SRA, match_opcode, 0 }, -{"sra", "I", "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, INSN_ALIAS }, -{"sub", "C", "Cs,Cw,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, INSN_ALIAS }, -{"sub", "I", "d,s,t", MATCH_SUB, MASK_SUB, match_opcode, 0 }, -{"lb", "I", "d,o(s)", MATCH_LB, MASK_LB, match_opcode, 0 }, -{"lb", "I", "d,A", 0, (int) M_LB, match_never, INSN_MACRO }, -{"lbu", "I", "d,o(s)", MATCH_LBU, MASK_LBU, match_opcode, 0 }, -{"lbu", "I", "d,A", 0, (int) M_LBU, match_never, INSN_MACRO }, -{"lh", "I", "d,o(s)", MATCH_LH, MASK_LH, match_opcode, 0 }, -{"lh", "I", "d,A", 0, (int) M_LH, match_never, INSN_MACRO }, -{"lhu", "I", "d,o(s)", MATCH_LHU, MASK_LHU, match_opcode, 0 }, -{"lhu", "I", "d,A", 0, (int) M_LHU, match_never, INSN_MACRO }, -{"lw", "C", "d,Cm(Cc)", MATCH_C_LWSP, MASK_C_LWSP, match_rd_nonzero, INSN_ALIAS }, -{"lw", "C", "Ct,Ck(Cs)", MATCH_C_LW, MASK_C_LW, match_opcode, INSN_ALIAS }, -{"lw", "I", "d,o(s)", MATCH_LW, MASK_LW, match_opcode, 0 }, -{"lw", "I", "d,A", 0, (int) M_LW, match_never, INSN_MACRO }, -{"not", "I", "d,s", MATCH_XORI | MASK_IMM, MASK_XORI | MASK_IMM, match_opcode, INSN_ALIAS }, -{"ori", "I", "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, 0 }, -{"or", "C", "Cs,Cw,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS }, -{"or", "C", "Cs,Ct,Cw", MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS }, -{"or", "I", "d,s,t", MATCH_OR, MASK_OR, match_opcode, 0 }, -{"or", "I", "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS }, -{"auipc", "I", "d,u", MATCH_AUIPC, MASK_AUIPC, match_opcode, 0 }, -{"seqz", "I", "d,s", MATCH_SLTIU | ENCODE_ITYPE_IMM (1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS }, -{"snez", "I", "d,t", MATCH_SLTU, MASK_SLTU | MASK_RS1, match_opcode, INSN_ALIAS }, -{"sltz", "I", "d,s", MATCH_SLT, MASK_SLT | MASK_RS2, match_opcode, INSN_ALIAS }, -{"sgtz", "I", "d,t", MATCH_SLT, MASK_SLT | MASK_RS1, match_opcode, INSN_ALIAS }, -{"slti", "I", "d,s,j", MATCH_SLTI, MASK_SLTI, match_opcode, INSN_ALIAS }, -{"slt", "I", "d,s,t", MATCH_SLT, MASK_SLT, match_opcode, 0 }, -{"slt", "I", "d,s,j", MATCH_SLTI, MASK_SLTI, match_opcode, 0 }, -{"sltiu", "I", "d,s,j", MATCH_SLTIU, MASK_SLTIU, match_opcode, 0 }, -{"sltu", "I", "d,s,t", MATCH_SLTU, MASK_SLTU, match_opcode, 0 }, -{"sltu", "I", "d,s,j", MATCH_SLTIU, MASK_SLTIU, match_opcode, INSN_ALIAS }, -{"sgt", "I", "d,t,s", MATCH_SLT, MASK_SLT, match_opcode, INSN_ALIAS }, -{"sgtu", "I", "d,t,s", MATCH_SLTU, MASK_SLTU, match_opcode, INSN_ALIAS }, -{"sb", "I", "t,q(s)", MATCH_SB, MASK_SB, match_opcode, 0 }, -{"sb", "I", "t,A,s", 0, (int) M_SB, match_never, INSN_MACRO }, -{"sh", "I", "t,q(s)", MATCH_SH, MASK_SH, match_opcode, 0 }, -{"sh", "I", "t,A,s", 0, (int) M_SH, match_never, INSN_MACRO }, -{"sw", "C", "CV,CM(Cc)", MATCH_C_SWSP, MASK_C_SWSP, match_opcode, INSN_ALIAS }, -{"sw", "C", "Ct,Ck(Cs)", MATCH_C_SW, MASK_C_SW, match_opcode, INSN_ALIAS }, -{"sw", "I", "t,q(s)", MATCH_SW, MASK_SW, match_opcode, 0 }, -{"sw", "I", "t,A,s", 0, (int) M_SW, match_never, INSN_MACRO }, -{"fence", "I", "", MATCH_FENCE | MASK_PRED | MASK_SUCC, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS }, -{"fence", "I", "P,Q", MATCH_FENCE, MASK_FENCE | MASK_RD | MASK_RS1 | (MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 }, -{"fence.i", "I", "", MATCH_FENCE_I, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, 0 }, -{"rdcycle", "I", "d", MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, INSN_ALIAS }, -{"rdinstret", "I", "d", MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, INSN_ALIAS }, -{"rdtime", "I", "d", MATCH_RDTIME, MASK_RDTIME, match_opcode, INSN_ALIAS }, -{"rdcycleh", "32I", "d", MATCH_RDCYCLEH, MASK_RDCYCLEH, match_opcode, INSN_ALIAS }, -{"rdinstreth","32I", "d", MATCH_RDINSTRETH, MASK_RDINSTRETH, match_opcode, INSN_ALIAS }, -{"rdtimeh", "32I", "d", MATCH_RDTIMEH, MASK_RDTIMEH, match_opcode, INSN_ALIAS }, -{"ecall", "I", "", MATCH_SCALL, MASK_SCALL, match_opcode, 0 }, -{"scall", "I", "", MATCH_SCALL, MASK_SCALL, match_opcode, 0 }, -{"xori", "I", "d,s,j", MATCH_XORI, MASK_XORI, match_opcode, 0 }, -{"xor", "C", "Cs,Cw,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, INSN_ALIAS }, -{"xor", "C", "Cs,Ct,Cw", MATCH_C_XOR, MASK_C_XOR, match_opcode, INSN_ALIAS }, -{"xor", "I", "d,s,t", MATCH_XOR, MASK_XOR, match_opcode, 0 }, -{"xor", "I", "d,s,j", MATCH_XORI, MASK_XORI, match_opcode, INSN_ALIAS }, -{"lwu", "64I", "d,o(s)", MATCH_LWU, MASK_LWU, match_opcode, 0 }, -{"lwu", "64I", "d,A", 0, (int) M_LWU, match_never, INSN_MACRO }, -{"ld", "64C", "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_ALIAS }, -{"ld", "64C", "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_ALIAS }, -{"ld", "64I", "d,o(s)", MATCH_LD, MASK_LD, match_opcode, 0 }, -{"ld", "64I", "d,A", 0, (int) M_LD, match_never, INSN_MACRO }, -{"sd", "64C", "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_ALIAS }, -{"sd", "64C", "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_ALIAS }, -{"sd", "64I", "t,q(s)", MATCH_SD, MASK_SD, match_opcode, 0 }, -{"sd", "64I", "t,A,s", 0, (int) M_SD, match_never, INSN_MACRO }, -{"sext.w", "64C", "d,CU", MATCH_C_ADDIW, MASK_C_ADDIW | MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS }, -{"sext.w", "64I", "d,s", MATCH_ADDIW, MASK_ADDIW | MASK_IMM, match_opcode, INSN_ALIAS }, -{"addiw", "64C", "d,CU,Cj", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS }, -{"addiw", "64I", "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, 0 }, -{"addw", "64C", "Cs,Cw,Ct", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, INSN_ALIAS }, -{"addw", "64C", "Cs,Ct,Cw", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, INSN_ALIAS }, -{"addw", "64C", "d,CU,Cj", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS }, -{"addw", "64I", "d,s,t", MATCH_ADDW, MASK_ADDW, match_opcode, 0 }, -{"addw", "64I", "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, INSN_ALIAS }, -{"negw", "64I", "d,t", MATCH_SUBW, MASK_SUBW | MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0 */ -{"slliw", "64I", "d,s,<", MATCH_SLLIW, MASK_SLLIW, match_opcode, 0 }, -{"sllw", "64I", "d,s,t", MATCH_SLLW, MASK_SLLW, match_opcode, 0 }, -{"sllw", "64I", "d,s,<", MATCH_SLLIW, MASK_SLLIW, match_opcode, INSN_ALIAS }, -{"srliw", "64I", "d,s,<", MATCH_SRLIW, MASK_SRLIW, match_opcode, 0 }, -{"srlw", "64I", "d,s,t", MATCH_SRLW, MASK_SRLW, match_opcode, 0 }, -{"srlw", "64I", "d,s,<", MATCH_SRLIW, MASK_SRLIW, match_opcode, INSN_ALIAS }, -{"sraiw", "64I", "d,s,<", MATCH_SRAIW, MASK_SRAIW, match_opcode, 0 }, -{"sraw", "64I", "d,s,t", MATCH_SRAW, MASK_SRAW, match_opcode, 0 }, -{"sraw", "64I", "d,s,<", MATCH_SRAIW, MASK_SRAIW, match_opcode, INSN_ALIAS }, -{"subw", "64C", "Cs,Cw,Ct", MATCH_C_SUBW, MASK_C_SUBW, match_opcode, INSN_ALIAS }, -{"subw", "64I", "d,s,t", MATCH_SUBW, MASK_SUBW, match_opcode, 0 }, - -/* Atomic memory operation instruction subset */ -{"lr.w", "A", "d,0(s)", MATCH_LR_W, MASK_LR_W | MASK_AQRL, match_opcode, 0 }, -{"sc.w", "A", "d,t,0(s)", MATCH_SC_W, MASK_SC_W | MASK_AQRL, match_opcode, 0 }, -{"amoadd.w", "A", "d,t,0(s)", MATCH_AMOADD_W, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 }, -{"amoswap.w", "A", "d,t,0(s)", MATCH_AMOSWAP_W, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 }, -{"amoand.w", "A", "d,t,0(s)", MATCH_AMOAND_W, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 }, -{"amoor.w", "A", "d,t,0(s)", MATCH_AMOOR_W, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 }, -{"amoxor.w", "A", "d,t,0(s)", MATCH_AMOXOR_W, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 }, -{"amomax.w", "A", "d,t,0(s)", MATCH_AMOMAX_W, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 }, -{"amomaxu.w", "A", "d,t,0(s)", MATCH_AMOMAXU_W, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 }, -{"amomin.w", "A", "d,t,0(s)", MATCH_AMOMIN_W, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 }, -{"amominu.w", "A", "d,t,0(s)", MATCH_AMOMINU_W, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 }, -{"lr.w.aq", "A", "d,0(s)", MATCH_LR_W | MASK_AQ, MASK_LR_W | MASK_AQRL, match_opcode, 0 }, -{"sc.w.aq", "A", "d,t,0(s)", MATCH_SC_W | MASK_AQ, MASK_SC_W | MASK_AQRL, match_opcode, 0 }, -{"amoadd.w.aq", "A", "d,t,0(s)", MATCH_AMOADD_W | MASK_AQ, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 }, -{"amoswap.w.aq", "A", "d,t,0(s)", MATCH_AMOSWAP_W | MASK_AQ, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 }, -{"amoand.w.aq", "A", "d,t,0(s)", MATCH_AMOAND_W | MASK_AQ, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 }, -{"amoor.w.aq", "A", "d,t,0(s)", MATCH_AMOOR_W | MASK_AQ, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 }, -{"amoxor.w.aq", "A", "d,t,0(s)", MATCH_AMOXOR_W | MASK_AQ, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 }, -{"amomax.w.aq", "A", "d,t,0(s)", MATCH_AMOMAX_W | MASK_AQ, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 }, -{"amomaxu.w.aq", "A", "d,t,0(s)", MATCH_AMOMAXU_W | MASK_AQ, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 }, -{"amomin.w.aq", "A", "d,t,0(s)", MATCH_AMOMIN_W | MASK_AQ, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 }, -{"amominu.w.aq", "A", "d,t,0(s)", MATCH_AMOMINU_W | MASK_AQ, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 }, -{"lr.w.rl", "A", "d,0(s)", MATCH_LR_W | MASK_RL, MASK_LR_W | MASK_AQRL, match_opcode, 0 }, -{"sc.w.rl", "A", "d,t,0(s)", MATCH_SC_W | MASK_RL, MASK_SC_W | MASK_AQRL, match_opcode, 0 }, -{"amoadd.w.rl", "A", "d,t,0(s)", MATCH_AMOADD_W | MASK_RL, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 }, -{"amoswap.w.rl", "A", "d,t,0(s)", MATCH_AMOSWAP_W | MASK_RL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 }, -{"amoand.w.rl", "A", "d,t,0(s)", MATCH_AMOAND_W | MASK_RL, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 }, -{"amoor.w.rl", "A", "d,t,0(s)", MATCH_AMOOR_W | MASK_RL, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 }, -{"amoxor.w.rl", "A", "d,t,0(s)", MATCH_AMOXOR_W | MASK_RL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 }, -{"amomax.w.rl", "A", "d,t,0(s)", MATCH_AMOMAX_W | MASK_RL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 }, -{"amomaxu.w.rl", "A", "d,t,0(s)", MATCH_AMOMAXU_W | MASK_RL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 }, -{"amomin.w.rl", "A", "d,t,0(s)", MATCH_AMOMIN_W | MASK_RL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 }, -{"amominu.w.rl", "A", "d,t,0(s)", MATCH_AMOMINU_W | MASK_RL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 }, -{"lr.w.aqrl", "A", "d,0(s)", MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, 0 }, -{"sc.w.aqrl", "A", "d,t,0(s)", MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, 0 }, -{"amoadd.w.aqrl", "A", "d,t,0(s)", MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 }, -{"amoswap.w.aqrl", "A", "d,t,0(s)", MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 }, -{"amoand.w.aqrl", "A", "d,t,0(s)", MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 }, -{"amoor.w.aqrl", "A", "d,t,0(s)", MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 }, -{"amoxor.w.aqrl", "A", "d,t,0(s)", MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 }, -{"amomax.w.aqrl", "A", "d,t,0(s)", MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 }, -{"amomaxu.w.aqrl", "A", "d,t,0(s)", MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 }, -{"amomin.w.aqrl", "A", "d,t,0(s)", MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 }, -{"amominu.w.aqrl", "A", "d,t,0(s)", MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 }, -{"lr.d", "64A", "d,0(s)", MATCH_LR_D, MASK_LR_D | MASK_AQRL, match_opcode, 0 }, -{"sc.d", "64A", "d,t,0(s)", MATCH_SC_D, MASK_SC_D | MASK_AQRL, match_opcode, 0 }, -{"amoadd.d", "64A", "d,t,0(s)", MATCH_AMOADD_D, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 }, -{"amoswap.d", "64A", "d,t,0(s)", MATCH_AMOSWAP_D, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 }, -{"amoand.d", "64A", "d,t,0(s)", MATCH_AMOAND_D, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 }, -{"amoor.d", "64A", "d,t,0(s)", MATCH_AMOOR_D, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 }, -{"amoxor.d", "64A", "d,t,0(s)", MATCH_AMOXOR_D, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 }, -{"amomax.d", "64A", "d,t,0(s)", MATCH_AMOMAX_D, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 }, -{"amomaxu.d", "64A", "d,t,0(s)", MATCH_AMOMAXU_D, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 }, -{"amomin.d", "64A", "d,t,0(s)", MATCH_AMOMIN_D, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 }, -{"amominu.d", "64A", "d,t,0(s)", MATCH_AMOMINU_D, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 }, -{"lr.d.aq", "64A", "d,0(s)", MATCH_LR_D | MASK_AQ, MASK_LR_D | MASK_AQRL, match_opcode, 0 }, -{"sc.d.aq", "64A", "d,t,0(s)", MATCH_SC_D | MASK_AQ, MASK_SC_D | MASK_AQRL, match_opcode, 0 }, -{"amoadd.d.aq", "64A", "d,t,0(s)", MATCH_AMOADD_D | MASK_AQ, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 }, -{"amoswap.d.aq", "64A", "d,t,0(s)", MATCH_AMOSWAP_D | MASK_AQ, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 }, -{"amoand.d.aq", "64A", "d,t,0(s)", MATCH_AMOAND_D | MASK_AQ, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 }, -{"amoor.d.aq", "64A", "d,t,0(s)", MATCH_AMOOR_D | MASK_AQ, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 }, -{"amoxor.d.aq", "64A", "d,t,0(s)", MATCH_AMOXOR_D | MASK_AQ, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 }, -{"amomax.d.aq", "64A", "d,t,0(s)", MATCH_AMOMAX_D | MASK_AQ, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 }, -{"amomaxu.d.aq", "64A", "d,t,0(s)", MATCH_AMOMAXU_D | MASK_AQ, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 }, -{"amomin.d.aq", "64A", "d,t,0(s)", MATCH_AMOMIN_D | MASK_AQ, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 }, -{"amominu.d.aq", "64A", "d,t,0(s)", MATCH_AMOMINU_D | MASK_AQ, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 }, -{"lr.d.rl", "64A", "d,0(s)", MATCH_LR_D | MASK_RL, MASK_LR_D | MASK_AQRL, match_opcode, 0 }, -{"sc.d.rl", "64A", "d,t,0(s)", MATCH_SC_D | MASK_RL, MASK_SC_D | MASK_AQRL, match_opcode, 0 }, -{"amoadd.d.rl", "64A", "d,t,0(s)", MATCH_AMOADD_D | MASK_RL, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 }, -{"amoswap.d.rl", "64A", "d,t,0(s)", MATCH_AMOSWAP_D | MASK_RL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 }, -{"amoand.d.rl", "64A", "d,t,0(s)", MATCH_AMOAND_D | MASK_RL, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 }, -{"amoor.d.rl", "64A", "d,t,0(s)", MATCH_AMOOR_D | MASK_RL, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 }, -{"amoxor.d.rl", "64A", "d,t,0(s)", MATCH_AMOXOR_D | MASK_RL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 }, -{"amomax.d.rl", "64A", "d,t,0(s)", MATCH_AMOMAX_D | MASK_RL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 }, -{"amomaxu.d.rl", "64A", "d,t,0(s)", MATCH_AMOMAXU_D | MASK_RL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 }, -{"amomin.d.rl", "64A", "d,t,0(s)", MATCH_AMOMIN_D | MASK_RL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 }, -{"amominu.d.rl", "64A", "d,t,0(s)", MATCH_AMOMINU_D | MASK_RL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 }, -{"lr.d.aqrl", "64A", "d,0(s)", MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, 0 }, -{"sc.d.aqrl", "64A", "d,t,0(s)", MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, 0 }, -{"amoadd.d.aqrl", "64A", "d,t,0(s)", MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 }, -{"amoswap.d.aqrl", "64A", "d,t,0(s)", MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 }, -{"amoand.d.aqrl", "64A", "d,t,0(s)", MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 }, -{"amoor.d.aqrl", "64A", "d,t,0(s)", MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 }, -{"amoxor.d.aqrl", "64A", "d,t,0(s)", MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 }, -{"amomax.d.aqrl", "64A", "d,t,0(s)", MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 }, -{"amomaxu.d.aqrl", "64A", "d,t,0(s)", MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 }, -{"amomin.d.aqrl", "64A", "d,t,0(s)", MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 }, -{"amominu.d.aqrl", "64A", "d,t,0(s)", MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 }, - -/* Multiply/Divide instruction subset */ -{"mul", "M", "d,s,t", MATCH_MUL, MASK_MUL, match_opcode, 0 }, -{"mulh", "M", "d,s,t", MATCH_MULH, MASK_MULH, match_opcode, 0 }, -{"mulhu", "M", "d,s,t", MATCH_MULHU, MASK_MULHU, match_opcode, 0 }, -{"mulhsu", "M", "d,s,t", MATCH_MULHSU, MASK_MULHSU, match_opcode, 0 }, -{"div", "M", "d,s,t", MATCH_DIV, MASK_DIV, match_opcode, 0 }, -{"divu", "M", "d,s,t", MATCH_DIVU, MASK_DIVU, match_opcode, 0 }, -{"rem", "M", "d,s,t", MATCH_REM, MASK_REM, match_opcode, 0 }, -{"remu", "M", "d,s,t", MATCH_REMU, MASK_REMU, match_opcode, 0 }, -{"mulw", "64M", "d,s,t", MATCH_MULW, MASK_MULW, match_opcode, 0 }, -{"divw", "64M", "d,s,t", MATCH_DIVW, MASK_DIVW, match_opcode, 0 }, -{"divuw", "64M", "d,s,t", MATCH_DIVUW, MASK_DIVUW, match_opcode, 0 }, -{"remw", "64M", "d,s,t", MATCH_REMW, MASK_REMW, match_opcode, 0 }, -{"remuw", "64M", "d,s,t", MATCH_REMUW, MASK_REMUW, match_opcode, 0 }, - -/* Single-precision floating-point instruction subset */ -{"frsr", "F", "d", MATCH_FRCSR, MASK_FRCSR, match_opcode, 0 }, -{"fssr", "F", "s", MATCH_FSCSR, MASK_FSCSR | MASK_RD, match_opcode, 0 }, -{"fssr", "F", "d,s", MATCH_FSCSR, MASK_FSCSR, match_opcode, 0 }, -{"frcsr", "F", "d", MATCH_FRCSR, MASK_FRCSR, match_opcode, 0 }, -{"fscsr", "F", "s", MATCH_FSCSR, MASK_FSCSR | MASK_RD, match_opcode, 0 }, -{"fscsr", "F", "d,s", MATCH_FSCSR, MASK_FSCSR, match_opcode, 0 }, -{"frrm", "F", "d", MATCH_FRRM, MASK_FRRM, match_opcode, 0 }, -{"fsrm", "F", "s", MATCH_FSRM, MASK_FSRM | MASK_RD, match_opcode, 0 }, -{"fsrm", "F", "d,s", MATCH_FSRM, MASK_FSRM, match_opcode, 0 }, -{"frflags", "F", "d", MATCH_FRFLAGS, MASK_FRFLAGS, match_opcode, 0 }, -{"fsflags", "F", "s", MATCH_FSFLAGS, MASK_FSFLAGS | MASK_RD, match_opcode, 0 }, -{"fsflags", "F", "d,s", MATCH_FSFLAGS, MASK_FSFLAGS, match_opcode, 0 }, -{"flw", "32C", "D,Cm(Cc)", MATCH_C_FLWSP, MASK_C_FLWSP, match_opcode, INSN_ALIAS }, -{"flw", "32C", "CD,Ck(Cs)", MATCH_C_FLW, MASK_C_FLW, match_opcode, INSN_ALIAS }, -{"flw", "F", "D,o(s)", MATCH_FLW, MASK_FLW, match_opcode, 0 }, -{"flw", "F", "D,A,s", 0, (int) M_FLW, match_never, INSN_MACRO }, -{"fsw", "32C", "CT,CM(Cc)", MATCH_C_FSWSP, MASK_C_FSWSP, match_opcode, INSN_ALIAS }, -{"fsw", "32C", "CD,Ck(Cs)", MATCH_C_FSW, MASK_C_FSW, match_opcode, INSN_ALIAS }, -{"fsw", "F", "T,q(s)", MATCH_FSW, MASK_FSW, match_opcode, 0 }, -{"fsw", "F", "T,A,s", 0, (int) M_FSW, match_never, INSN_MACRO }, -{"fmv.x.s", "F", "d,S", MATCH_FMV_X_S, MASK_FMV_X_S, match_opcode, 0 }, -{"fmv.s.x", "F", "D,s", MATCH_FMV_S_X, MASK_FMV_S_X, match_opcode, 0 }, -{"fmv.s", "F", "D,U", MATCH_FSGNJ_S, MASK_FSGNJ_S, match_rs1_eq_rs2, INSN_ALIAS }, -{"fneg.s", "F", "D,U", MATCH_FSGNJN_S, MASK_FSGNJN_S, match_rs1_eq_rs2, INSN_ALIAS }, -{"fabs.s", "F", "D,U", MATCH_FSGNJX_S, MASK_FSGNJX_S, match_rs1_eq_rs2, INSN_ALIAS }, -{"fsgnj.s", "F", "D,S,T", MATCH_FSGNJ_S, MASK_FSGNJ_S, match_opcode, 0 }, -{"fsgnjn.s", "F", "D,S,T", MATCH_FSGNJN_S, MASK_FSGNJN_S, match_opcode, 0 }, -{"fsgnjx.s", "F", "D,S,T", MATCH_FSGNJX_S, MASK_FSGNJX_S, match_opcode, 0 }, -{"fadd.s", "F", "D,S,T", MATCH_FADD_S | MASK_RM, MASK_FADD_S | MASK_RM, match_opcode, 0 }, -{"fadd.s", "F", "D,S,T,m", MATCH_FADD_S, MASK_FADD_S, match_opcode, 0 }, -{"fsub.s", "F", "D,S,T", MATCH_FSUB_S | MASK_RM, MASK_FSUB_S | MASK_RM, match_opcode, 0 }, -{"fsub.s", "F", "D,S,T,m", MATCH_FSUB_S, MASK_FSUB_S, match_opcode, 0 }, -{"fmul.s", "F", "D,S,T", MATCH_FMUL_S | MASK_RM, MASK_FMUL_S | MASK_RM, match_opcode, 0 }, -{"fmul.s", "F", "D,S,T,m", MATCH_FMUL_S, MASK_FMUL_S, match_opcode, 0 }, -{"fdiv.s", "F", "D,S,T", MATCH_FDIV_S | MASK_RM, MASK_FDIV_S | MASK_RM, match_opcode, 0 }, -{"fdiv.s", "F", "D,S,T,m", MATCH_FDIV_S, MASK_FDIV_S, match_opcode, 0 }, -{"fsqrt.s", "F", "D,S", MATCH_FSQRT_S | MASK_RM, MASK_FSQRT_S | MASK_RM, match_opcode, 0 }, -{"fsqrt.s", "F", "D,S,m", MATCH_FSQRT_S, MASK_FSQRT_S, match_opcode, 0 }, -{"fmin.s", "F", "D,S,T", MATCH_FMIN_S, MASK_FMIN_S, match_opcode, 0 }, -{"fmax.s", "F", "D,S,T", MATCH_FMAX_S, MASK_FMAX_S, match_opcode, 0 }, -{"fmadd.s", "F", "D,S,T,R", MATCH_FMADD_S | MASK_RM, MASK_FMADD_S | MASK_RM, match_opcode, 0 }, -{"fmadd.s", "F", "D,S,T,R,m", MATCH_FMADD_S, MASK_FMADD_S, match_opcode, 0 }, -{"fnmadd.s", "F", "D,S,T,R", MATCH_FNMADD_S | MASK_RM, MASK_FNMADD_S | MASK_RM, match_opcode, 0 }, -{"fnmadd.s", "F", "D,S,T,R,m", MATCH_FNMADD_S, MASK_FNMADD_S, match_opcode, 0 }, -{"fmsub.s", "F", "D,S,T,R", MATCH_FMSUB_S | MASK_RM, MASK_FMSUB_S | MASK_RM, match_opcode, 0 }, -{"fmsub.s", "F", "D,S,T,R,m", MATCH_FMSUB_S, MASK_FMSUB_S, match_opcode, 0 }, -{"fnmsub.s", "F", "D,S,T,R", MATCH_FNMSUB_S | MASK_RM, MASK_FNMSUB_S | MASK_RM, match_opcode, 0 }, -{"fnmsub.s", "F", "D,S,T,R,m", MATCH_FNMSUB_S, MASK_FNMSUB_S, match_opcode, 0 }, -{"fcvt.w.s", "F", "d,S", MATCH_FCVT_W_S | MASK_RM, MASK_FCVT_W_S | MASK_RM, match_opcode, 0 }, -{"fcvt.w.s", "F", "d,S,m", MATCH_FCVT_W_S, MASK_FCVT_W_S, match_opcode, 0 }, -{"fcvt.wu.s", "F", "d,S", MATCH_FCVT_WU_S | MASK_RM, MASK_FCVT_WU_S | MASK_RM, match_opcode, 0 }, -{"fcvt.wu.s", "F", "d,S,m", MATCH_FCVT_WU_S, MASK_FCVT_WU_S, match_opcode, 0 }, -{"fcvt.s.w", "F", "D,s", MATCH_FCVT_S_W | MASK_RM, MASK_FCVT_S_W | MASK_RM, match_opcode, 0 }, -{"fcvt.s.w", "F", "D,s,m", MATCH_FCVT_S_W, MASK_FCVT_S_W, match_opcode, 0 }, -{"fcvt.s.wu", "F", "D,s", MATCH_FCVT_S_WU | MASK_RM, MASK_FCVT_S_W | MASK_RM, match_opcode, 0 }, -{"fcvt.s.wu", "F", "D,s,m", MATCH_FCVT_S_WU, MASK_FCVT_S_WU, match_opcode, 0 }, -{"fclass.s", "F", "d,S", MATCH_FCLASS_S, MASK_FCLASS_S, match_opcode, 0 }, -{"feq.s", "F", "d,S,T", MATCH_FEQ_S, MASK_FEQ_S, match_opcode, 0 }, -{"flt.s", "F", "d,S,T", MATCH_FLT_S, MASK_FLT_S, match_opcode, 0 }, -{"fle.s", "F", "d,S,T", MATCH_FLE_S, MASK_FLE_S, match_opcode, 0 }, -{"fgt.s", "F", "d,T,S", MATCH_FLT_S, MASK_FLT_S, match_opcode, 0 }, -{"fge.s", "F", "d,T,S", MATCH_FLE_S, MASK_FLE_S, match_opcode, 0 }, -{"fcvt.l.s", "64F", "d,S", MATCH_FCVT_L_S | MASK_RM, MASK_FCVT_L_S | MASK_RM, match_opcode, 0 }, -{"fcvt.l.s", "64F", "d,S,m", MATCH_FCVT_L_S, MASK_FCVT_L_S, match_opcode, 0 }, -{"fcvt.lu.s", "64F", "d,S", MATCH_FCVT_LU_S | MASK_RM, MASK_FCVT_LU_S | MASK_RM, match_opcode, 0 }, -{"fcvt.lu.s", "64F", "d,S,m", MATCH_FCVT_LU_S, MASK_FCVT_LU_S, match_opcode, 0 }, -{"fcvt.s.l", "64F", "D,s", MATCH_FCVT_S_L | MASK_RM, MASK_FCVT_S_L | MASK_RM, match_opcode, 0 }, -{"fcvt.s.l", "64F", "D,s,m", MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 }, -{"fcvt.s.lu", "64F", "D,s", MATCH_FCVT_S_LU | MASK_RM, MASK_FCVT_S_L | MASK_RM, match_opcode, 0 }, -{"fcvt.s.lu", "64F", "D,s,m", MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 }, - -/* Double-precision floating-point instruction subset */ -{"fld", "C", "D,Cn(Cc)", MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS }, -{"fld", "C", "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_ALIAS }, -{"fld", "D", "D,o(s)", MATCH_FLD, MASK_FLD, match_opcode, 0 }, -{"fld", "D", "D,A,s", 0, (int) M_FLD, match_never, INSN_MACRO }, -{"fsd", "C", "CT,CN(Cc)", MATCH_C_FSDSP, MASK_C_FSDSP, match_opcode, INSN_ALIAS }, -{"fsd", "C", "CD,Cl(Cs)", MATCH_C_FSD, MASK_C_FSD, match_opcode, INSN_ALIAS }, -{"fsd", "D", "T,q(s)", MATCH_FSD, MASK_FSD, match_opcode, 0 }, -{"fsd", "D", "T,A,s", 0, (int) M_FSD, match_never, INSN_MACRO }, -{"fmv.d", "D", "D,U", MATCH_FSGNJ_D, MASK_FSGNJ_D, match_rs1_eq_rs2, INSN_ALIAS }, -{"fneg.d", "D", "D,U", MATCH_FSGNJN_D, MASK_FSGNJN_D, match_rs1_eq_rs2, INSN_ALIAS }, -{"fabs.d", "D", "D,U", MATCH_FSGNJX_D, MASK_FSGNJX_D, match_rs1_eq_rs2, INSN_ALIAS }, -{"fsgnj.d", "D", "D,S,T", MATCH_FSGNJ_D, MASK_FSGNJ_D, match_opcode, 0 }, -{"fsgnjn.d", "D", "D,S,T", MATCH_FSGNJN_D, MASK_FSGNJN_D, match_opcode, 0 }, -{"fsgnjx.d", "D", "D,S,T", MATCH_FSGNJX_D, MASK_FSGNJX_D, match_opcode, 0 }, -{"fadd.d", "D", "D,S,T", MATCH_FADD_D | MASK_RM, MASK_FADD_D | MASK_RM, match_opcode, 0 }, -{"fadd.d", "D", "D,S,T,m", MATCH_FADD_D, MASK_FADD_D, match_opcode, 0 }, -{"fsub.d", "D", "D,S,T", MATCH_FSUB_D | MASK_RM, MASK_FSUB_D | MASK_RM, match_opcode, 0 }, -{"fsub.d", "D", "D,S,T,m", MATCH_FSUB_D, MASK_FSUB_D, match_opcode, 0 }, -{"fmul.d", "D", "D,S,T", MATCH_FMUL_D | MASK_RM, MASK_FMUL_D | MASK_RM, match_opcode, 0 }, -{"fmul.d", "D", "D,S,T,m", MATCH_FMUL_D, MASK_FMUL_D, match_opcode, 0 }, -{"fdiv.d", "D", "D,S,T", MATCH_FDIV_D | MASK_RM, MASK_FDIV_D | MASK_RM, match_opcode, 0 }, -{"fdiv.d", "D", "D,S,T,m", MATCH_FDIV_D, MASK_FDIV_D, match_opcode, 0 }, -{"fsqrt.d", "D", "D,S", MATCH_FSQRT_D | MASK_RM, MASK_FSQRT_D | MASK_RM, match_opcode, 0 }, -{"fsqrt.d", "D", "D,S,m", MATCH_FSQRT_D, MASK_FSQRT_D, match_opcode, 0 }, -{"fmin.d", "D", "D,S,T", MATCH_FMIN_D, MASK_FMIN_D, match_opcode, 0 }, -{"fmax.d", "D", "D,S,T", MATCH_FMAX_D, MASK_FMAX_D, match_opcode, 0 }, -{"fmadd.d", "D", "D,S,T,R", MATCH_FMADD_D | MASK_RM, MASK_FMADD_D | MASK_RM, match_opcode, 0 }, -{"fmadd.d", "D", "D,S,T,R,m", MATCH_FMADD_D, MASK_FMADD_D, match_opcode, 0 }, -{"fnmadd.d", "D", "D,S,T,R", MATCH_FNMADD_D | MASK_RM, MASK_FNMADD_D | MASK_RM, match_opcode, 0 }, -{"fnmadd.d", "D", "D,S,T,R,m", MATCH_FNMADD_D, MASK_FNMADD_D, match_opcode, 0 }, -{"fmsub.d", "D", "D,S,T,R", MATCH_FMSUB_D | MASK_RM, MASK_FMSUB_D | MASK_RM, match_opcode, 0 }, -{"fmsub.d", "D", "D,S,T,R,m", MATCH_FMSUB_D, MASK_FMSUB_D, match_opcode, 0 }, -{"fnmsub.d", "D", "D,S,T,R", MATCH_FNMSUB_D | MASK_RM, MASK_FNMSUB_D | MASK_RM, match_opcode, 0 }, -{"fnmsub.d", "D", "D,S,T,R,m", MATCH_FNMSUB_D, MASK_FNMSUB_D, match_opcode, 0 }, -{"fcvt.w.d", "D", "d,S", MATCH_FCVT_W_D | MASK_RM, MASK_FCVT_W_D | MASK_RM, match_opcode, 0 }, -{"fcvt.w.d", "D", "d,S,m", MATCH_FCVT_W_D, MASK_FCVT_W_D, match_opcode, 0 }, -{"fcvt.wu.d", "D", "d,S", MATCH_FCVT_WU_D | MASK_RM, MASK_FCVT_WU_D | MASK_RM, match_opcode, 0 }, -{"fcvt.wu.d", "D", "d,S,m", MATCH_FCVT_WU_D, MASK_FCVT_WU_D, match_opcode, 0 }, -{"fcvt.d.w", "D", "D,s", MATCH_FCVT_D_W, MASK_FCVT_D_W | MASK_RM, match_opcode, 0 }, -{"fcvt.d.wu", "D", "D,s", MATCH_FCVT_D_WU, MASK_FCVT_D_WU | MASK_RM, match_opcode, 0 }, -{"fcvt.d.s", "D", "D,S", MATCH_FCVT_D_S, MASK_FCVT_D_S | MASK_RM, match_opcode, 0 }, -{"fcvt.s.d", "D", "D,S", MATCH_FCVT_S_D | MASK_RM, MASK_FCVT_S_D | MASK_RM, match_opcode, 0 }, -{"fcvt.s.d", "D", "D,S,m", MATCH_FCVT_S_D, MASK_FCVT_S_D, match_opcode, 0 }, -{"fclass.d", "D", "d,S", MATCH_FCLASS_D, MASK_FCLASS_D, match_opcode, 0 }, -{"feq.d", "D", "d,S,T", MATCH_FEQ_D, MASK_FEQ_D, match_opcode, 0 }, -{"flt.d", "D", "d,S,T", MATCH_FLT_D, MASK_FLT_D, match_opcode, 0 }, -{"fle.d", "D", "d,S,T", MATCH_FLE_D, MASK_FLE_D, match_opcode, 0 }, -{"fgt.d", "D", "d,T,S", MATCH_FLT_D, MASK_FLT_D, match_opcode, 0 }, -{"fge.d", "D", "d,T,S", MATCH_FLE_D, MASK_FLE_D, match_opcode, 0 }, -{"fmv.x.d", "64D", "d,S", MATCH_FMV_X_D, MASK_FMV_X_D, match_opcode, 0 }, -{"fmv.d.x", "64D", "D,s", MATCH_FMV_D_X, MASK_FMV_D_X, match_opcode, 0 }, -{"fcvt.l.d", "64D", "d,S", MATCH_FCVT_L_D | MASK_RM, MASK_FCVT_L_D | MASK_RM, match_opcode, 0 }, -{"fcvt.l.d", "64D", "d,S,m", MATCH_FCVT_L_D, MASK_FCVT_L_D, match_opcode, 0 }, -{"fcvt.lu.d", "64D", "d,S", MATCH_FCVT_LU_D | MASK_RM, MASK_FCVT_LU_D | MASK_RM, match_opcode, 0 }, -{"fcvt.lu.d", "64D", "d,S,m", MATCH_FCVT_LU_D, MASK_FCVT_LU_D, match_opcode, 0 }, -{"fcvt.d.l", "64D", "D,s", MATCH_FCVT_D_L | MASK_RM, MASK_FCVT_D_L | MASK_RM, match_opcode, 0 }, -{"fcvt.d.l", "64D", "D,s,m", MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 }, -{"fcvt.d.lu", "64D", "D,s", MATCH_FCVT_D_LU | MASK_RM, MASK_FCVT_D_L | MASK_RM, match_opcode, 0 }, -{"fcvt.d.lu", "64D", "D,s,m", MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 }, - -/* Quad-precision floating-point instruction subset */ -{"flq", "Q", "D,o(s)", MATCH_FLQ, MASK_FLQ, match_opcode, 0 }, -{"flq", "Q", "D,A,s", 0, (int) M_FLQ, match_never, INSN_MACRO }, -{"fsq", "Q", "T,q(s)", MATCH_FSQ, MASK_FSQ, match_opcode, 0 }, -{"fsq", "Q", "T,A,s", 0, (int) M_FSQ, match_never, INSN_MACRO }, -{"fmv.q", "Q", "D,U", MATCH_FSGNJ_Q, MASK_FSGNJ_Q, match_rs1_eq_rs2, INSN_ALIAS }, -{"fneg.q", "Q", "D,U", MATCH_FSGNJN_Q, MASK_FSGNJN_Q, match_rs1_eq_rs2, INSN_ALIAS }, -{"fabs.q", "Q", "D,U", MATCH_FSGNJX_Q, MASK_FSGNJX_Q, match_rs1_eq_rs2, INSN_ALIAS }, -{"fsgnj.q", "Q", "D,S,T", MATCH_FSGNJ_Q, MASK_FSGNJ_Q, match_opcode, 0 }, -{"fsgnjn.q", "Q", "D,S,T", MATCH_FSGNJN_Q, MASK_FSGNJN_Q, match_opcode, 0 }, -{"fsgnjx.q", "Q", "D,S,T", MATCH_FSGNJX_Q, MASK_FSGNJX_Q, match_opcode, 0 }, -{"fadd.q", "Q", "D,S,T", MATCH_FADD_Q | MASK_RM, MASK_FADD_Q | MASK_RM, match_opcode, 0 }, -{"fadd.q", "Q", "D,S,T,m", MATCH_FADD_Q, MASK_FADD_Q, match_opcode, 0 }, -{"fsub.q", "Q", "D,S,T", MATCH_FSUB_Q | MASK_RM, MASK_FSUB_Q | MASK_RM, match_opcode, 0 }, -{"fsub.q", "Q", "D,S,T,m", MATCH_FSUB_Q, MASK_FSUB_Q, match_opcode, 0 }, -{"fmul.q", "Q", "D,S,T", MATCH_FMUL_Q | MASK_RM, MASK_FMUL_Q | MASK_RM, match_opcode, 0 }, -{"fmul.q", "Q", "D,S,T,m", MATCH_FMUL_Q, MASK_FMUL_Q, match_opcode, 0 }, -{"fdiv.q", "Q", "D,S,T", MATCH_FDIV_Q | MASK_RM, MASK_FDIV_Q | MASK_RM, match_opcode, 0 }, -{"fdiv.q", "Q", "D,S,T,m", MATCH_FDIV_Q, MASK_FDIV_Q, match_opcode, 0 }, -{"fsqrt.q", "Q", "D,S", MATCH_FSQRT_Q | MASK_RM, MASK_FSQRT_Q | MASK_RM, match_opcode, 0 }, -{"fsqrt.q", "Q", "D,S,m", MATCH_FSQRT_Q, MASK_FSQRT_Q, match_opcode, 0 }, -{"fmin.q", "Q", "D,S,T", MATCH_FMIN_Q, MASK_FMIN_Q, match_opcode, 0 }, -{"fmax.q", "Q", "D,S,T", MATCH_FMAX_Q, MASK_FMAX_Q, match_opcode, 0 }, -{"fmadd.q", "Q", "D,S,T,R", MATCH_FMADD_Q | MASK_RM, MASK_FMADD_Q | MASK_RM, match_opcode, 0 }, -{"fmadd.q", "Q", "D,S,T,R,m", MATCH_FMADD_Q, MASK_FMADD_Q, match_opcode, 0 }, -{"fnmadd.q", "Q", "D,S,T,R", MATCH_FNMADD_Q | MASK_RM, MASK_FNMADD_Q | MASK_RM, match_opcode, 0 }, -{"fnmadd.q", "Q", "D,S,T,R,m", MATCH_FNMADD_Q, MASK_FNMADD_Q, match_opcode, 0 }, -{"fmsub.q", "Q", "D,S,T,R", MATCH_FMSUB_Q | MASK_RM, MASK_FMSUB_Q | MASK_RM, match_opcode, 0 }, -{"fmsub.q", "Q", "D,S,T,R,m", MATCH_FMSUB_Q, MASK_FMSUB_Q, match_opcode, 0 }, -{"fnmsub.q", "Q", "D,S,T,R", MATCH_FNMSUB_Q | MASK_RM, MASK_FNMSUB_Q | MASK_RM, match_opcode, 0 }, -{"fnmsub.q", "Q", "D,S,T,R,m", MATCH_FNMSUB_Q, MASK_FNMSUB_Q, match_opcode, 0 }, -{"fcvt.w.q", "Q", "d,S", MATCH_FCVT_W_Q | MASK_RM, MASK_FCVT_W_Q | MASK_RM, match_opcode, 0 }, -{"fcvt.w.q", "Q", "d,S,m", MATCH_FCVT_W_Q, MASK_FCVT_W_Q, match_opcode, 0 }, -{"fcvt.wu.q", "Q", "d,S", MATCH_FCVT_WU_Q | MASK_RM, MASK_FCVT_WU_Q | MASK_RM, match_opcode, 0 }, -{"fcvt.wu.q", "Q", "d,S,m", MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q, match_opcode, 0 }, -{"fcvt.q.w", "Q", "D,s", MATCH_FCVT_Q_W, MASK_FCVT_Q_W | MASK_RM, match_opcode, 0 }, -{"fcvt.q.wu", "Q", "D,s", MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU | MASK_RM, match_opcode, 0 }, -{"fcvt.q.s", "Q", "D,S", MATCH_FCVT_Q_S, MASK_FCVT_Q_S | MASK_RM, match_opcode, 0 }, -{"fcvt.q.d", "Q", "D,S", MATCH_FCVT_Q_D, MASK_FCVT_Q_D | MASK_RM, match_opcode, 0 }, -{"fcvt.s.q", "Q", "D,S", MATCH_FCVT_S_Q | MASK_RM, MASK_FCVT_S_Q | MASK_RM, match_opcode, 0 }, -{"fcvt.s.q", "Q", "D,S,m", MATCH_FCVT_S_Q, MASK_FCVT_S_Q, match_opcode, 0 }, -{"fcvt.d.q", "Q", "D,S", MATCH_FCVT_D_Q | MASK_RM, MASK_FCVT_D_Q | MASK_RM, match_opcode, 0 }, -{"fcvt.d.q", "Q", "D,S,m", MATCH_FCVT_D_Q, MASK_FCVT_D_Q, match_opcode, 0 }, -{"fclass.q", "Q", "d,S", MATCH_FCLASS_Q, MASK_FCLASS_Q, match_opcode, 0 }, -{"feq.q", "Q", "d,S,T", MATCH_FEQ_Q, MASK_FEQ_Q, match_opcode, 0 }, -{"flt.q", "Q", "d,S,T", MATCH_FLT_Q, MASK_FLT_Q, match_opcode, 0 }, -{"fle.q", "Q", "d,S,T", MATCH_FLE_Q, MASK_FLE_Q, match_opcode, 0 }, -{"fgt.q", "Q", "d,T,S", MATCH_FLT_Q, MASK_FLT_Q, match_opcode, 0 }, -{"fge.q", "Q", "d,T,S", MATCH_FLE_Q, MASK_FLE_Q, match_opcode, 0 }, -{"fmv.x.q", "64Q", "d,S", MATCH_FMV_X_Q, MASK_FMV_X_Q, match_opcode, 0 }, -{"fmv.q.x", "64Q", "D,s", MATCH_FMV_Q_X, MASK_FMV_Q_X, match_opcode, 0 }, -{"fcvt.l.q", "64Q", "d,S", MATCH_FCVT_L_Q | MASK_RM, MASK_FCVT_L_Q | MASK_RM, match_opcode, 0 }, -{"fcvt.l.q", "64Q", "d,S,m", MATCH_FCVT_L_Q, MASK_FCVT_L_Q, match_opcode, 0 }, -{"fcvt.lu.q", "64Q", "d,S", MATCH_FCVT_LU_Q | MASK_RM, MASK_FCVT_LU_Q | MASK_RM, match_opcode, 0 }, -{"fcvt.lu.q", "64Q", "d,S,m", MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q, match_opcode, 0 }, -{"fcvt.q.l", "64Q", "D,s", MATCH_FCVT_Q_L | MASK_RM, MASK_FCVT_Q_L | MASK_RM, match_opcode, 0 }, -{"fcvt.q.l", "64Q", "D,s,m", MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 }, -{"fcvt.q.lu", "64Q", "D,s", MATCH_FCVT_Q_LU | MASK_RM, MASK_FCVT_Q_L | MASK_RM, match_opcode, 0 }, -{"fcvt.q.lu", "64Q", "D,s,m", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 }, - -/* Compressed instructions. */ -{"c.ebreak", "C", "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, 0 }, -{"c.jr", "C", "d", MATCH_C_JR, MASK_C_JR, match_rd_nonzero, 0 }, -{"c.jalr", "C", "d", MATCH_C_JALR, MASK_C_JALR, match_rd_nonzero, 0 }, -{"c.j", "C", "Ca", MATCH_C_J, MASK_C_J, match_opcode, 0 }, -{"c.jal", "32C", "Ca", MATCH_C_JAL, MASK_C_JAL, match_opcode, 0 }, -{"c.beqz", "C", "Cs,Cp", MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, 0 }, -{"c.bnez", "C", "Cs,Cp", MATCH_C_BNEZ, MASK_C_BNEZ, match_opcode, 0 }, -{"c.lwsp", "C", "d,Cm(Cc)", MATCH_C_LWSP, MASK_C_LWSP, match_rd_nonzero, 0 }, -{"c.lw", "C", "Ct,Ck(Cs)", MATCH_C_LW, MASK_C_LW, match_opcode, 0 }, -{"c.swsp", "C", "CV,CM(Cc)", MATCH_C_SWSP, MASK_C_SWSP, match_opcode, 0 }, -{"c.sw", "C", "Ct,Ck(Cs)", MATCH_C_SW, MASK_C_SW, match_opcode, 0 }, -{"c.nop", "C", "", MATCH_C_ADDI, 0xffff, match_opcode, 0 }, -{"c.mv", "C", "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, 0 }, -{"c.lui", "C", "d,Cu", MATCH_C_LUI, MASK_C_LUI, match_c_lui, 0 }, -{"c.li", "C", "d,Cj", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, 0 }, -{"c.addi4spn","C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_opcode, 0 }, -{"c.addi16sp","C", "Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_opcode, 0 }, -{"c.addi", "C", "d,Cj,CU", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, 0 }, -{"c.add", "C", "d,CV,CU", MATCH_C_ADD, MASK_C_ADD, match_c_add, 0 }, -{"c.sub", "C", "Cs,Cs,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, 0 }, -{"c.and", "C", "Cs,Cs,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, 0 }, -{"c.or", "C", "Cs,Cs,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, 0 }, -{"c.xor", "C", "Cs,Cs,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, 0 }, -{"c.slli", "C", "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, 0 }, -{"c.srli", "C", "Cs,Cs,C>", MATCH_C_SRLI, MASK_C_SRLI, match_opcode, 0 }, -{"c.srai", "C", "Cs,Cs,C>", MATCH_C_SRAI, MASK_C_SRAI, match_opcode, 0 }, -{"c.andi", "C", "Cs,Cj,Cs", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, 0 }, -{"c.addiw", "64C", "d,Cj,CU", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, 0 }, -{"c.addw", "64C", "Cs,Ct,Cs", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, 0 }, -{"c.subw", "64C", "Cs,Cs,Ct", MATCH_C_SUBW, MASK_C_SUBW, match_opcode, 0 }, -{"c.ldsp", "64C", "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, 0 }, -{"c.ld", "64C", "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, 0 }, -{"c.sdsp", "64C", "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, 0 }, -{"c.sd", "64C", "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, 0 }, -{"c.fldsp", "C", "D,Cn(Cc)", MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, 0 }, -{"c.fld", "C", "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, 0 }, -{"c.fsdsp", "C", "CT,CN(Cc)", MATCH_C_FSDSP, MASK_C_FSDSP, match_opcode, 0 }, -{"c.fsd", "C", "CD,Cl(Cs)", MATCH_C_FSD, MASK_C_FSD, match_opcode, 0 }, -{"c.flwsp", "32C", "D,Cm(Cc)", MATCH_C_FLWSP, MASK_C_FLWSP, match_opcode, 0 }, -{"c.flw", "32C", "CD,Ck(Cs)", MATCH_C_FLW, MASK_C_FLW, match_opcode, 0 }, -{"c.fswsp", "32C", "CT,CM(Cc)", MATCH_C_FSWSP, MASK_C_FSWSP, match_opcode, 0 }, -{"c.fsw", "32C", "CD,Ck(Cs)", MATCH_C_FSW, MASK_C_FSW, match_opcode, 0 }, - -/* Supervisor instructions */ -{"csrr", "I", "d,E", MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, INSN_ALIAS }, -{"csrwi", "I", "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS }, -{"csrsi", "I", "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS }, -{"csrci", "I", "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS }, -{"csrw", "I", "E,s", MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, INSN_ALIAS }, -{"csrw", "I", "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS }, -{"csrs", "I", "E,s", MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, INSN_ALIAS }, -{"csrs", "I", "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS }, -{"csrc", "I", "E,s", MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, INSN_ALIAS }, -{"csrc", "I", "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS }, -{"csrrwi", "I", "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, 0 }, -{"csrrsi", "I", "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, 0 }, -{"csrrci", "I", "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, 0 }, -{"csrrw", "I", "d,E,s", MATCH_CSRRW, MASK_CSRRW, match_opcode, 0 }, -{"csrrw", "I", "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, INSN_ALIAS }, -{"csrrs", "I", "d,E,s", MATCH_CSRRS, MASK_CSRRS, match_opcode, 0 }, -{"csrrs", "I", "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, INSN_ALIAS }, -{"csrrc", "I", "d,E,s", MATCH_CSRRC, MASK_CSRRC, match_opcode, 0 }, -{"csrrc", "I", "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, INSN_ALIAS }, -{"uret", "I", "", MATCH_URET, MASK_URET, match_opcode, 0 }, -{"sret", "I", "", MATCH_SRET, MASK_SRET, match_opcode, 0 }, -{"hret", "I", "", MATCH_HRET, MASK_HRET, match_opcode, 0 }, -{"mret", "I", "", MATCH_MRET, MASK_MRET, match_opcode, 0 }, -{"dret", "I", "", MATCH_DRET, MASK_DRET, match_opcode, 0 }, -{"sfence.vm", "I", "", MATCH_SFENCE_VM, MASK_SFENCE_VM | MASK_RS1, match_opcode, 0 }, -{"sfence.vm", "I", "s", MATCH_SFENCE_VM, MASK_SFENCE_VM, match_opcode, 0 }, -{"wfi", "I", "", MATCH_WFI, MASK_WFI, match_opcode, 0 }, -}; - -#define RISCV_NUM_OPCODES \ - ((sizeof riscv_builtin_opcodes) / (sizeof (riscv_builtin_opcodes[0]))) -//const int bfd_riscv_num_builtin_opcodes = RISCV_NUM_OPCODES; - -/* Removed const from the following to allow for dynamic extensions to the - built-in instruction set. */ -static struct riscv_opcode *riscv_opcodes = - (struct riscv_opcode *) riscv_builtin_opcodes; -static int bfd_riscv_num_opcodes = RISCV_NUM_OPCODES; -#undef RISCV_NUM_OPCODES diff --git a/librz/arch/isa_gnu/riscv/riscv-opc.h b/librz/arch/isa_gnu/riscv/riscv-opc.h deleted file mode 100644 index af333e46980..00000000000 --- a/librz/arch/isa_gnu/riscv/riscv-opc.h +++ /dev/null @@ -1,1266 +0,0 @@ -// SPDX-FileCopyrightText: 2011-2015 Free Software Foundation, Inc. -// SPDX-License-Identifier: GPL-3.0-or-later - -/* Automatically generated by parse-opcodes. */ -#ifndef RISCV_ENCODING_H -#define RISCV_ENCODING_H -#define MATCH_SLLI_RV32 0x1013 -#define MASK_SLLI_RV32 0xfe00707f -#define MATCH_SRLI_RV32 0x5013 -#define MASK_SRLI_RV32 0xfe00707f -#define MATCH_SRAI_RV32 0x40005013 -#define MASK_SRAI_RV32 0xfe00707f -#define MATCH_FRFLAGS 0x102073 -#define MASK_FRFLAGS 0xfffff07f -#define MATCH_FSFLAGS 0x101073 -#define MASK_FSFLAGS 0xfff0707f -#define MATCH_FSFLAGSI 0x105073 -#define MASK_FSFLAGSI 0xfff0707f -#define MATCH_FRRM 0x202073 -#define MASK_FRRM 0xfffff07f -#define MATCH_FSRM 0x201073 -#define MASK_FSRM 0xfff0707f -#define MATCH_FSRMI 0x205073 -#define MASK_FSRMI 0xfff0707f -#define MATCH_FSCSR 0x301073 -#define MASK_FSCSR 0xfff0707f -#define MATCH_FRCSR 0x302073 -#define MASK_FRCSR 0xfffff07f -#define MATCH_RDCYCLE 0xc0002073 -#define MASK_RDCYCLE 0xfffff07f -#define MATCH_RDTIME 0xc0102073 -#define MASK_RDTIME 0xfffff07f -#define MATCH_RDINSTRET 0xc0202073 -#define MASK_RDINSTRET 0xfffff07f -#define MATCH_RDCYCLEH 0xc8002073 -#define MASK_RDCYCLEH 0xfffff07f -#define MATCH_RDTIMEH 0xc8102073 -#define MASK_RDTIMEH 0xfffff07f -#define MATCH_RDINSTRETH 0xc8202073 -#define MASK_RDINSTRETH 0xfffff07f -#define MATCH_SCALL 0x73 -#define MASK_SCALL 0xffffffff -#define MATCH_SBREAK 0x100073 -#define MASK_SBREAK 0xffffffff -#define MATCH_BEQ 0x63 -#define MASK_BEQ 0x707f -#define MATCH_BNE 0x1063 -#define MASK_BNE 0x707f -#define MATCH_BLT 0x4063 -#define MASK_BLT 0x707f -#define MATCH_BGE 0x5063 -#define MASK_BGE 0x707f -#define MATCH_BLTU 0x6063 -#define MASK_BLTU 0x707f -#define MATCH_BGEU 0x7063 -#define MASK_BGEU 0x707f -#define MATCH_JALR 0x67 -#define MASK_JALR 0x707f -#define MATCH_JAL 0x6f -#define MASK_JAL 0x7f -#define MATCH_LUI 0x37 -#define MASK_LUI 0x7f -#define MATCH_AUIPC 0x17 -#define MASK_AUIPC 0x7f -#define MATCH_ADDI 0x13 -#define MASK_ADDI 0x707f -#define MATCH_SLLI 0x1013 -#define MASK_SLLI 0xfc00707f -#define MATCH_SLTI 0x2013 -#define MASK_SLTI 0x707f -#define MATCH_SLTIU 0x3013 -#define MASK_SLTIU 0x707f -#define MATCH_XORI 0x4013 -#define MASK_XORI 0x707f -#define MATCH_SRLI 0x5013 -#define MASK_SRLI 0xfc00707f -#define MATCH_SRAI 0x40005013 -#define MASK_SRAI 0xfc00707f -#define MATCH_ORI 0x6013 -#define MASK_ORI 0x707f -#define MATCH_ANDI 0x7013 -#define MASK_ANDI 0x707f -#define MATCH_ADD 0x33 -#define MASK_ADD 0xfe00707f -#define MATCH_SUB 0x40000033 -#define MASK_SUB 0xfe00707f -#define MATCH_SLL 0x1033 -#define MASK_SLL 0xfe00707f -#define MATCH_SLT 0x2033 -#define MASK_SLT 0xfe00707f -#define MATCH_SLTU 0x3033 -#define MASK_SLTU 0xfe00707f -#define MATCH_XOR 0x4033 -#define MASK_XOR 0xfe00707f -#define MATCH_SRL 0x5033 -#define MASK_SRL 0xfe00707f -#define MATCH_SRA 0x40005033 -#define MASK_SRA 0xfe00707f -#define MATCH_OR 0x6033 -#define MASK_OR 0xfe00707f -#define MATCH_AND 0x7033 -#define MASK_AND 0xfe00707f -#define MATCH_ADDIW 0x1b -#define MASK_ADDIW 0x707f -#define MATCH_SLLIW 0x101b -#define MASK_SLLIW 0xfe00707f -#define MATCH_SRLIW 0x501b -#define MASK_SRLIW 0xfe00707f -#define MATCH_SRAIW 0x4000501b -#define MASK_SRAIW 0xfe00707f -#define MATCH_ADDW 0x3b -#define MASK_ADDW 0xfe00707f -#define MATCH_SUBW 0x4000003b -#define MASK_SUBW 0xfe00707f -#define MATCH_SLLW 0x103b -#define MASK_SLLW 0xfe00707f -#define MATCH_SRLW 0x503b -#define MASK_SRLW 0xfe00707f -#define MATCH_SRAW 0x4000503b -#define MASK_SRAW 0xfe00707f -#define MATCH_LB 0x3 -#define MASK_LB 0x707f -#define MATCH_LH 0x1003 -#define MASK_LH 0x707f -#define MATCH_LW 0x2003 -#define MASK_LW 0x707f -#define MATCH_LD 0x3003 -#define MASK_LD 0x707f -#define MATCH_LBU 0x4003 -#define MASK_LBU 0x707f -#define MATCH_LHU 0x5003 -#define MASK_LHU 0x707f -#define MATCH_LWU 0x6003 -#define MASK_LWU 0x707f -#define MATCH_SB 0x23 -#define MASK_SB 0x707f -#define MATCH_SH 0x1023 -#define MASK_SH 0x707f -#define MATCH_SW 0x2023 -#define MASK_SW 0x707f -#define MATCH_SD 0x3023 -#define MASK_SD 0x707f -#define MATCH_FENCE 0xf -#define MASK_FENCE 0x707f -#define MATCH_FENCE_I 0x100f -#define MASK_FENCE_I 0x707f -#define MATCH_MUL 0x2000033 -#define MASK_MUL 0xfe00707f -#define MATCH_MULH 0x2001033 -#define MASK_MULH 0xfe00707f -#define MATCH_MULHSU 0x2002033 -#define MASK_MULHSU 0xfe00707f -#define MATCH_MULHU 0x2003033 -#define MASK_MULHU 0xfe00707f -#define MATCH_DIV 0x2004033 -#define MASK_DIV 0xfe00707f -#define MATCH_DIVU 0x2005033 -#define MASK_DIVU 0xfe00707f -#define MATCH_REM 0x2006033 -#define MASK_REM 0xfe00707f -#define MATCH_REMU 0x2007033 -#define MASK_REMU 0xfe00707f -#define MATCH_MULW 0x200003b -#define MASK_MULW 0xfe00707f -#define MATCH_DIVW 0x200403b -#define MASK_DIVW 0xfe00707f -#define MATCH_DIVUW 0x200503b -#define MASK_DIVUW 0xfe00707f -#define MATCH_REMW 0x200603b -#define MASK_REMW 0xfe00707f -#define MATCH_REMUW 0x200703b -#define MASK_REMUW 0xfe00707f -#define MATCH_AMOADD_W 0x202f -#define MASK_AMOADD_W 0xf800707f -#define MATCH_AMOXOR_W 0x2000202f -#define MASK_AMOXOR_W 0xf800707f -#define MATCH_AMOOR_W 0x4000202f -#define MASK_AMOOR_W 0xf800707f -#define MATCH_AMOAND_W 0x6000202f -#define MASK_AMOAND_W 0xf800707f -#define MATCH_AMOMIN_W 0x8000202f -#define MASK_AMOMIN_W 0xf800707f -#define MATCH_AMOMAX_W 0xa000202f -#define MASK_AMOMAX_W 0xf800707f -#define MATCH_AMOMINU_W 0xc000202f -#define MASK_AMOMINU_W 0xf800707f -#define MATCH_AMOMAXU_W 0xe000202f -#define MASK_AMOMAXU_W 0xf800707f -#define MATCH_AMOSWAP_W 0x800202f -#define MASK_AMOSWAP_W 0xf800707f -#define MATCH_LR_W 0x1000202f -#define MASK_LR_W 0xf9f0707f -#define MATCH_SC_W 0x1800202f -#define MASK_SC_W 0xf800707f -#define MATCH_AMOADD_D 0x302f -#define MASK_AMOADD_D 0xf800707f -#define MATCH_AMOXOR_D 0x2000302f -#define MASK_AMOXOR_D 0xf800707f -#define MATCH_AMOOR_D 0x4000302f -#define MASK_AMOOR_D 0xf800707f -#define MATCH_AMOAND_D 0x6000302f -#define MASK_AMOAND_D 0xf800707f -#define MATCH_AMOMIN_D 0x8000302f -#define MASK_AMOMIN_D 0xf800707f -#define MATCH_AMOMAX_D 0xa000302f -#define MASK_AMOMAX_D 0xf800707f -#define MATCH_AMOMINU_D 0xc000302f -#define MASK_AMOMINU_D 0xf800707f -#define MATCH_AMOMAXU_D 0xe000302f -#define MASK_AMOMAXU_D 0xf800707f -#define MATCH_AMOSWAP_D 0x800302f -#define MASK_AMOSWAP_D 0xf800707f -#define MATCH_LR_D 0x1000302f -#define MASK_LR_D 0xf9f0707f -#define MATCH_SC_D 0x1800302f -#define MASK_SC_D 0xf800707f -#define MATCH_ECALL 0x73 -#define MASK_ECALL 0xffffffff -#define MATCH_EBREAK 0x100073 -#define MASK_EBREAK 0xffffffff -#define MATCH_URET 0x200073 -#define MASK_URET 0xffffffff -#define MATCH_SRET 0x10200073 -#define MASK_SRET 0xffffffff -#define MATCH_HRET 0x20200073 -#define MASK_HRET 0xffffffff -#define MATCH_MRET 0x30200073 -#define MASK_MRET 0xffffffff -#define MATCH_DRET 0x7b200073 -#define MASK_DRET 0xffffffff -#define MATCH_SFENCE_VM 0x10400073 -#define MASK_SFENCE_VM 0xfff07fff -#define MATCH_WFI 0x10500073 -#define MASK_WFI 0xffffffff -#define MATCH_CSRRW 0x1073 -#define MASK_CSRRW 0x707f -#define MATCH_CSRRS 0x2073 -#define MASK_CSRRS 0x707f -#define MATCH_CSRRC 0x3073 -#define MASK_CSRRC 0x707f -#define MATCH_CSRRWI 0x5073 -#define MASK_CSRRWI 0x707f -#define MATCH_CSRRSI 0x6073 -#define MASK_CSRRSI 0x707f -#define MATCH_CSRRCI 0x7073 -#define MASK_CSRRCI 0x707f -#define MATCH_FADD_S 0x53 -#define MASK_FADD_S 0xfe00007f -#define MATCH_FSUB_S 0x8000053 -#define MASK_FSUB_S 0xfe00007f -#define MATCH_FMUL_S 0x10000053 -#define MASK_FMUL_S 0xfe00007f -#define MATCH_FDIV_S 0x18000053 -#define MASK_FDIV_S 0xfe00007f -#define MATCH_FSGNJ_S 0x20000053 -#define MASK_FSGNJ_S 0xfe00707f -#define MATCH_FSGNJN_S 0x20001053 -#define MASK_FSGNJN_S 0xfe00707f -#define MATCH_FSGNJX_S 0x20002053 -#define MASK_FSGNJX_S 0xfe00707f -#define MATCH_FMIN_S 0x28000053 -#define MASK_FMIN_S 0xfe00707f -#define MATCH_FMAX_S 0x28001053 -#define MASK_FMAX_S 0xfe00707f -#define MATCH_FSQRT_S 0x58000053 -#define MASK_FSQRT_S 0xfff0007f -#define MATCH_FADD_D 0x2000053 -#define MASK_FADD_D 0xfe00007f -#define MATCH_FSUB_D 0xa000053 -#define MASK_FSUB_D 0xfe00007f -#define MATCH_FMUL_D 0x12000053 -#define MASK_FMUL_D 0xfe00007f -#define MATCH_FDIV_D 0x1a000053 -#define MASK_FDIV_D 0xfe00007f -#define MATCH_FSGNJ_D 0x22000053 -#define MASK_FSGNJ_D 0xfe00707f -#define MATCH_FSGNJN_D 0x22001053 -#define MASK_FSGNJN_D 0xfe00707f -#define MATCH_FSGNJX_D 0x22002053 -#define MASK_FSGNJX_D 0xfe00707f -#define MATCH_FMIN_D 0x2a000053 -#define MASK_FMIN_D 0xfe00707f -#define MATCH_FMAX_D 0x2a001053 -#define MASK_FMAX_D 0xfe00707f -#define MATCH_FCVT_S_D 0x40100053 -#define MASK_FCVT_S_D 0xfff0007f -#define MATCH_FCVT_D_S 0x42000053 -#define MASK_FCVT_D_S 0xfff0007f -#define MATCH_FSQRT_D 0x5a000053 -#define MASK_FSQRT_D 0xfff0007f -#define MATCH_FADD_Q 0x6000053 -#define MASK_FADD_Q 0xfe00007f -#define MATCH_FSUB_Q 0xe000053 -#define MASK_FSUB_Q 0xfe00007f -#define MATCH_FMUL_Q 0x16000053 -#define MASK_FMUL_Q 0xfe00007f -#define MATCH_FDIV_Q 0x1e000053 -#define MASK_FDIV_Q 0xfe00007f -#define MATCH_FSGNJ_Q 0x26000053 -#define MASK_FSGNJ_Q 0xfe00707f -#define MATCH_FSGNJN_Q 0x26001053 -#define MASK_FSGNJN_Q 0xfe00707f -#define MATCH_FSGNJX_Q 0x26002053 -#define MASK_FSGNJX_Q 0xfe00707f -#define MATCH_FMIN_Q 0x2e000053 -#define MASK_FMIN_Q 0xfe00707f -#define MATCH_FMAX_Q 0x2e001053 -#define MASK_FMAX_Q 0xfe00707f -#define MATCH_FCVT_S_Q 0x40300053 -#define MASK_FCVT_S_Q 0xfff0007f -#define MATCH_FCVT_Q_S 0x46000053 -#define MASK_FCVT_Q_S 0xfff0007f -#define MATCH_FCVT_D_Q 0x42300053 -#define MASK_FCVT_D_Q 0xfff0007f -#define MATCH_FCVT_Q_D 0x46100053 -#define MASK_FCVT_Q_D 0xfff0007f -#define MATCH_FSQRT_Q 0x5e000053 -#define MASK_FSQRT_Q 0xfff0007f -#define MATCH_FLE_S 0xa0000053 -#define MASK_FLE_S 0xfe00707f -#define MATCH_FLT_S 0xa0001053 -#define MASK_FLT_S 0xfe00707f -#define MATCH_FEQ_S 0xa0002053 -#define MASK_FEQ_S 0xfe00707f -#define MATCH_FLE_D 0xa2000053 -#define MASK_FLE_D 0xfe00707f -#define MATCH_FLT_D 0xa2001053 -#define MASK_FLT_D 0xfe00707f -#define MATCH_FEQ_D 0xa2002053 -#define MASK_FEQ_D 0xfe00707f -#define MATCH_FLE_Q 0xa6000053 -#define MASK_FLE_Q 0xfe00707f -#define MATCH_FLT_Q 0xa6001053 -#define MASK_FLT_Q 0xfe00707f -#define MATCH_FEQ_Q 0xa6002053 -#define MASK_FEQ_Q 0xfe00707f -#define MATCH_FCVT_W_S 0xc0000053 -#define MASK_FCVT_W_S 0xfff0007f -#define MATCH_FCVT_WU_S 0xc0100053 -#define MASK_FCVT_WU_S 0xfff0007f -#define MATCH_FCVT_L_S 0xc0200053 -#define MASK_FCVT_L_S 0xfff0007f -#define MATCH_FCVT_LU_S 0xc0300053 -#define MASK_FCVT_LU_S 0xfff0007f -#define MATCH_FMV_X_S 0xe0000053 -#define MASK_FMV_X_S 0xfff0707f -#define MATCH_FCLASS_S 0xe0001053 -#define MASK_FCLASS_S 0xfff0707f -#define MATCH_FCVT_W_D 0xc2000053 -#define MASK_FCVT_W_D 0xfff0007f -#define MATCH_FCVT_WU_D 0xc2100053 -#define MASK_FCVT_WU_D 0xfff0007f -#define MATCH_FCVT_L_D 0xc2200053 -#define MASK_FCVT_L_D 0xfff0007f -#define MATCH_FCVT_LU_D 0xc2300053 -#define MASK_FCVT_LU_D 0xfff0007f -#define MATCH_FMV_X_D 0xe2000053 -#define MASK_FMV_X_D 0xfff0707f -#define MATCH_FCLASS_D 0xe2001053 -#define MASK_FCLASS_D 0xfff0707f -#define MATCH_FCVT_W_Q 0xc6000053 -#define MASK_FCVT_W_Q 0xfff0007f -#define MATCH_FCVT_WU_Q 0xc6100053 -#define MASK_FCVT_WU_Q 0xfff0007f -#define MATCH_FCVT_L_Q 0xc6200053 -#define MASK_FCVT_L_Q 0xfff0007f -#define MATCH_FCVT_LU_Q 0xc6300053 -#define MASK_FCVT_LU_Q 0xfff0007f -#define MATCH_FMV_X_Q 0xe6000053 -#define MASK_FMV_X_Q 0xfff0707f -#define MATCH_FCLASS_Q 0xe6001053 -#define MASK_FCLASS_Q 0xfff0707f -#define MATCH_FCVT_S_W 0xd0000053 -#define MASK_FCVT_S_W 0xfff0007f -#define MATCH_FCVT_S_WU 0xd0100053 -#define MASK_FCVT_S_WU 0xfff0007f -#define MATCH_FCVT_S_L 0xd0200053 -#define MASK_FCVT_S_L 0xfff0007f -#define MATCH_FCVT_S_LU 0xd0300053 -#define MASK_FCVT_S_LU 0xfff0007f -#define MATCH_FMV_S_X 0xf0000053 -#define MASK_FMV_S_X 0xfff0707f -#define MATCH_FCVT_D_W 0xd2000053 -#define MASK_FCVT_D_W 0xfff0007f -#define MATCH_FCVT_D_WU 0xd2100053 -#define MASK_FCVT_D_WU 0xfff0007f -#define MATCH_FCVT_D_L 0xd2200053 -#define MASK_FCVT_D_L 0xfff0007f -#define MATCH_FCVT_D_LU 0xd2300053 -#define MASK_FCVT_D_LU 0xfff0007f -#define MATCH_FMV_D_X 0xf2000053 -#define MASK_FMV_D_X 0xfff0707f -#define MATCH_FCVT_Q_W 0xd6000053 -#define MASK_FCVT_Q_W 0xfff0007f -#define MATCH_FCVT_Q_WU 0xd6100053 -#define MASK_FCVT_Q_WU 0xfff0007f -#define MATCH_FCVT_Q_L 0xd6200053 -#define MASK_FCVT_Q_L 0xfff0007f -#define MATCH_FCVT_Q_LU 0xd6300053 -#define MASK_FCVT_Q_LU 0xfff0007f -#define MATCH_FMV_Q_X 0xf6000053 -#define MASK_FMV_Q_X 0xfff0707f -#define MATCH_FLW 0x2007 -#define MASK_FLW 0x707f -#define MATCH_FLD 0x3007 -#define MASK_FLD 0x707f -#define MATCH_FLQ 0x4007 -#define MASK_FLQ 0x707f -#define MATCH_FSW 0x2027 -#define MASK_FSW 0x707f -#define MATCH_FSD 0x3027 -#define MASK_FSD 0x707f -#define MATCH_FSQ 0x4027 -#define MASK_FSQ 0x707f -#define MATCH_FMADD_S 0x43 -#define MASK_FMADD_S 0x600007f -#define MATCH_FMSUB_S 0x47 -#define MASK_FMSUB_S 0x600007f -#define MATCH_FNMSUB_S 0x4b -#define MASK_FNMSUB_S 0x600007f -#define MATCH_FNMADD_S 0x4f -#define MASK_FNMADD_S 0x600007f -#define MATCH_FMADD_D 0x2000043 -#define MASK_FMADD_D 0x600007f -#define MATCH_FMSUB_D 0x2000047 -#define MASK_FMSUB_D 0x600007f -#define MATCH_FNMSUB_D 0x200004b -#define MASK_FNMSUB_D 0x600007f -#define MATCH_FNMADD_D 0x200004f -#define MASK_FNMADD_D 0x600007f -#define MATCH_FMADD_Q 0x6000043 -#define MASK_FMADD_Q 0x600007f -#define MATCH_FMSUB_Q 0x6000047 -#define MASK_FMSUB_Q 0x600007f -#define MATCH_FNMSUB_Q 0x600004b -#define MASK_FNMSUB_Q 0x600007f -#define MATCH_FNMADD_Q 0x600004f -#define MASK_FNMADD_Q 0x600007f -#define MATCH_C_ADDI4SPN 0x0 -#define MASK_C_ADDI4SPN 0xe003 -#define MATCH_C_FLD 0x2000 -#define MASK_C_FLD 0xe003 -#define MATCH_C_LW 0x4000 -#define MASK_C_LW 0xe003 -#define MATCH_C_FLW 0x6000 -#define MASK_C_FLW 0xe003 -#define MATCH_C_FSD 0xa000 -#define MASK_C_FSD 0xe003 -#define MATCH_C_SW 0xc000 -#define MASK_C_SW 0xe003 -#define MATCH_C_FSW 0xe000 -#define MASK_C_FSW 0xe003 -#define MATCH_C_ADDI 0x1 -#define MASK_C_ADDI 0xe003 -#define MATCH_C_JAL 0x2001 -#define MASK_C_JAL 0xe003 -#define MATCH_C_LI 0x4001 -#define MASK_C_LI 0xe003 -#define MATCH_C_LUI 0x6001 -#define MASK_C_LUI 0xe003 -#define MATCH_C_SRLI 0x8001 -#define MASK_C_SRLI 0xec03 -#define MATCH_C_SRAI 0x8401 -#define MASK_C_SRAI 0xec03 -#define MATCH_C_ANDI 0x8801 -#define MASK_C_ANDI 0xec03 -#define MATCH_C_SUB 0x8c01 -#define MASK_C_SUB 0xfc63 -#define MATCH_C_XOR 0x8c21 -#define MASK_C_XOR 0xfc63 -#define MATCH_C_OR 0x8c41 -#define MASK_C_OR 0xfc63 -#define MATCH_C_AND 0x8c61 -#define MASK_C_AND 0xfc63 -#define MATCH_C_SUBW 0x9c01 -#define MASK_C_SUBW 0xfc63 -#define MATCH_C_ADDW 0x9c21 -#define MASK_C_ADDW 0xfc63 -#define MATCH_C_J 0xa001 -#define MASK_C_J 0xe003 -#define MATCH_C_BEQZ 0xc001 -#define MASK_C_BEQZ 0xe003 -#define MATCH_C_BNEZ 0xe001 -#define MASK_C_BNEZ 0xe003 -#define MATCH_C_SLLI 0x2 -#define MASK_C_SLLI 0xe003 -#define MATCH_C_FLDSP 0x2002 -#define MASK_C_FLDSP 0xe003 -#define MATCH_C_LWSP 0x4002 -#define MASK_C_LWSP 0xe003 -#define MATCH_C_FLWSP 0x6002 -#define MASK_C_FLWSP 0xe003 -#define MATCH_C_MV 0x8002 -#define MASK_C_MV 0xf003 -#define MATCH_C_ADD 0x9002 -#define MASK_C_ADD 0xf003 -#define MATCH_C_FSDSP 0xa002 -#define MASK_C_FSDSP 0xe003 -#define MATCH_C_SWSP 0xc002 -#define MASK_C_SWSP 0xe003 -#define MATCH_C_FSWSP 0xe002 -#define MASK_C_FSWSP 0xe003 -#define MATCH_C_NOP 0x1 -#define MASK_C_NOP 0xffff -#define MATCH_C_ADDI16SP 0x6101 -#define MASK_C_ADDI16SP 0xef83 -#define MATCH_C_JR 0x8002 -#define MASK_C_JR 0xf07f -#define MATCH_C_JALR 0x9002 -#define MASK_C_JALR 0xf07f -#define MATCH_C_EBREAK 0x9002 -#define MASK_C_EBREAK 0xffff -#define MATCH_C_LD 0x6000 -#define MASK_C_LD 0xe003 -#define MATCH_C_SD 0xe000 -#define MASK_C_SD 0xe003 -#define MATCH_C_ADDIW 0x2001 -#define MASK_C_ADDIW 0xe003 -#define MATCH_C_LDSP 0x6002 -#define MASK_C_LDSP 0xe003 -#define MATCH_C_SDSP 0xe002 -#define MASK_C_SDSP 0xe003 -#define MATCH_CUSTOM0 0xb -#define MASK_CUSTOM0 0x707f -#define MATCH_CUSTOM0_RS1 0x200b -#define MASK_CUSTOM0_RS1 0x707f -#define MATCH_CUSTOM0_RS1_RS2 0x300b -#define MASK_CUSTOM0_RS1_RS2 0x707f -#define MATCH_CUSTOM0_RD 0x400b -#define MASK_CUSTOM0_RD 0x707f -#define MATCH_CUSTOM0_RD_RS1 0x600b -#define MASK_CUSTOM0_RD_RS1 0x707f -#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b -#define MASK_CUSTOM0_RD_RS1_RS2 0x707f -#define MATCH_CUSTOM1 0x2b -#define MASK_CUSTOM1 0x707f -#define MATCH_CUSTOM1_RS1 0x202b -#define MASK_CUSTOM1_RS1 0x707f -#define MATCH_CUSTOM1_RS1_RS2 0x302b -#define MASK_CUSTOM1_RS1_RS2 0x707f -#define MATCH_CUSTOM1_RD 0x402b -#define MASK_CUSTOM1_RD 0x707f -#define MATCH_CUSTOM1_RD_RS1 0x602b -#define MASK_CUSTOM1_RD_RS1 0x707f -#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b -#define MASK_CUSTOM1_RD_RS1_RS2 0x707f -#define MATCH_CUSTOM2 0x5b -#define MASK_CUSTOM2 0x707f -#define MATCH_CUSTOM2_RS1 0x205b -#define MASK_CUSTOM2_RS1 0x707f -#define MATCH_CUSTOM2_RS1_RS2 0x305b -#define MASK_CUSTOM2_RS1_RS2 0x707f -#define MATCH_CUSTOM2_RD 0x405b -#define MASK_CUSTOM2_RD 0x707f -#define MATCH_CUSTOM2_RD_RS1 0x605b -#define MASK_CUSTOM2_RD_RS1 0x707f -#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b -#define MASK_CUSTOM2_RD_RS1_RS2 0x707f -#define MATCH_CUSTOM3 0x7b -#define MASK_CUSTOM3 0x707f -#define MATCH_CUSTOM3_RS1 0x207b -#define MASK_CUSTOM3_RS1 0x707f -#define MATCH_CUSTOM3_RS1_RS2 0x307b -#define MASK_CUSTOM3_RS1_RS2 0x707f -#define MATCH_CUSTOM3_RD 0x407b -#define MASK_CUSTOM3_RD 0x707f -#define MATCH_CUSTOM3_RD_RS1 0x607b -#define MASK_CUSTOM3_RD_RS1 0x707f -#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b -#define MASK_CUSTOM3_RD_RS1_RS2 0x707f -#define CSR_FFLAGS 0x1 -#define CSR_FRM 0x2 -#define CSR_FCSR 0x3 -#define CSR_CYCLE 0xc00 -#define CSR_TIME 0xc01 -#define CSR_INSTRET 0xc02 -#define CSR_HPMCOUNTER3 0xc03 -#define CSR_HPMCOUNTER4 0xc04 -#define CSR_HPMCOUNTER5 0xc05 -#define CSR_HPMCOUNTER6 0xc06 -#define CSR_HPMCOUNTER7 0xc07 -#define CSR_HPMCOUNTER8 0xc08 -#define CSR_HPMCOUNTER9 0xc09 -#define CSR_HPMCOUNTER10 0xc0a -#define CSR_HPMCOUNTER11 0xc0b -#define CSR_HPMCOUNTER12 0xc0c -#define CSR_HPMCOUNTER13 0xc0d -#define CSR_HPMCOUNTER14 0xc0e -#define CSR_HPMCOUNTER15 0xc0f -#define CSR_HPMCOUNTER16 0xc10 -#define CSR_HPMCOUNTER17 0xc11 -#define CSR_HPMCOUNTER18 0xc12 -#define CSR_HPMCOUNTER19 0xc13 -#define CSR_HPMCOUNTER20 0xc14 -#define CSR_HPMCOUNTER21 0xc15 -#define CSR_HPMCOUNTER22 0xc16 -#define CSR_HPMCOUNTER23 0xc17 -#define CSR_HPMCOUNTER24 0xc18 -#define CSR_HPMCOUNTER25 0xc19 -#define CSR_HPMCOUNTER26 0xc1a -#define CSR_HPMCOUNTER27 0xc1b -#define CSR_HPMCOUNTER28 0xc1c -#define CSR_HPMCOUNTER29 0xc1d -#define CSR_HPMCOUNTER30 0xc1e -#define CSR_HPMCOUNTER31 0xc1f -#define CSR_SSTATUS 0x100 -#define CSR_SIE 0x104 -#define CSR_STVEC 0x105 -#define CSR_SSCRATCH 0x140 -#define CSR_SEPC 0x141 -#define CSR_SCAUSE 0x142 -#define CSR_SBADADDR 0x143 -#define CSR_SIP 0x144 -#define CSR_SPTBR 0x180 -#define CSR_MSTATUS 0x300 -#define CSR_MISA 0x301 -#define CSR_MEDELEG 0x302 -#define CSR_MIDELEG 0x303 -#define CSR_MIE 0x304 -#define CSR_MTVEC 0x305 -#define CSR_MSCRATCH 0x340 -#define CSR_MEPC 0x341 -#define CSR_MCAUSE 0x342 -#define CSR_MBADADDR 0x343 -#define CSR_MIP 0x344 -#define CSR_TSELECT 0x7a0 -#define CSR_TDATA1 0x7a1 -#define CSR_TDATA2 0x7a2 -#define CSR_TDATA3 0x7a3 -#define CSR_DCSR 0x7b0 -#define CSR_DPC 0x7b1 -#define CSR_DSCRATCH 0x7b2 -#define CSR_MCYCLE 0xb00 -#define CSR_MINSTRET 0xb02 -#define CSR_MHPMCOUNTER3 0xb03 -#define CSR_MHPMCOUNTER4 0xb04 -#define CSR_MHPMCOUNTER5 0xb05 -#define CSR_MHPMCOUNTER6 0xb06 -#define CSR_MHPMCOUNTER7 0xb07 -#define CSR_MHPMCOUNTER8 0xb08 -#define CSR_MHPMCOUNTER9 0xb09 -#define CSR_MHPMCOUNTER10 0xb0a -#define CSR_MHPMCOUNTER11 0xb0b -#define CSR_MHPMCOUNTER12 0xb0c -#define CSR_MHPMCOUNTER13 0xb0d -#define CSR_MHPMCOUNTER14 0xb0e -#define CSR_MHPMCOUNTER15 0xb0f -#define CSR_MHPMCOUNTER16 0xb10 -#define CSR_MHPMCOUNTER17 0xb11 -#define CSR_MHPMCOUNTER18 0xb12 -#define CSR_MHPMCOUNTER19 0xb13 -#define CSR_MHPMCOUNTER20 0xb14 -#define CSR_MHPMCOUNTER21 0xb15 -#define CSR_MHPMCOUNTER22 0xb16 -#define CSR_MHPMCOUNTER23 0xb17 -#define CSR_MHPMCOUNTER24 0xb18 -#define CSR_MHPMCOUNTER25 0xb19 -#define CSR_MHPMCOUNTER26 0xb1a -#define CSR_MHPMCOUNTER27 0xb1b -#define CSR_MHPMCOUNTER28 0xb1c -#define CSR_MHPMCOUNTER29 0xb1d -#define CSR_MHPMCOUNTER30 0xb1e -#define CSR_MHPMCOUNTER31 0xb1f -#define CSR_MUCOUNTEREN 0x320 -#define CSR_MSCOUNTEREN 0x321 -#define CSR_MHPMEVENT3 0x323 -#define CSR_MHPMEVENT4 0x324 -#define CSR_MHPMEVENT5 0x325 -#define CSR_MHPMEVENT6 0x326 -#define CSR_MHPMEVENT7 0x327 -#define CSR_MHPMEVENT8 0x328 -#define CSR_MHPMEVENT9 0x329 -#define CSR_MHPMEVENT10 0x32a -#define CSR_MHPMEVENT11 0x32b -#define CSR_MHPMEVENT12 0x32c -#define CSR_MHPMEVENT13 0x32d -#define CSR_MHPMEVENT14 0x32e -#define CSR_MHPMEVENT15 0x32f -#define CSR_MHPMEVENT16 0x330 -#define CSR_MHPMEVENT17 0x331 -#define CSR_MHPMEVENT18 0x332 -#define CSR_MHPMEVENT19 0x333 -#define CSR_MHPMEVENT20 0x334 -#define CSR_MHPMEVENT21 0x335 -#define CSR_MHPMEVENT22 0x336 -#define CSR_MHPMEVENT23 0x337 -#define CSR_MHPMEVENT24 0x338 -#define CSR_MHPMEVENT25 0x339 -#define CSR_MHPMEVENT26 0x33a -#define CSR_MHPMEVENT27 0x33b -#define CSR_MHPMEVENT28 0x33c -#define CSR_MHPMEVENT29 0x33d -#define CSR_MHPMEVENT30 0x33e -#define CSR_MHPMEVENT31 0x33f -#define CSR_MVENDORID 0xf11 -#define CSR_MARCHID 0xf12 -#define CSR_MIMPID 0xf13 -#define CSR_MHARTID 0xf14 -#define CSR_CYCLEH 0xc80 -#define CSR_TIMEH 0xc81 -#define CSR_INSTRETH 0xc82 -#define CSR_HPMCOUNTER3H 0xc83 -#define CSR_HPMCOUNTER4H 0xc84 -#define CSR_HPMCOUNTER5H 0xc85 -#define CSR_HPMCOUNTER6H 0xc86 -#define CSR_HPMCOUNTER7H 0xc87 -#define CSR_HPMCOUNTER8H 0xc88 -#define CSR_HPMCOUNTER9H 0xc89 -#define CSR_HPMCOUNTER10H 0xc8a -#define CSR_HPMCOUNTER11H 0xc8b -#define CSR_HPMCOUNTER12H 0xc8c -#define CSR_HPMCOUNTER13H 0xc8d -#define CSR_HPMCOUNTER14H 0xc8e -#define CSR_HPMCOUNTER15H 0xc8f -#define CSR_HPMCOUNTER16H 0xc90 -#define CSR_HPMCOUNTER17H 0xc91 -#define CSR_HPMCOUNTER18H 0xc92 -#define CSR_HPMCOUNTER19H 0xc93 -#define CSR_HPMCOUNTER20H 0xc94 -#define CSR_HPMCOUNTER21H 0xc95 -#define CSR_HPMCOUNTER22H 0xc96 -#define CSR_HPMCOUNTER23H 0xc97 -#define CSR_HPMCOUNTER24H 0xc98 -#define CSR_HPMCOUNTER25H 0xc99 -#define CSR_HPMCOUNTER26H 0xc9a -#define CSR_HPMCOUNTER27H 0xc9b -#define CSR_HPMCOUNTER28H 0xc9c -#define CSR_HPMCOUNTER29H 0xc9d -#define CSR_HPMCOUNTER30H 0xc9e -#define CSR_HPMCOUNTER31H 0xc9f -#define CSR_MCYCLEH 0xb80 -#define CSR_MINSTRETH 0xb82 -#define CSR_MHPMCOUNTER3H 0xb83 -#define CSR_MHPMCOUNTER4H 0xb84 -#define CSR_MHPMCOUNTER5H 0xb85 -#define CSR_MHPMCOUNTER6H 0xb86 -#define CSR_MHPMCOUNTER7H 0xb87 -#define CSR_MHPMCOUNTER8H 0xb88 -#define CSR_MHPMCOUNTER9H 0xb89 -#define CSR_MHPMCOUNTER10H 0xb8a -#define CSR_MHPMCOUNTER11H 0xb8b -#define CSR_MHPMCOUNTER12H 0xb8c -#define CSR_MHPMCOUNTER13H 0xb8d -#define CSR_MHPMCOUNTER14H 0xb8e -#define CSR_MHPMCOUNTER15H 0xb8f -#define CSR_MHPMCOUNTER16H 0xb90 -#define CSR_MHPMCOUNTER17H 0xb91 -#define CSR_MHPMCOUNTER18H 0xb92 -#define CSR_MHPMCOUNTER19H 0xb93 -#define CSR_MHPMCOUNTER20H 0xb94 -#define CSR_MHPMCOUNTER21H 0xb95 -#define CSR_MHPMCOUNTER22H 0xb96 -#define CSR_MHPMCOUNTER23H 0xb97 -#define CSR_MHPMCOUNTER24H 0xb98 -#define CSR_MHPMCOUNTER25H 0xb99 -#define CSR_MHPMCOUNTER26H 0xb9a -#define CSR_MHPMCOUNTER27H 0xb9b -#define CSR_MHPMCOUNTER28H 0xb9c -#define CSR_MHPMCOUNTER29H 0xb9d -#define CSR_MHPMCOUNTER30H 0xb9e -#define CSR_MHPMCOUNTER31H 0xb9f -#define CAUSE_MISALIGNED_FETCH 0x0 -#define CAUSE_FAULT_FETCH 0x1 -#define CAUSE_ILLEGAL_INSTRUCTION 0x2 -#define CAUSE_BREAKPOINT 0x3 -#define CAUSE_MISALIGNED_LOAD 0x4 -#define CAUSE_FAULT_LOAD 0x5 -#define CAUSE_MISALIGNED_STORE 0x6 -#define CAUSE_FAULT_STORE 0x7 -#define CAUSE_USER_ECALL 0x8 -#define CAUSE_SUPERVISOR_ECALL 0x9 -#define CAUSE_HYPERVISOR_ECALL 0xa -#define CAUSE_MACHINE_ECALL 0xb -#endif -#ifdef DECLARE_INSN -DECLARE_INSN(slli_rv32, MATCH_SLLI_RV32, MASK_SLLI_RV32) -DECLARE_INSN(srli_rv32, MATCH_SRLI_RV32, MASK_SRLI_RV32) -DECLARE_INSN(srai_rv32, MATCH_SRAI_RV32, MASK_SRAI_RV32) -DECLARE_INSN(frflags, MATCH_FRFLAGS, MASK_FRFLAGS) -DECLARE_INSN(fsflags, MATCH_FSFLAGS, MASK_FSFLAGS) -DECLARE_INSN(fsflagsi, MATCH_FSFLAGSI, MASK_FSFLAGSI) -DECLARE_INSN(frrm, MATCH_FRRM, MASK_FRRM) -DECLARE_INSN(fsrm, MATCH_FSRM, MASK_FSRM) -DECLARE_INSN(fsrmi, MATCH_FSRMI, MASK_FSRMI) -DECLARE_INSN(fscsr, MATCH_FSCSR, MASK_FSCSR) -DECLARE_INSN(frcsr, MATCH_FRCSR, MASK_FRCSR) -DECLARE_INSN(rdcycle, MATCH_RDCYCLE, MASK_RDCYCLE) -DECLARE_INSN(rdtime, MATCH_RDTIME, MASK_RDTIME) -DECLARE_INSN(rdinstret, MATCH_RDINSTRET, MASK_RDINSTRET) -DECLARE_INSN(rdcycleh, MATCH_RDCYCLEH, MASK_RDCYCLEH) -DECLARE_INSN(rdtimeh, MATCH_RDTIMEH, MASK_RDTIMEH) -DECLARE_INSN(rdinstreth, MATCH_RDINSTRETH, MASK_RDINSTRETH) -DECLARE_INSN(scall, MATCH_SCALL, MASK_SCALL) -DECLARE_INSN(sbreak, MATCH_SBREAK, MASK_SBREAK) -DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) -DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) -DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) -DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) -DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) -DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) -DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) -DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) -DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) -DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) -DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) -DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) -DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) -DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) -DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) -DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) -DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) -DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) -DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) -DECLARE_INSN(add, MATCH_ADD, MASK_ADD) -DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) -DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) -DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) -DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) -DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) -DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) -DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) -DECLARE_INSN(or, MATCH_OR, MASK_OR) -DECLARE_INSN(and, MATCH_AND, MASK_AND) -DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) -DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) -DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) -DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) -DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) -DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) -DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) -DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) -DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) -DECLARE_INSN(lb, MATCH_LB, MASK_LB) -DECLARE_INSN(lh, MATCH_LH, MASK_LH) -DECLARE_INSN(lw, MATCH_LW, MASK_LW) -DECLARE_INSN(ld, MATCH_LD, MASK_LD) -DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) -DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) -DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) -DECLARE_INSN(sb, MATCH_SB, MASK_SB) -DECLARE_INSN(sh, MATCH_SH, MASK_SH) -DECLARE_INSN(sw, MATCH_SW, MASK_SW) -DECLARE_INSN(sd, MATCH_SD, MASK_SD) -DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) -DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) -DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) -DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) -DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) -DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) -DECLARE_INSN(div, MATCH_DIV, MASK_DIV) -DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) -DECLARE_INSN(rem, MATCH_REM, MASK_REM) -DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) -DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) -DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) -DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) -DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) -DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) -DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) -DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) -DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) -DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) -DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) -DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) -DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) -DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) -DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) -DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) -DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) -DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) -DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) -DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) -DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) -DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) -DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) -DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) -DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) -DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) -DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) -DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) -DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) -DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) -DECLARE_INSN(uret, MATCH_URET, MASK_URET) -DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) -DECLARE_INSN(hret, MATCH_HRET, MASK_HRET) -DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) -DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) -DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM) -DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) -DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) -DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) -DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) -DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) -DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) -DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) -DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) -DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) -DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) -DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) -DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) -DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) -DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) -DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) -DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) -DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) -DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) -DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) -DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) -DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) -DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) -DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) -DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) -DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) -DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) -DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) -DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) -DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) -DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q) -DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q) -DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q) -DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q) -DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q) -DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q) -DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q) -DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q) -DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q) -DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q) -DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S) -DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q) -DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D) -DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q) -DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) -DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) -DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) -DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) -DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) -DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) -DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q) -DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q) -DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q) -DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) -DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) -DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) -DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) -DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S) -DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) -DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) -DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) -DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) -DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) -DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) -DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) -DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q) -DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q) -DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q) -DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q) -DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q) -DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q) -DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) -DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) -DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) -DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) -DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X) -DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) -DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) -DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) -DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) -DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) -DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W) -DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU) -DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L) -DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU) -DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X) -DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) -DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) -DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ) -DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) -DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) -DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ) -DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) -DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) -DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) -DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) -DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) -DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) -DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) -DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) -DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q) -DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q) -DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q) -DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q) -DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) -DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) -DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) -DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) -DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) -DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) -DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) -DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) -DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) -DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) -DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) -DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) -DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) -DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI) -DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) -DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR) -DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR) -DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND) -DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) -DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) -DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) -DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) -DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) -DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) -DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP) -DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) -DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP) -DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) -DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) -DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP) -DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) -DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP) -DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) -DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) -DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) -DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) -DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK) -DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) -DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) -DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) -DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) -DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) -DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0) -DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1) -DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2) -DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD) -DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1) -DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2) -DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1) -DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1) -DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2) -DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD) -DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1) -DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2) -DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2) -DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1) -DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2) -DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD) -DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1) -DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2) -DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3) -DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1) -DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) -DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) -DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) -DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) -#endif -#ifdef DECLARE_CSR -DECLARE_CSR(fflags, CSR_FFLAGS) -DECLARE_CSR(frm, CSR_FRM) -DECLARE_CSR(fcsr, CSR_FCSR) -DECLARE_CSR(cycle, CSR_CYCLE) -DECLARE_CSR(time, CSR_TIME) -DECLARE_CSR(instret, CSR_INSTRET) -DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3) -DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4) -DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5) -DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6) -DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7) -DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8) -DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9) -DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10) -DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11) -DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12) -DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13) -DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14) -DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15) -DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16) -DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17) -DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18) -DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19) -DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20) -DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21) -DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22) -DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23) -DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24) -DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25) -DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26) -DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27) -DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28) -DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29) -DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30) -DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31) -DECLARE_CSR(sstatus, CSR_SSTATUS) -DECLARE_CSR(sie, CSR_SIE) -DECLARE_CSR(stvec, CSR_STVEC) -DECLARE_CSR(sscratch, CSR_SSCRATCH) -DECLARE_CSR(sepc, CSR_SEPC) -DECLARE_CSR(scause, CSR_SCAUSE) -DECLARE_CSR(sbadaddr, CSR_SBADADDR) -DECLARE_CSR(sip, CSR_SIP) -DECLARE_CSR(sptbr, CSR_SPTBR) -DECLARE_CSR(mstatus, CSR_MSTATUS) -DECLARE_CSR(misa, CSR_MISA) -DECLARE_CSR(medeleg, CSR_MEDELEG) -DECLARE_CSR(mideleg, CSR_MIDELEG) -DECLARE_CSR(mie, CSR_MIE) -DECLARE_CSR(mtvec, CSR_MTVEC) -DECLARE_CSR(mscratch, CSR_MSCRATCH) -DECLARE_CSR(mepc, CSR_MEPC) -DECLARE_CSR(mcause, CSR_MCAUSE) -DECLARE_CSR(mbadaddr, CSR_MBADADDR) -DECLARE_CSR(mip, CSR_MIP) -DECLARE_CSR(tselect, CSR_TSELECT) -DECLARE_CSR(tdata1, CSR_TDATA1) -DECLARE_CSR(tdata2, CSR_TDATA2) -DECLARE_CSR(tdata3, CSR_TDATA3) -DECLARE_CSR(dcsr, CSR_DCSR) -DECLARE_CSR(dpc, CSR_DPC) -DECLARE_CSR(dscratch, CSR_DSCRATCH) -DECLARE_CSR(mcycle, CSR_MCYCLE) -DECLARE_CSR(minstret, CSR_MINSTRET) -DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3) -DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4) -DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5) -DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6) -DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7) -DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8) -DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9) -DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10) -DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11) -DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12) -DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13) -DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14) -DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15) -DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16) -DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17) -DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18) -DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19) -DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20) -DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21) -DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22) -DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23) -DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24) -DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25) -DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26) -DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27) -DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28) -DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29) -DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30) -DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31) -DECLARE_CSR(mucounteren, CSR_MUCOUNTEREN) -DECLARE_CSR(mscounteren, CSR_MSCOUNTEREN) -DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3) -DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4) -DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5) -DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6) -DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7) -DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8) -DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9) -DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10) -DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11) -DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12) -DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13) -DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14) -DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15) -DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16) -DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17) -DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18) -DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19) -DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20) -DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21) -DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22) -DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23) -DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24) -DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25) -DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26) -DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27) -DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28) -DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29) -DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30) -DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31) -DECLARE_CSR(mvendorid, CSR_MVENDORID) -DECLARE_CSR(marchid, CSR_MARCHID) -DECLARE_CSR(mimpid, CSR_MIMPID) -DECLARE_CSR(mhartid, CSR_MHARTID) -DECLARE_CSR(cycleh, CSR_CYCLEH) -DECLARE_CSR(timeh, CSR_TIMEH) -DECLARE_CSR(instreth, CSR_INSTRETH) -DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H) -DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H) -DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H) -DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H) -DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H) -DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H) -DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H) -DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H) -DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H) -DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H) -DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H) -DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H) -DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H) -DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H) -DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H) -DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H) -DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H) -DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H) -DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H) -DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H) -DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H) -DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H) -DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H) -DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H) -DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H) -DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H) -DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H) -DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H) -DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H) -DECLARE_CSR(mcycleh, CSR_MCYCLEH) -DECLARE_CSR(minstreth, CSR_MINSTRETH) -DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H) -DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H) -DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H) -DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H) -DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H) -DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H) -DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H) -DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H) -DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H) -DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H) -DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H) -DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H) -DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H) -DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H) -DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H) -DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H) -DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H) -DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H) -DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H) -DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H) -DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H) -DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H) -DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H) -DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H) -DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H) -DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H) -DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H) -DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H) -DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H) -#endif -#ifdef DECLARE_CAUSE -DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) -DECLARE_CAUSE("fault fetch", CAUSE_FAULT_FETCH) -DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION) -DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT) -DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD) -DECLARE_CAUSE("fault load", CAUSE_FAULT_LOAD) -DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE) -DECLARE_CAUSE("fault store", CAUSE_FAULT_STORE) -DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL) -DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL) -DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL) -DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL) -#endif - diff --git a/librz/arch/isa_gnu/riscv/riscv.c b/librz/arch/isa_gnu/riscv/riscv.c deleted file mode 100644 index 9af87e2bf49..00000000000 --- a/librz/arch/isa_gnu/riscv/riscv.c +++ /dev/null @@ -1,333 +0,0 @@ -// SPDX-FileCopyrightText: 2011-2015 Free Software Foundation, Inc. -// SPDX-License-Identifier: GPL-3.0-or-later - -/* RISC-V disassembler - Copyright 2011-2015 Free Software Foundation, Inc. - Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley. - Based on MIPS target. - This file is part of the GNU opcodes library. - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - It is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING3. If not, - see . - - - Code changes to make r2 friendly (qnix@0x80.org) -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "riscv-opc.h" -#include "riscv.h" - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a)) - -// TODO : an conf to chose between abi or numeric -static const char *const *riscv_gpr_names = riscv_gpr_names_abi; -static const char *const *riscv_fpr_names = riscv_fpr_names_abi; -static bool init_asm = 0; - -static void arg_p(char *buf, unsigned long val, const char *const *array, size_t size) { - const char *s = val >= size || array[val] ? array[val] : "unknown"; - sprintf(buf + strlen(buf), "%s", s); -} - -/* Print insn arguments for 32/64-bit code. */ -static void get_insn_args(char *buf, const char *d, insn_t l, uint64_t pc) { - int rs1 = (l >> OP_SH_RS1) & OP_MASK_RS1; - int rd = (l >> OP_SH_RD) & OP_MASK_RD; - uint64_t target; - - if (*d != '\0') { - sprintf(buf + strlen(buf), " "); - } - - for (; *d != '\0'; d++) { - switch (*d) { - /* Xcustom */ - case '^': - switch (*++d) { - case 'd': - sprintf(buf + strlen(buf), "%d", rd); - break; - case 's': - sprintf(buf + strlen(buf), "%d", rs1); - break; - case 't': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_OPERAND(RS2, l)); - break; - case 'j': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_OPERAND(CUSTOM_IMM, l)); - break; - } - break; - - case 'C': /* RVC */ - switch (*++d) { - case 's': /* RS1 x8-x15 */ - case 'w': /* RS1 x8-x15 */ - sprintf(buf + strlen(buf), "%s", - riscv_gpr_names[EXTRACT_OPERAND(CRS1S, l) + 8]); - break; - case 't': /* RS2 x8-x15 */ - case 'x': /* RS2 x8-x15 */ - sprintf(buf + strlen(buf), "%s", - riscv_gpr_names[EXTRACT_OPERAND(CRS2S, l) + 8]); - break; - case 'U': /* RS1, constrained to equal RD */ - sprintf(buf + strlen(buf), "%s", riscv_gpr_names[rd]); - break; - case 'c': /* RS1, constrained to equal sp */ - sprintf(buf + strlen(buf), "%s", riscv_gpr_names[X_SP]); - break; - case 'V': /* RS2 */ - sprintf(buf + strlen(buf), "%s", - riscv_gpr_names[EXTRACT_OPERAND(CRS2, l)]); - break; - case 'i': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_RVC_SIMM3(l)); - break; - case 'j': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_RVC_IMM(l)); - break; - case 'k': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_RVC_LW_IMM(l)); - break; - case 'l': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_RVC_LD_IMM(l)); - break; - case 'm': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_RVC_LWSP_IMM(l)); - break; - case 'n': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_RVC_LDSP_IMM(l)); - break; - case 'K': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_RVC_ADDI4SPN_IMM(l)); - break; - case 'L': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_RVC_ADDI16SP_IMM(l)); - break; - case 'M': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_RVC_SWSP_IMM(l)); - break; - case 'N': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_RVC_SDSP_IMM(l)); - break; - case 'p': - target = EXTRACT_RVC_B_IMM(l) + pc; - sprintf(buf + strlen(buf), "0x%" PFMT64x, (ut64)target); - break; - case 'a': - target = EXTRACT_RVC_J_IMM(l) + pc; - sprintf(buf + strlen(buf), "0x%" PFMT64x, (ut64)target); - break; - case 'u': - sprintf(buf + strlen(buf), "0x%x", - (int)(EXTRACT_RVC_IMM(l) & (RISCV_BIGIMM_REACH - 1))); - break; - case '>': - sprintf(buf + strlen(buf), "0x%x", (int)EXTRACT_RVC_IMM(l) & 0x3f); - break; - case '<': - sprintf(buf + strlen(buf), "0x%x", (int)EXTRACT_RVC_IMM(l) & 0x1f); - break; - case 'T': /* floating-point RS2 */ - sprintf(buf + strlen(buf), "%s", - riscv_fpr_names[EXTRACT_OPERAND(CRS2, l)]); - break; - case 'D': /* floating-point RS2 x8-x15 */ - sprintf(buf + strlen(buf), "%s", - riscv_fpr_names[EXTRACT_OPERAND(CRS2S, l) + 8]); - break; - } - break; - - case ',': - sprintf(buf + strlen(buf), "%c ", *d); - break; - case '(': - case ')': - case '[': - case ']': - sprintf(buf + strlen(buf), "%c", *d); - break; - case '0': - /* Only print constant 0 if it is the last argument */ - if (!d[1]) { - sprintf(buf + strlen(buf), "0"); - } - break; - - case 'b': - case 's': - sprintf(buf + strlen(buf), "%s", riscv_gpr_names[rs1]); - break; - - case 't': - sprintf(buf + strlen(buf), "%s", - riscv_gpr_names[EXTRACT_OPERAND(RS2, l)]); - break; - - case 'u': - sprintf(buf + strlen(buf), "0x%x", - (unsigned)EXTRACT_UTYPE_IMM(l) >> RISCV_IMM_BITS); - break; - - case 'm': - arg_p(buf, EXTRACT_OPERAND(RM, l), - riscv_rm, ARRAY_SIZE(riscv_rm)); - break; - - case 'P': - arg_p(buf, EXTRACT_OPERAND(PRED, l), - riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ)); - break; - - case 'Q': - arg_p(buf, EXTRACT_OPERAND(SUCC, l), - riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ)); - break; - case 'o': - case 'j': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_ITYPE_IMM(l)); - break; - case 'q': - sprintf(buf + strlen(buf), "%d", (int)EXTRACT_STYPE_IMM(l)); - break; - case 'a': - target = EXTRACT_UJTYPE_IMM(l) + pc; - sprintf(buf + strlen(buf), "0x%" PFMT64x, (ut64)target); - break; - case 'p': - target = EXTRACT_SBTYPE_IMM(l) + pc; - sprintf(buf + strlen(buf), "0x%" PFMT64x, (ut64)target); - break; - case 'd': - sprintf(buf + strlen(buf), "%s", riscv_gpr_names[rd]); - break; - case 'z': - sprintf(buf + strlen(buf), "%s", riscv_gpr_names[0]); - break; - case '>': - sprintf(buf + strlen(buf), "0x%x", (int)EXTRACT_OPERAND(SHAMT, l)); - break; - case '<': - sprintf(buf + strlen(buf), "0x%x", (int)EXTRACT_OPERAND(SHAMTW, l)); - break; - case 'S': - case 'U': - sprintf(buf + strlen(buf), "%s", riscv_fpr_names[rs1]); - break; - case 'T': - sprintf(buf + strlen(buf), "%s", riscv_fpr_names[EXTRACT_OPERAND(RS2, l)]); - break; - case 'D': - sprintf(buf + strlen(buf), "%s", riscv_fpr_names[rd]); - break; - case 'R': - sprintf(buf + strlen(buf), "%s", riscv_fpr_names[EXTRACT_OPERAND(RS3, l)]); - break; - case 'E': { - const char *csr_name = NULL; - unsigned int csr = EXTRACT_OPERAND(CSR, l); - switch (csr) { -#define DECLARE_CSR(name, num) \ - case num: csr_name = #name; break; -#include "riscv-opc.h" -#undef DECLARE_CSR - } - if (csr_name) { - sprintf(buf + strlen(buf), "%s", csr_name); - } else { - sprintf(buf + strlen(buf), "0x%x", csr); - } - break; - } - case 'Z': - sprintf(buf + strlen(buf), "%d", rs1); - break; - default: - /* xgettext:c-format */ - sprintf(buf + strlen(buf), "# internal error, undefined modifier (%c)", - *d); - return; - } - } -} - -static struct riscv_opcode *get_opcode(insn_t word) { - struct riscv_opcode *op; - static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1] = { 0 }; - -#define OP_HASH_IDX(i) ((i) & (riscv_insn_length(i) == 2 ? 3 : OP_MASK_OP)) - - if (!init_asm) { - for (op = riscv_opcodes; op < &riscv_opcodes[NUMOPCODES]; op++) { - if (!riscv_hash[OP_HASH_IDX(op->match)]) { - riscv_hash[OP_HASH_IDX(op->match)] = op; - } - } - init_asm = 1; - } - - return (struct riscv_opcode *)riscv_hash[OP_HASH_IDX(word)]; -} - -static int riscv_disassemble(RzAsm *a, RzAsmOp *rop, insn_t word, int xlen, int len) { - const bool no_alias = false; - const struct riscv_opcode *op = get_opcode(word); - if (!op) { - return -1; - } - for (; op < &riscv_opcodes[NUMOPCODES]; op++) { - if (!(op->match_func)(op, word)) { - continue; - } - if (no_alias && (op->pinfo & INSN_ALIAS)) { - continue; - } - if (isdigit((ut8)op->subset[0]) && atoi(op->subset) != xlen) { - continue; - } - if (op->name && op->args) { - rz_asm_op_set_asm(rop, op->name); - get_insn_args(rz_asm_op_get_asm(rop), op->args, word, a->pc); - return 0; - } - return -1; - } - return 0; -} - -static int riscv_dis(RzAsm *a, RzAsmOp *rop, const ut8 *buf, ut64 len) { - insn_t insn = { 0 }; - rz_asm_op_set_asm(rop, "invalid"); - if (len < 2) { - return -1; - } - // Read <= 8 bytes into 8-byte buffer in little endian fashion - RZ_STATIC_ASSERT(sizeof(insn) == 8); - ut8 tmp[8] = { 0 }; - memcpy(&tmp, buf, RZ_MIN(sizeof(insn), len)); - insn = rz_read_le64(tmp); - int insn_len = riscv_insn_length(insn); - if (len < insn_len) { - return -1; - } - riscv_disassemble(a, rop, insn, a->bits, len); - return insn_len; -} diff --git a/librz/arch/isa_gnu/riscv/riscv.h b/librz/arch/isa_gnu/riscv/riscv.h deleted file mode 100644 index dcf70306981..00000000000 --- a/librz/arch/isa_gnu/riscv/riscv.h +++ /dev/null @@ -1,353 +0,0 @@ -// SPDX-FileCopyrightText: 2011-2017 Free Software Foundation, Inc. -// SPDX-License-Identifier: GPL-3.0-or-later - -/* riscv.h. RISC-V opcode list for GDB, the GNU debugger. - Copyright (C) 2011-2017 Free Software Foundation, Inc. - Contributed by Andrew Waterman - - This file is part of GDB, GAS, and the GNU binutils. - - GDB, GAS, and the GNU binutils are free software; you can redistribute - them and/or modify them under the terms of the GNU General Public - License as published by the Free Software Foundation; either version - 3, or (at your option) any later version. - - GDB, GAS, and the GNU binutils are distributed in the hope that they - will be useful, but WITHOUT ANY WARRANTY; without even the implied - warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING3. If not, - see . */ - -#ifndef _RISCV_H_ -#define _RISCV_H_ - -#include "riscv-opc.h" -#include -#include - -typedef uint64_t insn_t; - -static inline unsigned int riscv_insn_length (insn_t insn) -{ - if ((insn & 0x3) != 0x3) /* RVC. */ - return 2; - if ((insn & 0x1f) != 0x1f) /* Base ISA and extensions in 32-bit space. */ - return 4; - if ((insn & 0x3f) == 0x1f) /* 48-bit extensions. */ - return 6; - if ((insn & 0x7f) == 0x3f) /* 64-bit extensions. */ - return 8; - /* Longer instructions not supported at the moment. */ - return 2; -} - -static const char * const riscv_rm[8] = -{ - "rne", "rtz", "rdn", "rup", "rmm", 0, 0, "dyn" -}; - -static const char * const riscv_pred_succ[16] = -{ - 0, "w", "r", "rw", "o", "ow", "or", "orw", - "i", "iw", "ir", "irw", "io", "iow", "ior", "iorw" -}; - -#define RVC_JUMP_BITS 11 -#define RVC_JUMP_REACH ((1ULL << RVC_JUMP_BITS) * RISCV_JUMP_ALIGN) - -#define RVC_BRANCH_BITS 8 -#define RVC_BRANCH_REACH ((1ULL << RVC_BRANCH_BITS) * RISCV_BRANCH_ALIGN) - -#define RV_X(x, s, n) (((x) >> (s)) & ((1 << (n)) - 1)) -#define RV_IMM_SIGN(x) (-(((x) >> 31) & 1)) - -#define EXTRACT_ITYPE_IMM(x) \ - (RV_X(x, 20, 12) | (RV_IMM_SIGN(x) << 12)) -#define EXTRACT_STYPE_IMM(x) \ - (RV_X(x, 7, 5) | (RV_X(x, 25, 7) << 5) | (RV_IMM_SIGN(x) << 12)) -#define EXTRACT_SBTYPE_IMM(x) \ - ((RV_X(x, 8, 4) << 1) | (RV_X(x, 25, 6) << 5) | (RV_X(x, 7, 1) << 11) | (RV_IMM_SIGN(x) << 12)) -#define EXTRACT_UTYPE_IMM(x) \ - ((RV_X(x, 12, 20) << 12) | (RV_IMM_SIGN(x) << 32)) -#define EXTRACT_UJTYPE_IMM(x) \ - ((RV_X(x, 21, 10) << 1) | (RV_X(x, 20, 1) << 11) | (RV_X(x, 12, 8) << 12) | (RV_IMM_SIGN(x) << 20)) -#define EXTRACT_RVC_IMM(x) \ - (RV_X(x, 2, 5) | (-RV_X(x, 12, 1) << 5)) -#define EXTRACT_RVC_LUI_IMM(x) \ - (EXTRACT_RVC_IMM (x) << RISCV_IMM_BITS) -#define EXTRACT_RVC_SIMM3(x) \ - (RV_X(x, 10, 2) | (-RV_X(x, 12, 1) << 2)) -#define EXTRACT_RVC_ADDI4SPN_IMM(x) \ - ((RV_X(x, 6, 1) << 2) | (RV_X(x, 5, 1) << 3) | (RV_X(x, 11, 2) << 4) | (RV_X(x, 7, 4) << 6)) -#define EXTRACT_RVC_ADDI16SP_IMM(x) \ - ((RV_X(x, 6, 1) << 4) | (RV_X(x, 2, 1) << 5) | (RV_X(x, 5, 1) << 6) | (RV_X(x, 3, 2) << 7) | (-RV_X(x, 12, 1) << 9)) -#define EXTRACT_RVC_LW_IMM(x) \ - ((RV_X(x, 6, 1) << 2) | (RV_X(x, 10, 3) << 3) | (RV_X(x, 5, 1) << 6)) -#define EXTRACT_RVC_LD_IMM(x) \ - ((RV_X(x, 10, 3) << 3) | (RV_X(x, 5, 2) << 6)) -#define EXTRACT_RVC_LWSP_IMM(x) \ - ((RV_X(x, 4, 3) << 2) | (RV_X(x, 12, 1) << 5) | (RV_X(x, 2, 2) << 6)) -#define EXTRACT_RVC_LDSP_IMM(x) \ - ((RV_X(x, 5, 2) << 3) | (RV_X(x, 12, 1) << 5) | (RV_X(x, 2, 3) << 6)) -#define EXTRACT_RVC_SWSP_IMM(x) \ - ((RV_X(x, 9, 4) << 2) | (RV_X(x, 7, 2) << 6)) -#define EXTRACT_RVC_SDSP_IMM(x) \ - ((RV_X(x, 10, 3) << 3) | (RV_X(x, 7, 3) << 6)) -#define EXTRACT_RVC_B_IMM(x) \ - ((RV_X(x, 3, 2) << 1) | (RV_X(x, 10, 2) << 3) | (RV_X(x, 2, 1) << 5) | (RV_X(x, 5, 2) << 6) | (-RV_X(x, 12, 1) << 8)) -#define EXTRACT_RVC_J_IMM(x) \ - ((RV_X(x, 3, 3) << 1) | (RV_X(x, 11, 1) << 4) | (RV_X(x, 2, 1) << 5) | (RV_X(x, 7, 1) << 6) | (RV_X(x, 6, 1) << 7) | (RV_X(x, 9, 2) << 8) | (RV_X(x, 8, 1) << 10) | (-RV_X(x, 12, 1) << 11)) - -#define ENCODE_ITYPE_IMM(x) \ - (RV_X(x, 0, 12) << 20) -#define ENCODE_STYPE_IMM(x) \ - ((RV_X(x, 0, 5) << 7) | (RV_X(x, 5, 7) << 25)) -#define ENCODE_SBTYPE_IMM(x) \ - ((RV_X(x, 1, 4) << 8) | (RV_X(x, 5, 6) << 25) | (RV_X(x, 11, 1) << 7) | (RV_X(x, 12, 1) << 31)) -#define ENCODE_UTYPE_IMM(x) \ - (RV_X(x, 12, 20) << 12) -#define ENCODE_UJTYPE_IMM(x) \ - ((RV_X(x, 1, 10) << 21) | (RV_X(x, 11, 1) << 20) | (RV_X(x, 12, 8) << 12) | (RV_X(x, 20, 1) << 31)) -#define ENCODE_RVC_IMM(x) \ - ((RV_X(x, 0, 5) << 2) | (RV_X(x, 5, 1) << 12)) -#define ENCODE_RVC_LUI_IMM(x) \ - ENCODE_RVC_IMM ((x) >> RISCV_IMM_BITS) -#define ENCODE_RVC_SIMM3(x) \ - (RV_X(x, 0, 3) << 10) -#define ENCODE_RVC_ADDI4SPN_IMM(x) \ - ((RV_X(x, 2, 1) << 6) | (RV_X(x, 3, 1) << 5) | (RV_X(x, 4, 2) << 11) | (RV_X(x, 6, 4) << 7)) -#define ENCODE_RVC_ADDI16SP_IMM(x) \ - ((RV_X(x, 4, 1) << 6) | (RV_X(x, 5, 1) << 2) | (RV_X(x, 6, 1) << 5) | (RV_X(x, 7, 2) << 3) | (RV_X(x, 9, 1) << 12)) -#define ENCODE_RVC_LW_IMM(x) \ - ((RV_X(x, 2, 1) << 6) | (RV_X(x, 3, 3) << 10) | (RV_X(x, 6, 1) << 5)) -#define ENCODE_RVC_LD_IMM(x) \ - ((RV_X(x, 3, 3) << 10) | (RV_X(x, 6, 2) << 5)) -#define ENCODE_RVC_LWSP_IMM(x) \ - ((RV_X(x, 2, 3) << 4) | (RV_X(x, 5, 1) << 12) | (RV_X(x, 6, 2) << 2)) -#define ENCODE_RVC_LDSP_IMM(x) \ - ((RV_X(x, 3, 2) << 5) | (RV_X(x, 5, 1) << 12) | (RV_X(x, 6, 3) << 2)) -#define ENCODE_RVC_SWSP_IMM(x) \ - ((RV_X(x, 2, 4) << 9) | (RV_X(x, 6, 2) << 7)) -#define ENCODE_RVC_SDSP_IMM(x) \ - ((RV_X(x, 3, 3) << 10) | (RV_X(x, 6, 3) << 7)) -#define ENCODE_RVC_B_IMM(x) \ - ((RV_X(x, 1, 2) << 3) | (RV_X(x, 3, 2) << 10) | (RV_X(x, 5, 1) << 2) | (RV_X(x, 6, 2) << 5) | (RV_X(x, 8, 1) << 12)) -#define ENCODE_RVC_J_IMM(x) \ - ((RV_X(x, 1, 3) << 3) | (RV_X(x, 4, 1) << 11) | (RV_X(x, 5, 1) << 2) | (RV_X(x, 6, 1) << 7) | (RV_X(x, 7, 1) << 6) | (RV_X(x, 8, 2) << 9) | (RV_X(x, 10, 1) << 8) | (RV_X(x, 11, 1) << 12)) - -#define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x)) -#define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x)) -#define VALID_SBTYPE_IMM(x) (EXTRACT_SBTYPE_IMM(ENCODE_SBTYPE_IMM(x)) == (x)) -#define VALID_UTYPE_IMM(x) (EXTRACT_UTYPE_IMM(ENCODE_UTYPE_IMM(x)) == (x)) -#define VALID_UJTYPE_IMM(x) (EXTRACT_UJTYPE_IMM(ENCODE_UJTYPE_IMM(x)) == (x)) -#define VALID_RVC_IMM(x) (EXTRACT_RVC_IMM(ENCODE_RVC_IMM(x)) == (x)) -#define VALID_RVC_LUI_IMM(x) (EXTRACT_RVC_LUI_IMM(ENCODE_RVC_LUI_IMM(x)) == (x)) -#define VALID_RVC_SIMM3(x) (EXTRACT_RVC_SIMM3(ENCODE_RVC_SIMM3(x)) == (x)) -#define VALID_RVC_ADDI4SPN_IMM(x) (EXTRACT_RVC_ADDI4SPN_IMM(ENCODE_RVC_ADDI4SPN_IMM(x)) == (x)) -#define VALID_RVC_ADDI16SP_IMM(x) (EXTRACT_RVC_ADDI16SP_IMM(ENCODE_RVC_ADDI16SP_IMM(x)) == (x)) -#define VALID_RVC_LW_IMM(x) (EXTRACT_RVC_LW_IMM(ENCODE_RVC_LW_IMM(x)) == (x)) -#define VALID_RVC_LD_IMM(x) (EXTRACT_RVC_LD_IMM(ENCODE_RVC_LD_IMM(x)) == (x)) -#define VALID_RVC_LWSP_IMM(x) (EXTRACT_RVC_LWSP_IMM(ENCODE_RVC_LWSP_IMM(x)) == (x)) -#define VALID_RVC_LDSP_IMM(x) (EXTRACT_RVC_LDSP_IMM(ENCODE_RVC_LDSP_IMM(x)) == (x)) -#define VALID_RVC_SWSP_IMM(x) (EXTRACT_RVC_SWSP_IMM(ENCODE_RVC_SWSP_IMM(x)) == (x)) -#define VALID_RVC_SDSP_IMM(x) (EXTRACT_RVC_SDSP_IMM(ENCODE_RVC_SDSP_IMM(x)) == (x)) -#define VALID_RVC_B_IMM(x) (EXTRACT_RVC_B_IMM(ENCODE_RVC_B_IMM(x)) == (x)) -#define VALID_RVC_J_IMM(x) (EXTRACT_RVC_J_IMM(ENCODE_RVC_J_IMM(x)) == (x)) - -#define RISCV_RTYPE(insn, rd, rs1, rs2) \ - ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2)) -#define RISCV_ITYPE(insn, rd, rs1, imm) \ - ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ENCODE_ITYPE_IMM(imm)) -#define RISCV_STYPE(insn, rs1, rs2, imm) \ - ((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_STYPE_IMM(imm)) -#define RISCV_SBTYPE(insn, rs1, rs2, target) \ - ((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_SBTYPE_IMM(target)) -#define RISCV_UTYPE(insn, rd, bigimm) \ - ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UTYPE_IMM(bigimm)) -#define RISCV_UJTYPE(insn, rd, target) \ - ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UJTYPE_IMM(target)) - -#define RISCV_NOP RISCV_ITYPE(ADDI, 0, 0, 0) -#define RVC_NOP MATCH_C_ADDI - -#define RISCV_CONST_HIGH_PART(VALUE) \ - (((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1)) -#define RISCV_CONST_LOW_PART(VALUE) ((VALUE) - RISCV_CONST_HIGH_PART (VALUE)) -#define RISCV_PCREL_HIGH_PART(VALUE, PC) RISCV_CONST_HIGH_PART((VALUE) - (PC)) -#define RISCV_PCREL_LOW_PART(VALUE, PC) RISCV_CONST_LOW_PART((VALUE) - (PC)) - -#define RISCV_JUMP_BITS RISCV_BIGIMM_BITS -#define RISCV_JUMP_ALIGN_BITS 1 -#define RISCV_JUMP_ALIGN (1 << RISCV_JUMP_ALIGN_BITS) -#define RISCV_JUMP_REACH ((1ULL << RISCV_JUMP_BITS) * RISCV_JUMP_ALIGN) - -#define RISCV_IMM_BITS 12 -#define RISCV_BIGIMM_BITS (32 - RISCV_IMM_BITS) -#define RISCV_IMM_REACH (1LL << RISCV_IMM_BITS) -#define RISCV_BIGIMM_REACH (1LL << RISCV_BIGIMM_BITS) -#define RISCV_RVC_IMM_REACH (1LL << 6) -#define RISCV_BRANCH_BITS RISCV_IMM_BITS -#define RISCV_BRANCH_ALIGN_BITS RISCV_JUMP_ALIGN_BITS -#define RISCV_BRANCH_ALIGN (1 << RISCV_BRANCH_ALIGN_BITS) -#define RISCV_BRANCH_REACH (RISCV_IMM_REACH * RISCV_BRANCH_ALIGN) - -/* RV fields. */ - -#define OP_MASK_OP 0x7f -#define OP_SH_OP 0 -#define OP_MASK_RS2 0x1f -#define OP_SH_RS2 20 -#define OP_MASK_RS1 0x1f -#define OP_SH_RS1 15 -#define OP_MASK_RS3 0x1f -#define OP_SH_RS3 27 -#define OP_MASK_RD 0x1f -#define OP_SH_RD 7 -#define OP_MASK_SHAMT 0x3f -#define OP_SH_SHAMT 20 -#define OP_MASK_SHAMTW 0x1f -#define OP_SH_SHAMTW 20 -#define OP_MASK_RM 0x7 -#define OP_SH_RM 12 -#define OP_MASK_PRED 0xf -#define OP_SH_PRED 24 -#define OP_MASK_SUCC 0xf -#define OP_SH_SUCC 20 -#define OP_MASK_AQ 0x1 -#define OP_SH_AQ 26 -#define OP_MASK_RL 0x1 -#define OP_SH_RL 25 - -#define OP_MASK_CUSTOM_IMM 0x7f -#define OP_SH_CUSTOM_IMM 25 -#define OP_MASK_CSR 0xfff -#define OP_SH_CSR 20 - -/* RVC fields. */ - -#define OP_MASK_CRS2 0x1f -#define OP_SH_CRS2 2 -#define OP_MASK_CRS1S 0x7 -#define OP_SH_CRS1S 7 -#define OP_MASK_CRS2S 0x7 -#define OP_SH_CRS2S 2 - -/* ABI names for selected x-registers. */ - -#define X_RA 1 -#define X_SP 2 -#define X_GP 3 -#define X_TP 4 -#define X_T0 5 -#define X_T1 6 -#define X_T2 7 -#define X_T3 28 - -#define NGPR 32 -#define NFPR 32 - -/* Replace bits MASK << SHIFT of STRUCT with the equivalent bits in - VALUE << SHIFT. VALUE is evaluated exactly once. */ -#define INSERT_BITS(STRUCT, VALUE, MASK, SHIFT) \ - (STRUCT) = (((STRUCT) & ~((insn_t)(MASK) << (SHIFT))) \ - | ((insn_t)((VALUE) & (MASK)) << (SHIFT))) - -/* Extract bits MASK << SHIFT from STRUCT and shift them right - SHIFT places. */ -#define EXTRACT_BITS(STRUCT, MASK, SHIFT) \ - (((STRUCT) >> (SHIFT)) & (MASK)) - -/* Extract the operand given by FIELD from integer INSN. */ -#define EXTRACT_OPERAND(FIELD, INSN) \ - EXTRACT_BITS ((INSN), OP_MASK_##FIELD, OP_SH_##FIELD) - -/* This structure holds information for a particular instruction. */ - -struct riscv_opcode -{ - /* The name of the instruction. */ - const char *name; - /* The ISA subset name (I, M, A, F, D, Xextension). */ - const char *subset; - /* A string describing the arguments for this instruction. */ - const char *args; - /* The basic opcode for the instruction. When assembling, this - opcode is modified by the arguments to produce the actual opcode - that is used. If pinfo is INSN_MACRO, then this is 0. */ - insn_t match; - /* If pinfo is not INSN_MACRO, then this is a bit mask for the - relevant portions of the opcode when disassembling. If the - actual opcode anded with the match field equals the opcode field, - then we have found the correct instruction. If pinfo is - INSN_MACRO, then this field is the macro identifier. */ - insn_t mask; - /* A function to determine if a word corresponds to this instruction. - Usually, this computes ((word & mask) == match). */ - int (*match_func) (const struct riscv_opcode *op, insn_t word); - /* For a macro, this is INSN_MACRO. Otherwise, it is a collection - of bits describing the instruction, notably any relevant hazard - information. */ - unsigned long pinfo; -}; - -/* Instruction is a simple alias (e.g. "mv" for "addi"). */ -#define INSN_ALIAS 0x00000001 -/* Instruction is actually a macro. It should be ignored by the - disassembler, and requires special treatment by the assembler. */ -#define INSN_MACRO 0xffffffff - -/* This is a list of macro expanded instructions. - - _I appended means immediate - _A appended means address - _AB appended means address with base register - _D appended means 64 bit floating point constant - _S appended means 32 bit floating point constant. */ - -enum -{ - M_LA, - M_LLA, - M_LA_TLS_GD, - M_LA_TLS_IE, - M_LB, - M_LBU, - M_LH, - M_LHU, - M_LW, - M_LWU, - M_LD, - M_SB, - M_SH, - M_SW, - M_SD, - M_FLW, - M_FLD, - M_FLQ, - M_FSW, - M_FSD, - M_FSQ, - M_CALL, - M_J, - M_LI, - M_NUM_MACROS -}; - - -#if 0 || _MSC_VER -extern const char * const riscv_gpr_names_numeric[NGPR]; -extern const char * const riscv_gpr_names_abi[NGPR]; -extern const char * const riscv_fpr_names_numeric[NFPR]; -extern const char * const riscv_fpr_names_abi[NFPR]; -extern struct riscv_opcode *riscv_opcodes; -//extern const struct riscv_opcode riscv_opcodes[]; -#ifdef _MSC_VER -extern int bfd_riscv_num_opcodes; -#endif -#endif -#define NUMOPCODES bfd_riscv_num_opcodes - -#endif /* _RISCV_H_ */ diff --git a/librz/arch/isa_gnu/riscv/riscv_inc.h b/librz/arch/isa_gnu/riscv/riscv_inc.h deleted file mode 100644 index 21c6fec9eea..00000000000 --- a/librz/arch/isa_gnu/riscv/riscv_inc.h +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2024 deroad -// SPDX-License-Identifier: LGPL-3.0-only - -#ifndef RISCV_INC_H -#define RISCV_INC_H - -#include - -int riscv_dis(RzAsm *a, RzAsmOp *rop, const ut8 *buf, ut64 len); - -#endif /* RISCV_INC_H */ \ No newline at end of file diff --git a/librz/arch/meson.build b/librz/arch/meson.build index df6c5b98cbe..430dcd0099a 100644 --- a/librz/arch/meson.build +++ b/librz/arch/meson.build @@ -365,7 +365,6 @@ if get_option('use_gpl') 'arc_gnu', 'cris_gnu', 'lanai_gnu', - 'riscv_gnu', 'vax_gnu', 'z80_gnu', ] @@ -375,7 +374,6 @@ if get_option('use_gpl') 'p_gnu/arch_arc.c', 'p_gnu/arch_cris.c', 'p_gnu/arch_lanai.c', - 'p_gnu/arch_riscv.c', 'p_gnu/arch_vax.c', 'p_gnu/arch_z80.c', ] @@ -392,6 +390,7 @@ if get_option('use_gpl') 'isa_gnu/lanai/lanai-opc.c', # 'isa_gnu/riscv/riscv-opc.c', # 'isa_gnu/riscv/riscv.c', + 'isa_gnu/sparc/sparc-opc.c', 'isa_gnu/vax/vax-dis.c', # 'isa_gnu/z80/expressions.c', # 'isa_gnu/z80/z80.c', diff --git a/librz/arch/p_gnu/analysis/analysis_riscv_gnu.c b/librz/arch/p_gnu/analysis/analysis_riscv_gnu.c deleted file mode 100644 index 35d02f9c8ba..00000000000 --- a/librz/arch/p_gnu/analysis/analysis_riscv_gnu.c +++ /dev/null @@ -1,940 +0,0 @@ -// SPDX-FileCopyrightText: 2015-2019 qnix -// SPDX-License-Identifier: LGPL-3.0-only - -#include -#include -#include -#include -#include -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a)) -#define RISCVARGSMAX (8) -#define RISCVARGSIZE (64) -#define RISCVARGN(x) ((x)->arg[(x)->num++]) - -typedef struct riscv_args { - int num; - char arg[RISCVARGSMAX][RISCVARGSIZE]; -} riscv_args_t; - -static bool init_analysis = false; - -#define is_any(...) _is_any(o->name, __VA_ARGS__, NULL) -static bool _is_any(const char *str, ...) { - char *cur; - va_list va; - va_start(va, str); - while (true) { - cur = va_arg(va, char *); - if (!cur) { - break; - } - if (!strcmp(str, cur)) { - va_end(va); - return true; - } - } - va_end(va); - return false; -} - -static void arg_p2(char *buf, unsigned long val, const char *const *array, size_t size) { - const char *s = val >= size || array[val] ? array[val] : "unknown"; - snprintf(buf, RISCVARGSIZE, "%s", s); -} - -static struct riscv_opcode *get_opcode_analysis(insn_t word) { - struct riscv_opcode *op; - static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1] = { 0 }; - -#define OP_HASH_IDX(i) ((i) & (riscv_insn_length(i) == 2 ? 3 : OP_MASK_OP)) - - if (!init_analysis) { - for (op = riscv_opcodes; op < &riscv_opcodes[NUMOPCODES]; op++) { - if (!riscv_hash[OP_HASH_IDX(op->match)]) { - riscv_hash[OP_HASH_IDX(op->match)] = op; - } - } - init_analysis = true; - } - - return (struct riscv_opcode *)riscv_hash[OP_HASH_IDX(word)]; -} - -/* Print insn arguments for 32/64-bit code. */ -static void get_insn_args_analysis(riscv_args_t *args, const char *d, insn_t l, uint64_t pc) { - int rs1 = (l >> OP_SH_RS1) & OP_MASK_RS1; - int rd = (l >> OP_SH_RD) & OP_MASK_RD; - uint64_t target; - args->num = 0; - - for (; *d != '\0' && args->num < RISCVARGSMAX; d++) { - switch (*d) { - /* Xcustom */ - case '^': - switch (*++d) { - case 'd': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", rd); - break; - case 's': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", rs1); - break; - case 't': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_OPERAND(RS2, l)); - break; - case 'j': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_OPERAND(CUSTOM_IMM, l)); - break; - } - break; - - case 'C': /* RVC */ - switch (*++d) { - case 's': /* RS1 x8-x15 */ - case 'w': /* RS1 x8-x15 */ - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", - riscv_gpr_names[EXTRACT_OPERAND(CRS1S, l) + 8]); - break; - case 't': /* RS2 x8-x15 */ - case 'x': /* RS2 x8-x15 */ - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", - riscv_gpr_names[EXTRACT_OPERAND(CRS2S, l) + 8]); - break; - case 'U': /* RS1, constrained to equal RD in CI format*/ - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", riscv_gpr_names[rd]); - break; - case 'c': /* RS1, constrained to equal sp */ - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", riscv_gpr_names[X_SP]); - break; - case 'V': /* RS2 */ - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", - riscv_gpr_names[EXTRACT_OPERAND(CRS2, l)]); - break; - case 'i': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_RVC_SIMM3(l)); - break; - case 'j': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_RVC_IMM(l)); - break; - case 'k': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_RVC_LW_IMM(l)); - break; - case 'l': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_RVC_LD_IMM(l)); - break; - case 'm': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_RVC_LWSP_IMM(l)); - break; - case 'n': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_RVC_LDSP_IMM(l)); - break; - case 'K': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_RVC_ADDI4SPN_IMM(l)); - break; - case 'L': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_RVC_ADDI16SP_IMM(l)); - break; - case 'M': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_RVC_SWSP_IMM(l)); - break; - case 'N': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_RVC_SDSP_IMM(l)); - break; - case 'p': - target = EXTRACT_RVC_B_IMM(l) + pc; - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%" PFMT64x, (ut64)target); - break; - case 'a': - target = EXTRACT_RVC_J_IMM(l) + pc; - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%" PFMT64x, (ut64)target); - break; - case 'u': - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", - (int)(EXTRACT_RVC_IMM(l) & (RISCV_BIGIMM_REACH - 1))); - break; - case '>': - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", (int)EXTRACT_RVC_IMM(l) & 0x3f); - break; - case '<': - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", (int)EXTRACT_RVC_IMM(l) & 0x1f); - break; - case 'T': /* floating-point RS2 */ - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", - riscv_fpr_names[EXTRACT_OPERAND(CRS2, l)]); - break; - case 'D': /* floating-point RS2 x8-x15 */ - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", - riscv_fpr_names[EXTRACT_OPERAND(CRS2S, l) + 8]); - break; - } - break; - - case ',': - case '(': - case ')': - case '[': - case ']': - break; - case '0': - /* Only print constant 0 if it is the last argument */ - if (!d[1]) { - snprintf(RISCVARGN(args), RISCVARGSIZE, "0"); - } - break; - - case 'b': - case 's': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", riscv_gpr_names[rs1]); - break; - - case 't': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", - riscv_gpr_names[EXTRACT_OPERAND(RS2, l)]); - break; - - case 'u': - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", - (unsigned)EXTRACT_UTYPE_IMM(l) >> RISCV_IMM_BITS); - break; - - case 'm': - arg_p2(RISCVARGN(args), EXTRACT_OPERAND(RM, l), - riscv_rm, ARRAY_SIZE(riscv_rm)); - break; - - case 'P': - arg_p2(RISCVARGN(args), EXTRACT_OPERAND(PRED, l), - riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ)); - break; - - case 'Q': - arg_p2(RISCVARGN(args), EXTRACT_OPERAND(SUCC, l), - riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ)); - break; - case 'o': - case 'j': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_ITYPE_IMM(l)); - break; - case 'q': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_STYPE_IMM(l)); - break; - case 'a': - target = EXTRACT_UJTYPE_IMM(l) + pc; - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%" PFMT64x, (ut64)target); - break; - case 'p': - target = EXTRACT_SBTYPE_IMM(l) + pc; - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%" PFMT64x, (ut64)target); - break; - case 'd': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", riscv_gpr_names[rd]); - break; - case 'z': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", riscv_gpr_names[0]); - break; - case '>': - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", (int)EXTRACT_OPERAND(SHAMT, l)); - break; - case '<': - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", (int)EXTRACT_OPERAND(SHAMTW, l)); - break; - case 'S': - case 'U': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", riscv_fpr_names[rs1]); - break; - case 'T': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", riscv_fpr_names[EXTRACT_OPERAND(RS2, l)]); - break; - case 'D': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", riscv_fpr_names[rd]); - break; - case 'R': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", riscv_fpr_names[EXTRACT_OPERAND(RS3, l)]); - break; - case 'E': { - const char *csr_name = NULL; - unsigned int csr = EXTRACT_OPERAND(CSR, l); - switch (csr) { -#define DECLARE_CSR(name, num) \ - case num: \ - csr_name = #name; \ - break; -#include -#undef DECLARE_CSR - } - if (csr_name) { - snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", csr_name); - } else { - snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", csr); - } - break; - } - case 'Z': - snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", rs1); - break; - default: - /* xgettext:c-format */ - snprintf(RISCVARGN(args), RISCVARGSIZE, "# internal error, undefined modifier (%c)", - *d); - return; - } - } -} - -static const char *arg_n(riscv_args_t *args, int n) { - if (n >= args->num || !strcmp(args->arg[n], "zero")) { - return "0"; - } - return args->arg[n]; -} - -static int riscv_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask) { - const int no_alias = 1; - riscv_args_t args = { 0 }; - ut64 word = 0; - int xlen = analysis->bits; - op->size = 4; - op->addr = addr; - op->type = RZ_ANALYSIS_OP_TYPE_UNK; - - if (len >= sizeof(ut64)) { - word = rz_read_ble64(data, analysis->big_endian); - } else if (len >= sizeof(ut16)) { - word = rz_read_ble16(data, analysis->big_endian); - } else { - op->type = RZ_ANALYSIS_OP_TYPE_ILL; - return -1; - } - - struct riscv_opcode *o = get_opcode_analysis(word); - for (; o && o < &riscv_opcodes[NUMOPCODES]; o++) { - if (!(o->match_func)(o, word)) { - continue; - } - if (no_alias && (o->pinfo & INSN_ALIAS)) { - continue; - } - if (isdigit((ut8)o->subset[0]) && atoi(o->subset) != xlen) { - continue; - } - if (o->name) { - break; - } - op->type = RZ_ANALYSIS_OP_TYPE_ILL; - return -1; - } - if (!o || o >= &riscv_opcodes[NUMOPCODES] || !o->name) { - op->type = RZ_ANALYSIS_OP_TYPE_ILL; - return -1; - } - - if (mask & RZ_ANALYSIS_OP_MASK_DISASM) { - op->mnemonic = rz_str_dup(o->name); - } - - if (o->args) { - const char *name = o->name; - // Test for compressed instruction - if (!strncmp("c.", o->name, 2)) { - name += 2; - op->size = 2; - } -#define ARG(x) (arg_n(&args, (x))) - get_insn_args_analysis(&args, o->args, word, addr); - if (!strcmp(name, "nop")) { - esilprintf(op, ","); - } - // math - else if (!strncmp(name, "addi16sp", 8)) { - esilprintf(op, "%s,sp,+,%s,=", ARG(1), ARG(0)); - if (!strcmp(ARG(0), riscv_gpr_names[X_SP])) { - op->stackop = RZ_ANALYSIS_STACK_INC; - op->stackptr = rz_num_math(NULL, ARG(1)); - } - } else if (!strncmp(name, "addiw", 5)) { - rz_strbuf_appendf(&op->esil, "%s,0xffffffff,%s,&,", ARG(2), ARG(1)); - rz_strbuf_appendf(&op->esil, "+,%s,=,", ARG(0)); - rz_strbuf_appendf(&op->esil, "32,%s,~=", ARG(0)); - if (!strcmp(ARG(0), riscv_gpr_names[X_SP]) && - !strcmp(ARG(1), riscv_gpr_names[X_SP])) { - op->stackop = RZ_ANALYSIS_STACK_INC; - op->stackptr = rz_num_math(NULL, ARG(2)); - } - } else if (!strncmp(name, "addw", 4)) { - esilprintf(op, "0xffffffff,%s,&,", ARG(2)); - rz_strbuf_appendf(&op->esil, "0xffffffff,%s,&,", ARG(1)); - rz_strbuf_appendf(&op->esil, "+,%s,=,", ARG(0)); - rz_strbuf_appendf(&op->esil, "32,%s,~=", ARG(0)); - } else if (!strncmp(name, "add", 3)) { - esilprintf(op, "%s,%s,+,%s,=", ARG(2), ARG(1), ARG(0)); - if (name[3] == 'i' && !strcmp(ARG(0), riscv_gpr_names[X_SP]) && - !strcmp(ARG(1), riscv_gpr_names[X_SP])) { - op->stackop = RZ_ANALYSIS_STACK_INC; - op->stackptr = -(signed)rz_num_math(NULL, ARG(2)); - } - } else if (!strncmp(name, "subw", 4)) { - esilprintf(op, "0xffffffff,%s,&,", ARG(2)); - rz_strbuf_appendf(&op->esil, "0xffffffff,%s,&,", ARG(1)); - rz_strbuf_appendf(&op->esil, "-,%s,=,", ARG(0)); - rz_strbuf_appendf(&op->esil, "32,%s,~=", ARG(0)); - } else if (!strncmp(name, "sub", 3)) { - esilprintf(op, "%s,%s,-,%s,=", ARG(2), ARG(1), ARG(0)); - if (name[3] == 'i' && !strcmp(ARG(0), riscv_gpr_names[X_SP]) && - !strcmp(ARG(1), riscv_gpr_names[X_SP])) { - op->stackop = RZ_ANALYSIS_STACK_INC; - op->stackptr = rz_num_math(NULL, ARG(2)); - } - } else if (!strncmp(name, "mulw", 4)) { - esilprintf(op, "0xffffffff,%s,&,", ARG(2)); - rz_strbuf_appendf(&op->esil, "0xffffffff,%s,&,", ARG(1)); - rz_strbuf_appendf(&op->esil, "*,%s,=,", ARG(0)); - rz_strbuf_appendf(&op->esil, "32,%s,~=", ARG(0)); - } else if (!strncmp(name, "mul", 3)) { - esilprintf(op, "%s,%s,*,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "div", 3)) { - esilprintf(op, "%s,%s,/,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "rem", 3)) { - esilprintf(op, "%s,%s,%%,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "xor", 3)) { - esilprintf(op, "%s,%s,^,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "or", 2)) { - esilprintf(op, "%s,%s,|,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "and", 3)) { - esilprintf(op, "%s,%s,&,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strcmp(name, "auipc")) { - esilprintf(op, "%s000,$$,+,%s,=", ARG(1), ARG(0)); - } else if (!strncmp(name, "sll", 3)) { - esilprintf(op, "%s,%s,<<,%s,=", ARG(2), ARG(1), ARG(0)); - if (name[3] == 'w' || !strncmp(name, "slliw", 5)) { - rz_strbuf_appendf(&op->esil, ",32,%s,~=", ARG(0)); - } - } else if (!strcmp(name, "srlw") || !strcmp(name, "srliw")) { - esilprintf(op, "%s,0xffffffff,%s,&,>>,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "srl", 3)) { - esilprintf(op, "%s,%s,>>,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strcmp(name, "sraiw")) { - esilprintf(op, "%s,%s,>>>>,%s,=,", ARG(2), ARG(1), ARG(0)); - rz_strbuf_appendf(&op->esil, "%s,64,-,%s,~=", ARG(2), ARG(0)); - } else if (!strncmp(name, "sra", 3)) { - esilprintf(op, "%s,%s,>>>>,%s,=", ARG(2), ARG(1), ARG(0)); - } - // assigns - else if (!strcmp(name, "mv")) { - esilprintf(op, "%s,%s,=", ARG(1), ARG(0)); - } else if (!strcmp(name, "li")) { - esilprintf(op, "%s,%s,=", ARG(1), ARG(0)); - } else if (!strcmp(name, "lui")) { - esilprintf(op, "%s000,%s,=", ARG(1), ARG(0)); - if (analysis->bits == 64) { - rz_strbuf_appendf(&op->esil, ",32,%s,~=", ARG(0)); - } - } - // csr instrs - // rd, rs1, CSR - else if (!strncmp(name, "csrrw", 5)) { - // Writes rs1 into CSR, places the old value in rd - esilprintf(op, "%s,0,+,%s,%s,=,%s,=", ARG(1), ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "csrrs", 5)) { - // Ors rs1 with CSR, places old value in rd - esilprintf(op, "%s,0,+,%s,%s,|=,%s,=", ARG(1), ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "csrrc", 5)) { - // Ands the inverse of rs1 with CSR, places old value in rd - esilprintf(op, "%s,0,+,%s,1,+,0,-,%s,&=,%s,=", ARG(1), ARG(1), ARG(2), ARG(0)); - } - // stores - else if (!strcmp(name, "sd") || !strcmp(name, "sdsp")) { - esilprintf(op, "%s,%s,%s,+,=[8]", ARG(0), ARG(2), ARG(1)); - } else if (!strcmp(name, "sw") || !strcmp(name, "swsp")) { - esilprintf(op, "%s,%s,%s,+,=[4]", ARG(0), ARG(2), ARG(1)); - } else if (!strcmp(name, "sh") || !strcmp(name, "shsp")) { - esilprintf(op, "%s,%s,%s,+,=[2]", ARG(0), ARG(2), ARG(1)); - } else if (!strcmp(name, "sb") || !strcmp(name, "sbsp")) { - esilprintf(op, "%s,%s,%s,+,=[1]", ARG(0), ARG(2), ARG(1)); - } else if (!strcmp(name, "fsq") || !strcmp(name, "fsqsp")) { - esilprintf(op, "%s,%s,+,[16],%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strcmp(name, "fsd") || !strcmp(name, "fsdsp")) { - esilprintf(op, "%s,%s,%s,+,=[8]", ARG(0), ARG(2), ARG(1)); - } else if (!strcmp(name, "fsw") || !strcmp(name, "fswsp")) { - esilprintf(op, "%s,%s,%s,+,=[4]", ARG(0), ARG(2), ARG(1)); - } else if (!strcmp(name, "fsh") || !strcmp(name, "fshsp")) { - esilprintf(op, "%s,%s,%s,+,=[2]", ARG(0), ARG(2), ARG(1)); - } else if (!strcmp(name, "fsb") || !strcmp(name, "fsbsp")) { - esilprintf(op, "%s,%s,%s,+,=[1]", ARG(0), ARG(2), ARG(1)); - } - // loads - else if (!strcmp(name, "ld") || !strcmp(name, "ldsp")) { - esilprintf(op, "%s,%s,+,[8],%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strcmp(name, "lw") || !strcmp(name, "lwu") || !strcmp(name, "lwsp")) { - esilprintf(op, "%s,%s,+,[4],%s,=", ARG(2), ARG(1), ARG(0)); - if ((analysis->bits == 64) && strcmp(name, "lwu")) { - rz_strbuf_appendf(&op->esil, ",32,%s,~=", ARG(0)); - } - } else if (!strcmp(name, "lh") || !strcmp(name, "lhu") || !strcmp(name, "lhsp")) { - esilprintf(op, "%s,%s,+,[2],%s,=", ARG(2), ARG(1), ARG(0)); - if (strcmp(name, "lwu")) { - rz_strbuf_appendf(&op->esil, ",16,%s,~=", ARG(0)); - } - } else if (!strcmp(name, "lb") || !strcmp(name, "lbu") || !strcmp(name, "lbsp")) { - esilprintf(op, "%s,%s,+,[1],%s,=", ARG(2), ARG(1), ARG(0)); - if (strcmp(name, "lbu")) { - rz_strbuf_appendf(&op->esil, ",8,%s,~=", ARG(0)); - } - } else if (!strcmp(name, "flq") || !strcmp(name, "flqsp")) { - esilprintf(op, "%s,%s,+,[16],%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strcmp(name, "fld") || !strcmp(name, "fldsp")) { - esilprintf(op, "%s,%s,+,[8],%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strcmp(name, "flw") || !strcmp(name, "flwsp")) { - esilprintf(op, "%s,%s,+,[4],%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strcmp(name, "flh") || !strcmp(name, "flhsp")) { - esilprintf(op, "%s,%s,+,[2],%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strcmp(name, "flb") || !strcmp(name, "flbsp")) { - esilprintf(op, "%s,%s,+,[1],%s,=", ARG(2), ARG(1), ARG(0)); - } - // jumps - else if (!strcmp(name, "jalr")) { - if (strcmp(ARG(0), "0")) { - esilprintf(op, "%s,%s,+,pc,=,%d,$$,+,%s,=", ARG(2), ARG(1), op->size, ARG(0)); - } else { - esilprintf(op, "%s,%s,+,pc,=", ARG(2), ARG(1)); - } - } else if (!strcmp(name, "jal")) { - if (strcmp(ARG(0), "0")) { - if (args.num == 1) { - esilprintf(op, "%d,$$,+,ra,=,%s,pc,=", op->size, ARG(0)); - } else { - esilprintf(op, "%d,$$,+,%s,=,%s,pc,=", op->size, ARG(0), ARG(1)); - } - } else { - esilprintf(op, "%s,pc,=", ARG(1)); - } - } else if (!strcmp(name, "jr") || !strcmp(name, "j")) { - esilprintf(op, "%s,pc,=", ARG(0)); - } else if (!strcmp(name, "ecall") || !strcmp(name, "ebreak")) { - esilprintf(op, "TRAP"); - } - // Branches & cmps - else if (!strcmp(name, "beq")) { - esilprintf(op, "%s,%s,==,$z,?{,%s,pc,=,},", ARG(1), ARG(0), ARG(2)); - } else if (!strcmp(name, "bne")) { - esilprintf(op, "%s,%s,==,$z,!,?{,%s,pc,=,},", ARG(1), ARG(0), ARG(2)); - } else if (!strcmp(name, "ble") || !strcmp(name, "bleu")) { - esilprintf(op, "%s,%s,<=,?{,%s,pc,=,},", ARG(1), ARG(0), ARG(2)); - } else if (!strcmp(name, "blt") || !strcmp(name, "bltu")) { - esilprintf(op, "%s,%s,<,?{,%s,pc,=,},", ARG(1), ARG(0), ARG(2)); - } else if (!strcmp(name, "bge") || !strcmp(name, "bgeu")) { - esilprintf(op, "%s,%s,>=,?{,%s,pc,=,},", ARG(1), ARG(0), ARG(2)); - } else if (!strcmp(name, "bgt") || !strcmp(name, "bgtu")) { - esilprintf(op, "%s,%s,>,?{,%s,pc,=,},", ARG(1), ARG(0), ARG(2)); - } else if (!strcmp(name, "beqz")) { - esilprintf(op, "%s,0,==,$z,?{,%s,pc,=,},", ARG(0), ARG(1)); - } else if (!strcmp(name, "bnez")) { - esilprintf(op, "%s,0,==,$z,!,?{,%s,pc,=,},", ARG(0), ARG(1)); - } else if (!strcmp(name, "blez")) { - esilprintf(op, "%s,0,<=,?{,%s,pc,=,},", ARG(0), ARG(1)); - } else if (!strcmp(name, "bltz")) { - esilprintf(op, "%s,0,<,?{,%s,pc,=,},", ARG(0), ARG(1)); - } else if (!strcmp(name, "bgez")) { - esilprintf(op, "%s,0,>=,?{,%s,pc,=,},", ARG(0), ARG(1)); - } else if (!strcmp(name, "bgtz")) { - esilprintf(op, "%s,0,>,?{,%s,pc,=,},", ARG(0), ARG(1)); - } else if (!strncmp(name, "seq", 3)) { - esilprintf(op, "%s,%s,==,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "sne", 3)) { - esilprintf(op, "%s,%s,!=,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "sle", 3)) { - esilprintf(op, "%s,%s,<=,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "slt", 3)) { - esilprintf(op, "%s,%s,<,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "sge", 3)) { - esilprintf(op, "%s,%s,>=,%s,=", ARG(2), ARG(1), ARG(0)); - } else if (!strncmp(name, "sgt", 3)) { - esilprintf(op, "%s,%s,>,%s,=", ARG(2), ARG(1), ARG(0)); - } -#undef ARG - } - - // branch/jumps/calls/rets - if (is_any("jal")) { - // decide whether it's jump or call - int rd = (word >> OP_SH_RD) & OP_MASK_RD; - op->type = (rd == 0) ? RZ_ANALYSIS_OP_TYPE_JMP : RZ_ANALYSIS_OP_TYPE_CALL; - op->jump = EXTRACT_UJTYPE_IMM(word) + addr; - op->fail = addr + op->size; - } else if (is_any("c.jal")) { - op->type = RZ_ANALYSIS_OP_TYPE_CALL; - op->jump = EXTRACT_RVC_IMM(word) + addr; - op->fail = addr + op->size; - } else if (is_any("jr")) { - op->type = RZ_ANALYSIS_OP_TYPE_JMP; - } else if (is_any("c.j", "jump")) { - op->type = RZ_ANALYSIS_OP_TYPE_JMP; - op->jump = EXTRACT_RVC_J_IMM(word) + addr; - } else if (is_any("jalr")) { - // decide whether it's ret or call - int rd = (word >> OP_SH_RD) & OP_MASK_RD; - op->type = (rd == 0) ? RZ_ANALYSIS_OP_TYPE_RET : RZ_ANALYSIS_OP_TYPE_UCALL; - if (rd != 0) { - op->val = EXTRACT_ITYPE_IMM(word); - } - } else if (is_any("c.ret")) { - op->type = RZ_ANALYSIS_OP_TYPE_RET; - } else if (is_any("c.jalr")) { - op->type = RZ_ANALYSIS_OP_TYPE_UCALL; - } else if (is_any("c.jr")) { - op->type = RZ_ANALYSIS_OP_TYPE_RET; - } else if (is_any("beqz", "beq", "blez", "bgez", "ble", - "bleu", "bge", "bgeu", "bltz", "bgtz", "blt", "bltu", - "bgt", "bgtu", "bnez", "bne")) { - op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - op->jump = EXTRACT_SBTYPE_IMM(word) + addr; - op->fail = addr + op->size; - } else if (is_any("c.beqz", "c.bnez")) { - op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - op->jump = EXTRACT_RVC_B_IMM(word) + addr; - op->fail = addr + op->size; - // math - } else if (is_any("c.addi", "c.addiw")) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - op->val = EXTRACT_RVC_IMM(word); - } else if (is_any("addi", "addiw")) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - op->val = EXTRACT_ITYPE_IMM(word); - } else if (is_any("c.addi4spn")) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - op->val = EXTRACT_RVC_ADDI4SPN_IMM(word); - } else if (is_any("c.addi16sp")) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - op->val = EXTRACT_RVC_ADDI16SP_IMM(word); - } else if (is_any("addw", "add", "c.addw", "c.add")) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - } else if (is_any("auipc")) { - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - op->val = EXTRACT_UTYPE_IMM(word); - } else if (is_any("c.mv", "csrrw", "csrrc", "csrrs")) { - op->type = RZ_ANALYSIS_OP_TYPE_MOV; - } else if (is_any("subi", "subw", "sub", "c.sub", "c.subw")) { - op->type = RZ_ANALYSIS_OP_TYPE_SUB; - } else if (is_any("xori", "xor", "c.xor")) { - op->type = RZ_ANALYSIS_OP_TYPE_XOR; - } else if (is_any("andi", "and", "c.andi", "c.and")) { - op->type = RZ_ANALYSIS_OP_TYPE_AND; - } else if (is_any("ori", "or", "c.or")) { - op->type = RZ_ANALYSIS_OP_TYPE_OR; - } else if (is_any("not")) { - op->type = RZ_ANALYSIS_OP_TYPE_NOT; - } else if (is_any("c.nop")) { - op->type = RZ_ANALYSIS_OP_TYPE_NOP; - } else if (is_any("mul", "mulh", "mulhu", "mulhsu", "mulw")) { - op->type = RZ_ANALYSIS_OP_TYPE_MUL; - } else if (is_any("div", "divu", "divw", "divuw")) { - op->type = RZ_ANALYSIS_OP_TYPE_DIV; - } else if (is_any("sll", "slli", "sllw", "slliw", "c.slli")) { - op->type = RZ_ANALYSIS_OP_TYPE_SHL; - } else if (is_any("srl", "srlw", "srliw", "c.srli")) { - op->type = RZ_ANALYSIS_OP_TYPE_SHR; - } else if (is_any("sra", "srai", "sraiw", "c.srai")) { - op->type = RZ_ANALYSIS_OP_TYPE_SAR; - // memory - } else if (is_any("sd", "sb", "sh", "sw", "c.sd", "c.sw", - "c.swsp", "c.sdsp")) { - op->type = RZ_ANALYSIS_OP_TYPE_STORE; - } else if (is_any("ld", "lw", "lwu", "lb", "lbu", "lh", - "lhu", "la", "lla", "c.ld", "c.lw", "c.lwsp")) { - op->type = RZ_ANALYSIS_OP_TYPE_LOAD; - } else if (is_any("lui")) { - op->type = RZ_ANALYSIS_OP_TYPE_MOV; - op->val = EXTRACT_UTYPE_IMM(word); - } else if (is_any("c.lui")) { - op->type = RZ_ANALYSIS_OP_TYPE_MOV; - op->val = EXTRACT_RVC_IMM(word); - } else if (is_any("li")) { - op->type = RZ_ANALYSIS_OP_TYPE_MOV; - op->val = EXTRACT_ITYPE_IMM(word); - } else if (is_any("c.li")) { - op->type = RZ_ANALYSIS_OP_TYPE_MOV; - op->val = EXTRACT_RVC_IMM(word); - } - if (mask & RZ_ANALYSIS_OP_MASK_VAL && args.num) { - op->dst = RZ_NEW0(RzAnalysisValue); - char *argf = rz_str_dup(o->args); - const char *comma = NULL; - int dst_idx = 0, src_idx; - if (op->type == RZ_ANALYSIS_OP_TYPE_STORE) { - comma = rz_str_rchr(argf, argf + strlen(argf), ','); - if (comma) { - *(char *)comma++ = 0; - if (strchr(comma, '(')) { - dst_idx = args.num = args.num - 2; - } else { - dst_idx = args.num = args.num - 1; - } - } - } else { - comma = strtok(argf, ","); - dst_idx = 0; - } - if (comma && strchr(comma, '(')) { - op->dst->type = RZ_ANALYSIS_VAL_MEM; - op->dst->delta = (st64)rz_num_get(NULL, args.arg[dst_idx++]); - op->dst->reg = rz_reg_get(analysis->reg, args.arg[dst_idx], -1); - src_idx = op->type == RZ_ANALYSIS_OP_TYPE_STORE ? 0 : 2; - } else if (isdigit(args.arg[dst_idx][0])) { - op->dst->type = RZ_ANALYSIS_VAL_IMM; - op->dst->imm = rz_num_get(NULL, args.arg[dst_idx]); - src_idx = op->type == RZ_ANALYSIS_OP_TYPE_STORE ? 0 : 1; - } else { - op->dst->type = RZ_ANALYSIS_VAL_REG; - op->dst->reg = rz_reg_get(analysis->reg, args.arg[dst_idx], -1); - src_idx = op->type == RZ_ANALYSIS_OP_TYPE_STORE ? 0 : 1; - } - - comma = op->type == RZ_ANALYSIS_OP_TYPE_STORE - ? strtok(argf, ",") - : strtok(NULL, ","); - int i; - for (i = 0; src_idx < args.num; i++, src_idx++) { - op->src[i] = RZ_NEW0(RzAnalysisValue); - if (comma && strchr(comma, '(')) { - op->src[i]->type = RZ_ANALYSIS_VAL_MEM; - op->src[i]->delta = (st64)rz_num_get(NULL, args.arg[src_idx]); - op->src[i]->reg = rz_reg_get(analysis->reg, args.arg[src_idx + 1], -1); - src_idx++; - } else if (isalpha(args.arg[src_idx][0])) { - op->src[i]->type = RZ_ANALYSIS_VAL_REG; - op->src[i]->reg = rz_reg_get(analysis->reg, args.arg[src_idx], -1); - } else { - op->src[i]->type = RZ_ANALYSIS_VAL_IMM; - op->src[i]->imm = rz_num_get(NULL, args.arg[src_idx]); - } - comma = strtok(NULL, ","); - } - free(argf); - } - return op->size; -} - -static char *get_reg_profile(RzAnalysis *analysis) { - const char *p = NULL; - switch (analysis->bits) { - case 32: - p = - "=PC pc\n" - "=A0 a0\n" - "=A1 a1\n" - "=A2 a2\n" - "=A3 a3\n" - "=A4 a4\n" - "=A5 a5\n" - "=A6 a6\n" - "=A7 a7\n" - "=R0 a0\n" - "=R1 a1\n" - "=SP sp\n" // ABI: stack pointer - "=LR ra\n" // ABI: return address - "=BP s0\n" // ABI: frame pointer - "=SN a7\n" // ABI: syscall numer - "gpr pc .32 0 0\n" - // RV32I regs (ABI names) - // From user-Level ISA Specification, section 2.1 - // "zero" has been left out as it ignores writes and always reads as zero - "gpr ra .32 4 0\n" // =x1 - "gpr sp .32 8 0\n" // =x2 - "gpr gp .32 12 0\n" // =x3 - "gpr tp .32 16 0\n" // =x4 - "gpr t0 .32 20 0\n" // =x5 - "gpr t1 .32 24 0\n" // =x6 - "gpr t2 .32 28 0\n" // =x7 - "gpr s0 .32 32 0\n" // =x8 - "gpr s1 .32 36 0\n" // =x9 - "gpr a0 .32 40 0\n" // =x10 - "gpr a1 .32 44 0\n" // =x11 - "gpr a2 .32 48 0\n" // =x12 - "gpr a3 .32 52 0\n" // =x13 - "gpr a4 .32 56 0\n" // =x14 - "gpr a5 .32 60 0\n" // =x15 - "gpr a6 .32 64 0\n" // =x16 - "gpr a7 .32 68 0\n" // =x17 - "gpr s2 .32 72 0\n" // =x18 - "gpr s3 .32 76 0\n" // =x19 - "gpr s4 .32 80 0\n" // =x20 - "gpr s5 .32 84 0\n" // =x21 - "gpr s6 .32 88 0\n" // =x22 - "gpr s7 .32 92 0\n" // =x23 - "gpr s8 .32 96 0\n" // =x24 - "gpr s9 .32 100 0\n" // =x25 - "gpr s10 .32 104 0\n" // =x26 - "gpr s11 .32 108 0\n" // =x27 - "gpr t3 .32 112 0\n" // =x28 - "gpr t4 .32 116 0\n" // =x29 - "gpr t5 .32 120 0\n" // =x30 - "gpr t6 .32 124 0\n" // =x31 - // RV32F/D regs (ABI names) - // From user-Level ISA Specification, section 8.1 and 9.1 - "fpu ft0 .64 128 0\n" // =f0 - "fpu ft1 .64 136 0\n" // =f1 - "fpu ft2 .64 144 0\n" // =f2 - "fpu ft3 .64 152 0\n" // =f3 - "fpu ft4 .64 160 0\n" // =f4 - "fpu ft5 .64 168 0\n" // =f5 - "fpu ft6 .64 176 0\n" // =f6 - "fpu ft7 .64 184 0\n" // =f7 - "fpu fs0 .64 192 0\n" // =f8 - "fpu fs1 .64 200 0\n" // =f9 - "fpu fa0 .64 208 0\n" // =f10 - "fpu fa1 .64 216 0\n" // =f11 - "fpu fa2 .64 224 0\n" // =f12 - "fpu fa3 .64 232 0\n" // =f13 - "fpu fa4 .64 240 0\n" // =f14 - "fpu fa5 .64 248 0\n" // =f15 - "fpu fa6 .64 256 0\n" // =f16 - "fpu fa7 .64 264 0\n" // =f17 - "fpu fs2 .64 272 0\n" // =f18 - "fpu fs3 .64 280 0\n" // =f19 - "fpu fs4 .64 288 0\n" // =f20 - "fpu fs5 .64 296 0\n" // =f21 - "fpu fs6 .64 304 0\n" // =f22 - "fpu fs7 .64 312 0\n" // =f23 - "fpu fs8 .64 320 0\n" // =f24 - "fpu fs9 .64 328 0\n" // =f25 - "fpu fs10 .64 336 0\n" // =f26 - "fpu fs11 .64 344 0\n" // =f27 - "fpu ft8 .64 352 0\n" // =f28 - "fpu ft9 .64 360 0\n" // =f29 - "fpu ft10 .64 368 0\n" // =f30 - "fpu ft11 .64 376 0\n" // =f31 - "fpu fcsr .32 384 0\n" - "flg nx .1 3072 0\n" - "flg uf .1 3073 0\n" - "flg of .1 3074 0\n" - "flg dz .1 3075 0\n" - "flg nv .1 3076 0\n" - "flg frm .3 3077 0\n"; - - break; - case 64: - p = - "=PC pc\n" - "=SP sp\n" // ABI: stack pointer - "=LR ra\n" // ABI: return address - "=BP s0\n" // ABI: frame pointer - "=A0 a0\n" - "=A1 a1\n" - "=A2 a2\n" - "=A3 a3\n" - "=A4 a4\n" - "=A5 a5\n" - "=A6 a6\n" - "=A7 a7\n" - "=R0 a0\n" - "=R1 a1\n" - "=SN a7\n" // ABI: syscall numer - "gpr pc .64 0 0\n" - // RV64I regs (ABI names) - // From user-Level ISA Specification, section 2.1 and 4.1 - // "zero" has been left out as it ignores writes and always reads as zero - "gpr ra .64 8 0\n" // =x1 - "gpr sp .64 16 0\n" // =x2 - "gpr gp .64 24 0\n" // =x3 - "gpr tp .64 32 0\n" // =x4 - "gpr t0 .64 40 0\n" // =x5 - "gpr t1 .64 48 0\n" // =x6 - "gpr t2 .64 56 0\n" // =x7 - "gpr s0 .64 64 0\n" // =x8 - "gpr s1 .64 72 0\n" // =x9 - "gpr a0 .64 80 0\n" // =x10 - "gpr a1 .64 88 0\n" // =x11 - "gpr a2 .64 96 0\n" // =x12 - "gpr a3 .64 104 0\n" // =x13 - "gpr a4 .64 112 0\n" // =x14 - "gpr a5 .64 120 0\n" // =x15 - "gpr a6 .64 128 0\n" // =x16 - "gpr a7 .64 136 0\n" // =x17 - "gpr s2 .64 144 0\n" // =x18 - "gpr s3 .64 152 0\n" // =x19 - "gpr s4 .64 160 0\n" // =x20 - "gpr s5 .64 168 0\n" // =x21 - "gpr s6 .64 176 0\n" // =x22 - "gpr s7 .64 184 0\n" // =x23 - "gpr s8 .64 192 0\n" // =x24 - "gpr s9 .64 200 0\n" // =x25 - "gpr s10 .64 208 0\n" // =x26 - "gpr s11 .64 216 0\n" // =x27 - "gpr t3 .64 224 0\n" // =x28 - "gpr t4 .64 232 0\n" // =x29 - "gpr t5 .64 240 0\n" // =x30 - "gpr t6 .64 248 0\n" // =x31 - // RV64F/D regs (ABI names) - "fpu ft0 .64 256 0\n" // =f0 - "fpu ft1 .64 264 0\n" // =f1 - "fpu ft2 .64 272 0\n" // =f2 - "fpu ft3 .64 280 0\n" // =f3 - "fpu ft4 .64 288 0\n" // =f4 - "fpu ft5 .64 296 0\n" // =f5 - "fpu ft6 .64 304 0\n" // =f6 - "fpu ft7 .64 312 0\n" // =f7 - "fpu fs0 .64 320 0\n" // =f8 - "fpu fs1 .64 328 0\n" // =f9 - "fpu fa0 .64 336 0\n" // =f10 - "fpu fa1 .64 344 0\n" // =f11 - "fpu fa2 .64 352 0\n" // =f12 - "fpu fa3 .64 360 0\n" // =f13 - "fpu fa4 .64 368 0\n" // =f14 - "fpu fa5 .64 376 0\n" // =f15 - "fpu fa6 .64 384 0\n" // =f16 - "fpu fa7 .64 392 0\n" // =f17 - "fpu fs2 .64 400 0\n" // =f18 - "fpu fs3 .64 408 0\n" // =f19 - "fpu fs4 .64 416 0\n" // =f20 - "fpu fs5 .64 424 0\n" // =f21 - "fpu fs6 .64 432 0\n" // =f22 - "fpu fs7 .64 440 0\n" // =f23 - "fpu fs8 .64 448 0\n" // =f24 - "fpu fs9 .64 456 0\n" // =f25 - "fpu fs10 .64 464 0\n" // =f26 - "fpu fs11 .64 472 0\n" // =f27 - "fpu ft8 .64 480 0\n" // =f28 - "fpu ft9 .64 488 0\n" // =f29 - "fpu ft10 .64 496 0\n" // =f30 - "fpu ft11 .64 504 0\n" // =f31 - "fpu fcsr .32 512 0\n" - "flg nx .1 4096 0\n" - "flg uf .1 4097 0\n" - "flg of .1 4098 0\n" - "flg dz .1 4099 0\n" - "flg nv .1 4100 0\n" - "flg frm .3 4101 0\n"; - - break; - } - return rz_str_dup(p); -} - -static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) { - bool is_64_bits = a && a->bits == 64; - - switch (query) { - case RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE: - return is_64_bits ? 4 : 2; - case RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE: - return 6; - case RZ_ANALYSIS_ARCHINFO_TEXT_ALIGN: - /* fall-thru */ - case RZ_ANALYSIS_ARCHINFO_DATA_ALIGN: - return 2; - case RZ_ANALYSIS_ARCHINFO_CAN_USE_POINTERS: - return true; - default: - return -1; - } -} - -RzAnalysisPlugin rz_analysis_plugin_riscv_gnu = { - .name = "riscv", - .desc = "RISC-V analysis plugin", - .license = "LGPL", - .arch = "riscv", - .bits = 32 | 64, - .archinfo = archinfo, - .op = &riscv_op, - .get_reg_profile = &get_reg_profile, - .esil = true, -}; diff --git a/librz/arch/p_gnu/arch_riscv.c b/librz/arch/p_gnu/arch_riscv.c deleted file mode 100644 index 8e464619ea3..00000000000 --- a/librz/arch/p_gnu/arch_riscv.c +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2024 RizinOrg -// SPDX-FileCopyrightText: 2024 deroad -// SPDX-License-Identifier: LGPL-3.0-only - -#include - -#include "../isa_gnu/riscv/riscv-opc.c" -#include -#include "../isa_gnu/riscv/riscv.c" - -#include "analysis/analysis_riscv_gnu.c" -#include "asm/asm_riscv_gnu.c" -#include "parse/parse_riscv_gnu.c" - -RZ_ARCH_WITH_PARSE_PLUGIN_DEFINE_DEPRECATED(riscv_gnu); diff --git a/librz/arch/p_gnu/asm/asm_riscv_gnu.c b/librz/arch/p_gnu/asm/asm_riscv_gnu.c deleted file mode 100644 index 130f8cd90a7..00000000000 --- a/librz/arch/p_gnu/asm/asm_riscv_gnu.c +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-FileCopyrightText: 2015-2021 qnix -// SPDX-License-Identifier: LGPL-3.0-only - -#include -#include -#include -#include - -static int riscv_gnu_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { - return op->size = riscv_dis(a, op, buf, len); -} - -RzAsmPlugin rz_asm_plugin_riscv_gnu = { - .name = "riscv", - .desc = "RISC-V disassembler", - .arch = "riscv", - .bits = 32 | 64, - .endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG, - .license = "GPL3", - .disassemble = &riscv_gnu_disassemble, -}; diff --git a/librz/arch/p_gnu/parse/parse_riscv_gnu.c b/librz/arch/p_gnu/parse/parse_riscv_gnu.c deleted file mode 100644 index 9933ecc4154..00000000000 --- a/librz/arch/p_gnu/parse/parse_riscv_gnu.c +++ /dev/null @@ -1,226 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Aswin C (officialcjunior) -// SPDX-License-Identifier: LGPL-3.0-only - -#include -#include -#include -#include - -static int replace(int argc, const char *argv[], char *newstr) { -#define MAXPSEUDOOPS 10 - int i, j, k, d; - char ch; - struct { - int narg; - char *op; - char *str; - int args[MAXPSEUDOOPS]; - } ops[] = { - { 0, "add", "# = # + #", { 1, 2, 3 } }, - { 0, "addi", "# = # + #", { 1, 2, 3 } }, - { 0, "and", "# = # & #", { 1, 2, 3 } }, - { 0, "andi", "# = # & #", { 1, 2, 3 } }, - { 0, "beq", "if (# == #) goto #", { 1, 2, 3 } }, - { 0, "bleu", "if (unsigned)# <= # goto #", { 1, 2, 3 } }, - { 0, "bltu", "if (unsigned)# < # goto #", { 1, 2, 3 } }, - { 0, "blt", "if (# < #) goto #", { 1, 2, 3 } }, - { 0, "beqz", "if (# == 0) goto #", { 1, 2 } }, - { 0, "bne", "if (# != #) goto #", { 1, 2, 3 } }, - { 0, "bnez", "if (# != 0) goto #", { 1, 2 } }, - { 0, "bgez", "if (# >= 0) goto #", { 1, 2 } }, - { 0, "bgtz", "if (# > 0) goto #", { 1, 2 } }, - { 0, "fld", "# = #", { 1, 2 } }, - { 0, "j", "jmp #", { 1 } }, - { 0, "jr", "jmp #", { 1 } }, - { 0, "jalr", "jmp #", { 1 } }, - { 0, "jal", "jmp #", { 1 } }, - { 0, "ld", "# = (double)[#]", { 1, 2 } }, - { 0, "li", "# = #", { 1, 2 } }, - { 0, "lh", "# = [#]", { 1, 2 } }, - { 0, "lui", "# = #", { 1, 2 } }, - { 0, "lbu", "# = (unsigned)[#]", { 1, 2 } }, - { 0, "lhu", "# = (unsigned)[#]", { 1, 2 } }, - { 0, "lw", "# = [#]", { 1, 2 } }, - { 0, "mv", "# = #", { 1, 2 } }, - { 0, "or", "# = # | #", { 1, 2, 3 } }, - { 0, "sd", "[#] = (double)#", { 2, 1 } }, - { 0, "sw", "[#] = #", { 2, 1 } }, - { 0, "sb", "[#] = #", { 2, 1 } }, - { 0, "sh", "[#] = #", { 2, 1 } }, - { 0, "sub", "# = # - #", { 1, 2, 3 } }, - { 0, NULL } - }; - if (!newstr) { - return false; - } - - for (i = 0; ops[i].op; i++) { - if (ops[i].narg) { - if (argc - 1 != ops[i].narg) { - continue; - } - } - if (!strcmp(ops[i].op, argv[0])) { - if (newstr) { - d = 0; - j = 0; - ch = ops[i].str[j]; - for (j = 0, k = 0; ch != '\0'; j++, k++) { - ch = ops[i].str[j]; - if (ch == '#') { - if (d >= MAXPSEUDOOPS) { - // XXX Shouldn't ever happen... - continue; - } - int idx = ops[i].args[d]; - d++; - if (idx <= 0) { - // XXX Shouldn't ever happen... - continue; - } - const char *w = argv[idx]; - if (w) { - strcpy(newstr + k, w); - k += strlen(w) - 1; - } - } else { - newstr[k] = ch; - } - } - newstr[k] = '\0'; - } - rz_str_replace_char(newstr, '{', '('); - rz_str_replace_char(newstr, '}', ')'); - return true; - } - } - - /* TODO: this is slow */ - newstr[0] = '\0'; - for (i = 0; i < argc; i++) { - strcat(newstr, argv[i]); - strcat(newstr, (!i || i == argc - 1) ? " " : ","); - } - - rz_str_replace_char(newstr, '{', '('); - rz_str_replace_char(newstr, '}', ')'); - return false; -} - -static bool parse(RzParse *p, const char *data, RzStrBuf *sb) { - char w0[256], w1[256], w2[256], w3[256]; - char str[1024] = { 0 }; - int i, len = strlen(data), n; - char *buf, *ptr, *optr, *num; - - if (len >= sizeof(w0)) { - return false; - } - // malloc can be slow here :? - if (!(buf = malloc(len + 1))) { - return false; - } - memcpy(buf, data, len + 1); - if (*buf) { - *w0 = *w1 = *w2 = *w3 = '\0'; - ptr = strchr(buf, ' '); - if (!ptr) { - ptr = strchr(buf, '\t'); - } - if (ptr) { - *ptr = '\0'; - for (++ptr; *ptr == ' '; ptr++) { - ; - } - strncpy(w0, buf, sizeof(w0) - 1); - strncpy(w1, ptr, sizeof(w1) - 1); - - optr = ptr; - if (*ptr == '(') { - ptr = strchr(ptr + 1, ')'); - } - if (ptr && *ptr == '[') { - ptr = strchr(ptr + 1, ']'); - } - if (ptr && *ptr == '{') { - ptr = strchr(ptr + 1, '}'); - } - if (!ptr) { - eprintf("Unbalanced bracket\n"); - free(buf); - return false; - } - ptr = strchr(ptr, ','); - if (ptr) { - *ptr = '\0'; - for (++ptr; *ptr == ' '; ptr++) { - ; - } - strncpy(w1, optr, sizeof(w1) - 1); - strncpy(w2, ptr, sizeof(w2) - 1); - optr = ptr; - ptr = strchr(ptr, ','); - if (ptr) { - *ptr = '\0'; - for (++ptr; *ptr == ' '; ptr++) { - ; - } - strncpy(w2, optr, sizeof(w2) - 1); - strncpy(w3, ptr, sizeof(w3) - 1); - } - } - ptr = strchr(buf, '('); - if (ptr) { - *ptr = 0; - num = (char *)rz_str_lchr(buf, ' '); - if (!num) { - num = (char *)rz_str_lchr(buf, ','); - } - if (num) { - n = atoi(num + 1); - *ptr = '['; - rz_str_cpy(num + 1, ptr); - ptr = (char *)rz_str_lchr(buf, ']'); - if (n && ptr) { - char *rest = rz_str_dup(ptr + 1); - size_t dist = len + 1 - (ptr - buf); - if (n > 0) { - snprintf(ptr, dist, "+%d]%s", n, rest); - } else { - snprintf(ptr, dist, "%d]%s", n, rest); - } - free(rest); - } - } else { - *ptr = '['; - } - } - } - { - const char *wa[] = { w0, w1, w2, w3 }; - int nw = 0; - for (i = 0; i < 4; i++) { - if (wa[i][0]) { - nw++; - } - } - replace(nw, wa, str); - } - } - { - char *s = rz_str_dup(str); - s = rz_str_replace(s, "+ -", "- ", 1); - s = rz_str_replace(s, "- -", "+ ", 1); - rz_strf(str, "%s", s); - free(s); - } - free(buf); - rz_strbuf_set(sb, str); - return true; -} - -RzParsePlugin rz_parse_plugin_riscv_gnu_pseudo = { - .name = "riscv.pseudo", - .desc = "riscv pseudo syntax", - .parse = parse, -}; diff --git a/test/db/analysis/riscv b/test/db/analysis/riscv index 5ffe90624ea..a9f3127f49d 100644 --- a/test/db/analysis/riscv +++ b/test/db/analysis/riscv @@ -54,10 +54,4043 @@ e asm.pseudo=1 pd 5 EOF EXPECT=< 0x00010c86 07e10702 vle32.v v2, (a5) ; arg6 +| :: 0x00010c8a c107 addi a5, a5, 0x10 ; arg6 +| :: 0x00010c8c d7001102 vadd.vv v1, v1, v2 +| `==< 0x00010c90 e39bd7ff bne a5, t4, 0x10c86 +| : 0x00010c94 f32620c2 csrr a3, vlenb +| : 0x00010c98 8a96 add a3, a3, sp ; arg4 +| : 0x00010c9a a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x00010c9e 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x00010ca2 d730005e vmv.v.i v1, 0 +| : 0x00010ca6 1147 li a4, 4 +| .--> 0x00010ca8 d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg6 +| :: 0x00010cac 07e10602 vle32.v v2, (a3) ; arg4 +| :: 0x00010cb0 13982700 slli a6, a5, 2 ; arg6 +| :: 0x00010cb4 1d8f sub a4, a4, a5 ; arg6 +| :: 0x00010cb6 c296 add a3, a3, a6 ; arg4 +| :: 0x00010cb8 d7802002 vadd.vv v1, v2, v1 +| `==< 0x00010cbc 75f7 bnez a4, 0x10ca8 +| : 0x00010cbe d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 +| : 0x00010cc2 57610042 vmv.s.x v2, zero +| : 0x00010cc6 f32720c2 csrr a5, vlenb +| : 0x00010cca d7201102 vredsum.vs v1, v1, v2 +| : 0x00010cce c107 addi a5, a5, 0x10 ; arg6 +| : 0x00010cd0 37070080 lui a4, 0x80000 +| : 0x00010cd4 3308f100 add a6, sp, a5 ; arg6 +| : 0x00010cd8 5741075e vmv.v.x v2, a4 +| : 0x00010cdc c286 mv a3, a6 +| : 0x00010cde 1147 li a4, 4 +| : 0x00010ce0 d7281042 vmv.x.s a7, v1 +| .--> 0x00010ce4 d777670c vsetvli a5, a4, e8, mf4, ta, ma ; arg6 +| :: 0x00010ce8 27e10602 vse32.v v2, (a3) ; arg4 +| :: 0x00010cec 1d8f sub a4, a4, a5 ; arg6 +| :: 0x00010cee 8a07 slli a5, a5, 2 +| :: 0x00010cf0 be96 add a3, a3, a5 ; arg6 +| `==< 0x00010cf2 6dfb bnez a4, 0x10ce4 +| : 0x00010cf4 577002cd vsetivli zero, 4, e0x20, m1, ta, ma +| : 0x00010cf8 87600802 vle32.v v1, (a6) +| .--> 0x00010cfc 07610502 vle32.v v2, (a0) ; arg1 +| :: 0x00010d00 4105 addi a0, a0, 0x10 ; arg1 +| :: 0x00010d02 d700111e vmax.vv v1, v1, v2 +| `==< 0x00010d06 e39baefe bne t4, a0, 0x10cfc +| : 0x00010d0a a7600802 vse32.v v1, (a6) +| : 0x00010d0e d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 +| : 0x00010d12 d7400e5e vmv.v.x v1, t3 +| : 0x00010d16 c286 mv a3, a6 +| : 0x00010d18 1147 li a4, 4 +| : 0x00010d1a 5731109e vmv1r.v v2, v1 +| .--> 0x00010d1e d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg6 +| :: 0x00010d22 07e20602 vle32.v v4, (a3) ; arg4 +| :: 0x00010d26 13952700 slli a0, a5, 2 ; arg6 +| :: 0x00010d2a 1d8f sub a4, a4, a5 ; arg6 +| :: 0x00010d2c aa96 add a3, a3, a0 ; arg4 +| :: 0x00010d2e 5701411e vmax.vv v2, v4, v2 +| `==< 0x00010d32 75f7 bnez a4, 0x10d1e +| : 0x00010d34 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x00010d38 b7070080 lui a5, 0x80000 +| : 0x00010d3c 57e20742 vmv.s.x v4, a5 +| : 0x00010d40 fd37 addiw a5, a5, -1 ; arg6 +| : 0x00010d42 5721221e vredmax.vs v2, v2, v4 +| : 0x00010d46 57c2075e vmv.v.x v4, a5 +| : 0x00010d4a f32720c2 csrr a5, vlenb +| : 0x00010d4e 93870702 addi a5, a5, 0x20 ; arg6 +| : 0x00010d52 3305f100 add a0, sp, a5 ; arg6 +| : 0x00010d56 aa86 mv a3, a0 +| : 0x00010d58 1147 li a4, 4 +| : 0x00010d5a 572e2042 vmv.x.s t3, v2 +| .--> 0x00010d5e d777670c vsetvli a5, a4, e8, mf4, ta, ma ; arg6 +| :: 0x00010d62 27e20602 vse32.v v4, (a3) ; arg4 +| :: 0x00010d66 1d8f sub a4, a4, a5 ; arg6 +| :: 0x00010d68 8a07 slli a5, a5, 2 +| :: 0x00010d6a be96 add a3, a3, a5 ; arg6 +| `==< 0x00010d6c 6dfb bnez a4, 0x10d5e +| : 0x00010d6e 577002cd vsetivli zero, 4, e0x20, m1, ta, ma +| : 0x00010d72 07610502 vle32.v v2, (a0) +| .--> 0x00010d76 07620302 vle32.v v4, (t1) +| :: 0x00010d7a 4103 addi t1, t1, 0x10 +| :: 0x00010d7c 57012216 vmin.vv v2, v2, v4 +| `==< 0x00010d80 e39b6efe bne t4, t1, 0x10d76 +| : 0x00010d84 27610502 vse32.v v2, (a0) +| : 0x00010d88 aa86 mv a3, a0 +| : 0x00010d8a 1147 li a4, 4 +| .--> 0x00010d8c d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg6 +| :: 0x00010d90 07e10602 vle32.v v2, (a3) ; arg4 +| :: 0x00010d94 13952700 slli a0, a5, 2 ; arg6 +| :: 0x00010d98 1d8f sub a4, a4, a5 ; arg6 +| :: 0x00010d9a aa96 add a3, a3, a0 ; arg4 +| :: 0x00010d9c d7802016 vmin.vv v1, v2, v1 +| `==< 0x00010da0 75f7 bnez a4, 0x10d8c +| : 0x00010da2 b7070080 lui a5, 0x80000 +| : 0x00010da6 577002cd vsetivli zero, 4, e0x20, m1, ta, ma +| : 0x00010daa fd37 addiw a5, a5, -1 ; arg6 +| : 0x00010dac 57e20742 vmv.s.x v4, a5 +| : 0x00010db0 57b10f5e vmv.v.i v2, -1 +| : 0x00010db4 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x00010db8 d7201216 vredmin.vs v1, v1, v4 +| : 0x00010dbc 0563 lui t1, 1 +| : 0x00010dbe 2e93 add t1, t1, a1 ; arg2 +| : 0x00010dc0 2e85 mv a0, a1 +| : 0x00010dc2 ae87 mv a5, a1 +| : 0x00010dc4 d7261042 vmv.x.s a3, v1 +| : 0x00010dc8 577002cd vsetivli zero, 4, e0x20, m1, ta, ma +| .--> 0x00010dcc 87e00702 vle32.v v1, (a5) ; arg6 +| :: 0x00010dd0 c107 addi a5, a5, 0x10 ; arg6 +| :: 0x00010dd2 57812026 vand.vv v2, v2, v1 +| `==< 0x00010dd6 e39b67fe bne a5, t1, 0x10dcc +| : 0x00010dda f32720c2 csrr a5, vlenb +| : 0x00010dde 93870703 addi a5, a5, 0x30 ; arg6 +| : 0x00010de2 3308f100 add a6, sp, a5 ; arg6 +| : 0x00010de6 27610802 vse32.v v2, (a6) +| : 0x00010dea 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x00010dee d7b00f5e vmv.v.i v1, -1 +| : 0x00010df2 1147 li a4, 4 +| .--> 0x00010df4 d7770709 vsetvli a5, a4, e0x20, m1, tu, ma ; arg6 +| :: 0x00010df8 07610802 vle32.v v2, (a6) +| :: 0x00010dfc 939e2700 slli t4, a5, 2 ; arg6 +| :: 0x00010e00 1d8f sub a4, a4, a5 ; arg6 +| :: 0x00010e02 7698 add a6, a6, t4 +| :: 0x00010e04 d7802026 vand.vv v1, v2, v1 +| `==< 0x00010e08 75f7 bnez a4, 0x10df4 +| : 0x00010e0a 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x00010e0e fd57 li a5, -1 +| : 0x00010e10 57e20742 vmv.s.x v4, a5 +| : 0x00010e14 5731309e vmv1r.v v2, v3 +| : 0x00010e18 d7201206 vredand.vs v1, v1, v4 +| : 0x00010e1c 57271042 vmv.x.s a4, v1 +| : 0x00010e20 577002cd vsetivli zero, 4, e0x20, m1, ta, ma +| .--> 0x00010e24 87e00502 vle32.v v1, (a1) ; arg2 +| :: 0x00010e28 c105 addi a1, a1, 0x10 ; arg2 +| :: 0x00010e2a 5781202a vor.vv v2, v2, v1 +| `==< 0x00010e2e e39b65fe bne a1, t1, 0x10e24 +| : 0x00010e32 f32720c2 csrr a5, vlenb +| : 0x00010e36 93870704 addi a5, a5, 0x40 ; arg6 +| : 0x00010e3a 3308f100 add a6, sp, a5 ; arg6 +| : 0x00010e3e 27610802 vse32.v v2, (a6) +| : 0x00010e42 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x00010e46 d730005e vmv.v.i v1, 0 +| : 0x00010e4a 9145 li a1, 4 +| .--> 0x00010e4c d7f70509 vsetvli a5, a1, e0x20, m1, tu, ma ; arg6 +| :: 0x00010e50 07610802 vle32.v v2, (a6) +| :: 0x00010e54 939e2700 slli t4, a5, 2 ; arg6 +| :: 0x00010e58 9d8d sub a1, a1, a5 ; arg6 +| :: 0x00010e5a 7698 add a6, a6, t4 +| :: 0x00010e5c d780202a vor.vv v1, v2, v1 +| `==< 0x00010e60 f5f5 bnez a1, 0x10e4c +| : 0x00010e62 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x00010e66 57620042 vmv.s.x v4, zero +| : 0x00010e6a 5731309e vmv1r.v v2, v3 +| : 0x00010e6e d720120a vredor.vs v1, v1, v4 +| : 0x00010e72 d7271042 vmv.x.s a5, v1 +| : 0x00010e76 577002cd vsetivli zero, 4, e0x20, m1, ta, ma +| .--> 0x00010e7a 87600502 vle32.v v1, (a0) +| :: 0x00010e7e 4105 addi a0, a0, 0x10 +| :: 0x00010e80 5781202e vxor.vv v2, v2, v1 +| `==< 0x00010e84 e31b65fe bne a0, t1, 0x10e7a +| : 0x00010e88 f32520c2 csrr a1, vlenb +| : 0x00010e8c 93850505 addi a1, a1, 0x50 ; arg2 +| : 0x00010e90 3308b100 add a6, sp, a1 ; arg2 +| : 0x00010e94 27610802 vse32.v v2, (a6) +| : 0x00010e98 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x00010e9c d730005e vmv.v.i v1, 0 +| : 0x00010ea0 9145 li a1, 4 +| .--> 0x00010ea2 57f50509 vsetvli a0, a1, e0x20, m1, tu, ma ; arg2 +| :: 0x00010ea6 07610802 vle32.v v2, (a6) +| :: 0x00010eaa 13132500 slli t1, a0, 2 +| :: 0x00010eae 898d sub a1, a1, a0 ; arg2 +| :: 0x00010eb0 1a98 add a6, a6, t1 +| :: 0x00010eb2 d780202e vxor.vv v1, v2, v1 +| `==< 0x00010eb6 f5f5 bnez a1, 0x10ea2 +| : 0x00010eb8 577002cd vsetivli zero, 4, e0x20, m1, ta, ma +| : 0x00010ebc d7610042 vmv.s.x v3, zero +| : 0x00010ec0 5731005e vmv.v.i v2, 0 +| : 0x00010ec4 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x00010ec8 d7a0110e vredxor.vs v1, v1, v3 +| : 0x00010ecc 856f lui t6, 1 +| : 0x00010ece b29f add t6, t6, a2 ; arg3 +| : 0x00010ed0 328f mv t5, a2 +| : 0x00010ed2 b285 mv a1, a2 +| : 0x00010ed4 57281042 vmv.x.s a6, v1 +| : 0x00010ed8 577002cd vsetivli zero, 4, e0x20, m1, ta, ma +| .--> 0x00010edc 87e00502 vle32.v v1, (a1) ; arg2 +| :: 0x00010ee0 c105 addi a1, a1, 0x10 ; arg2 +| :: 0x00010ee2 57912002 vfadd.vv v2, v2, v1 +| `==< 0x00010ee6 e39bbffe bne t6, a1, 0x10edc +| : 0x00010eea f32520c2 csrr a1, vlenb +| : 0x00010eee 93850506 addi a1, a1, 0x60 ; arg2 +| : 0x00010ef2 3303b100 add t1, sp, a1 ; arg2 +| : 0x00010ef6 27610302 vse32.v v2, (t1) +| : 0x00010efa 530400f0 fmv.w.x fs0, zero +| : 0x00010efe 9145 li a1, 4 +| .--> 0x00010f00 57f5650c vsetvli a0, a1, e8, mf4, ta, ma ; arg2 +| :: 0x00010f04 07610302 vle32.v v2, (t1) +| :: 0x00010f08 57f000cd vsetivli zero, 1, e0x20, m1, ta, ma +| :: 0x00010f0c d7500442 vfmv.s.f v1, fs0 +| :: 0x00010f10 5770050d vsetvli zero, a0, e0x20, m1, ta, ma +| :: 0x00010f14 931e2500 slli t4, a0, 2 +| :: 0x00010f18 898d sub a1, a1, a0 ; arg2 +| :: 0x00010f1a d790200e vfredosum.vs v1, v2, v1 +| :: 0x00010f1e 7693 add t1, t1, t4 +| :: 0x00010f20 57141042 vfmv.f.s fs0, v1 +| `==< 0x00010f24 f1fd bnez a1, 0x10f00 +| : 0x00010f26 cd62 lui t0, 0x13 ; 0x13000 ; "P\U00000005\U00000001" +| : 0x00010f28 07a78202 flw fa4, 0x28(t0) +| : 0x00010f2c d775000d vsetvli a1, zero, e0x20, m1, ta, ma ; arg2 +| : 0x00010f30 732520c2 csrr a0, vlenb +| : 0x00010f34 13050507 addi a0, a0, 0x70 +| : 0x00010f38 d750075e vfmv.v.f v1, fa4 +| : 0x00010f3c b30ea100 add t4, sp, a0 +| : 0x00010f40 7683 mv t1, t4 +| : 0x00010f42 9145 li a1, 4 +| .--> 0x00010f44 57f5650c vsetvli a0, a1, e8, mf4, ta, ma ; arg2 +| :: 0x00010f48 a7600302 vse32.v v1, (t1) +| :: 0x00010f4c 898d sub a1, a1, a0 ; arg2 +| :: 0x00010f4e 0a05 slli a0, a0, 2 +| :: 0x00010f50 2a93 add t1, t1, a0 +| `==< 0x00010f52 edf9 bnez a1, 0x10f44 +| : 0x00010f54 577002cd vsetivli zero, 4, e0x20, m1, ta, ma +| : 0x00010f58 87e00e02 vle32.v v1, (t4) +| : 0x00010f5c 3285 mv a0, a2 +| .--> 0x00010f5e 07610502 vle32.v v2, (a0) +| :: 0x00010f62 4105 addi a0, a0, 0x10 +| :: 0x00010f64 5710116e vmflt.vv v0, v1, v2 +| :: 0x00010f68 d700115c vmerge.vvm v1, v1, v2, v0 +| `==< 0x00010f6c e399affe bne t6, a0, 0x10f5e +| : 0x00010f70 a7e00e02 vse32.v v1, (t4) +| : 0x00010f74 5776000d vsetvli a2, zero, e0x20, m1, ta, ma ; arg3 +| : 0x00010f78 d7d0075e vfmv.v.f v1, fa5 +| : 0x00010f7c f685 mv a1, t4 +| : 0x00010f7e 1146 li a2, 4 +| : 0x00010f80 5731109e vmv1r.v v2, v1 +| .--> 0x00010f84 57750609 vsetvli a0, a2, e0x20, m1, tu, ma ; arg3 +| :: 0x00010f88 87e10502 vle32.v v3, (a1) ; arg2 +| :: 0x00010f8c 13132500 slli t1, a0, 2 +| :: 0x00010f90 098e sub a2, a2, a0 ; arg3 +| :: 0x00010f92 9a95 add a1, a1, t1 ; arg2 +| :: 0x00010f94 5711311a vfmax.vv v2, v3, v2 +| `==< 0x00010f98 75f6 bnez a2, 0x10f84 +| : 0x00010f9a 07a78202 flw fa4, 0x28(t0) +| : 0x00010f9e 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x00010fa2 cd64 lui s1, 0x13 ; 0x13000 ; "P\U00000005\U00000001" +| : 0x00010fa4 57520742 vfmv.s.f v4, fa4 +| : 0x00010fa8 87a7c402 flw fa5, 0x2c(s1) +| : 0x00010fac 5711221e vfredmax.vs v2, v2, v4 +| : 0x00010fb0 732620c2 csrr a2, vlenb +| : 0x00010fb4 13060608 addi a2, a2, 0x80 ; arg3 +| : 0x00010fb8 d7d1075e vfmv.v.f v3, fa5 +| : 0x00010fbc 0a96 add a2, a2, sp ; arg3 +| : 0x00010fbe 3283 mv t1, a2 +| : 0x00010fc0 9145 li a1, 4 +| : 0x00010fc2 d7142042 vfmv.f.s fs1, v2 +| .--> 0x00010fc6 57f5650c vsetvli a0, a1, e8, mf4, ta, ma ; arg2 +| :: 0x00010fca a7610302 vse32.v v3, (t1) +| :: 0x00010fce 898d sub a1, a1, a0 ; arg2 +| :: 0x00010fd0 0a05 slli a0, a0, 2 +| :: 0x00010fd2 2a93 add t1, t1, a0 +| `==< 0x00010fd4 edf9 bnez a1, 0x10fc6 +| : 0x00010fd6 577002cd vsetivli zero, 4, e0x20, m1, ta, ma +| : 0x00010fda 07610602 vle32.v v2, (a2) ; arg3 +| .--> 0x00010fde 87610f02 vle32.v v3, (t5) +| :: 0x00010fe2 410f addi t5, t5, 0x10 +| :: 0x00010fe4 5710316e vmflt.vv v0, v3, v2 +| :: 0x00010fe8 5781215c vmerge.vvm v2, v2, v3, v0 +| `==< 0x00010fec e319ffff bne t5, t6, 0x10fde +| : 0x00010ff0 27610602 vse32.v v2, (a2) ; arg3 +| : 0x00010ff4 9145 li a1, 4 +| .--> 0x00010ff6 57f50509 vsetvli a0, a1, e0x20, m1, tu, ma ; arg2 +| :: 0x00010ffa 07610602 vle32.v v2, (a2) ; arg3 +| :: 0x00010ffe 13132500 slli t1, a0, 2 +| :: 0x00011002 898d sub a1, a1, a0 ; arg2 +| :: 0x00011004 1a96 add a2, a2, t1 ; arg3 +| :: 0x00011006 d7101112 vfmin.vv v1, v1, v2 +| `==< 0x0001100a f5f5 bnez a1, 0x10ff6 +| : 0x0001100c 4965 lui a0, 0x12 +| : 0x0001100e 7286 mv a2, t3 +| : 0x00011010 c685 mv a1, a7 +| : 0x00011012 1305859c addi a0, a0, -0x638 +| : 0x00011016 a7008102 vs1r.v v1, (sp) +| : 0x0001101a eff06fd8 jal sym.imp.printf ; int printf(const char *format) +| : 0x0001101e 87608102 vl1re32.v v1, (sp) +| : 0x00011022 87a7c402 flw fa5, 0x2c(s1) +| : 0x00011026 5774000d vsetvli s0, zero, e0x20, m1, ta, ma +| : 0x0001102a 53870442 fcvt.d.s fa4, fs1 +| : 0x0001102e 57d10742 vfmv.s.f v2, fa5 +| : 0x00011032 f32220c2 csrr t0, vlenb +| : 0x00011036 d7101116 vfredmin.vs v1, v1, v2 +| : 0x0001103a 530607e2 fmv.x.d a2, fa4 +| : 0x0001103e 53070442 fcvt.d.s fa4, fs0 +| : 0x00011042 1691 add sp, sp, t0 +| : 0x00011044 ea70 ld ra, 0xb8(sp) +| : 0x00011046 4a74 ld s0, 0xb0(sp) +| : 0x00011048 aa74 ld s1, 0xa8(sp) +| : 0x0001104a d7171042 vfmv.f.s fa5, v1 +| : 0x0001104e 6a24 fld fs0, 0x98(sp) +| : 0x00011050 d3870742 fcvt.d.s fa5, fa5 +| : 0x00011054 ca24 fld fs1, 0x90(sp) +| : 0x00011056 d30507e2 fmv.x.d a1, fa4 +| : 0x0001105a d38607e2 fmv.x.d a3, fa5 +| : 0x0001105e 4965 lui a0, 0x12 +| : 0x00011060 130505a0 addi a0, a0, -0x600 +| : 0x00011064 2961 addi sp, sp, 0xc0 +\ `=< 0x00011066 6ff0afd3 j sym.imp.printf +EOF +RUN + + +NAME=Vector instructions: vector sign injection +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x0001156e d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011572 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x00011576 07e10502 vle32.v v2, (a1) ; arg2 +| : 0x0001157a 13982700 slli a6, a5, 2 ; arg6 +| : 0x0001157e 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011580 c298 add a7, a7, a6 ; arg8 +| : 0x00011582 c295 add a1, a1, a6 ; arg2 +| : 0x00011584 d7101122 vfsgnj.vv v1, v1, v2 +| : 0x00011588 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x0001158c c296 add a3, a3, a6 ; arg4 +| `=< 0x0001158e 65f3 bnez a4, 0x1156e +| 0x00011590 b286 mv a3, a2 +| 0x00011592 aa85 mv a1, a0 +| 0x00011594 13070040 li a4, 0x400 +| .-> 0x00011598 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x0001159c 87e00502 vle32.v v1, (a1) ; arg2 +| : 0x000115a0 13982700 slli a6, a5, 2 ; arg6 +| : 0x000115a4 1d8f sub a4, a4, a5 ; arg6 +| : 0x000115a6 c295 add a1, a1, a6 ; arg2 +| : 0x000115a8 d790102a vfabs.v v1, v1 +| : 0x000115ac a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000115b0 c296 add a3, a3, a6 ; arg4 +| `=< 0x000115b2 7df3 bnez a4, 0x11598 +| 0x000115b4 87a7c180 flw fa5, -0x7f4(gp) +| 0x000115b8 d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 +| 0x000115bc 13070040 li a4, 0x400 +| 0x000115c0 57d1075e vfmv.v.f v2, fa5 +| .-> 0x000115c4 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000115c8 87600502 vle32.v v1, (a0) ; arg1 +| : 0x000115cc 93962700 slli a3, a5, 2 ; arg6 +| : 0x000115d0 1d8f sub a4, a4, a5 ; arg6 +| : 0x000115d2 3695 add a0, a0, a3 ; arg1 +| : 0x000115d4 d7101122 vfsgnj.vv v1, v1, v2 +| : 0x000115d8 a7600602 vse32.v v1, (a2) ; arg3 +| : 0x000115dc 3696 add a2, a2, a3 ; arg3 +| `=< 0x000115de 7df3 bnez a4, 0x115c4 +| 0x000115e0 8280 ret +EOF +RUN + + +NAME=Vector instructions: vector saturating +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x0001126e d777f70c vsetvli a5, a4, e0x10, mf2, ta, ma ; arg6 +| : 0x00011272 87520302 vle16.v v5, (t1) +| : 0x00011276 07d20802 vle16.v v4, (a7) ; arg8 +| : 0x0001127a 13981700 slli a6, a5, 1 ; arg6 +| : 0x0001127e 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011280 c298 add a7, a7, a6 ; arg8 +| : 0x00011282 4293 add t1, t1, a6 +| : 0x00011284 d72052c6 vwadd.vv v1, v5, v4 +| : 0x00011288 5770000d vsetvli zero, zero, e0x20, m1, ta, ma +| : 0x0001128c d780111e vmax.vv v1, v1, v3 +| : 0x00011290 d7001116 vmin.vv v1, v1, v2 +| : 0x00011294 5770f00c vsetvli zero, zero, e0x10, mf2, ta, ma +| : 0x00011298 d73010b2 vnsrl.wi v1, v1, 0 +| : 0x0001129c a7d00602 vse16.v v1, (a3) ; arg4 +| : 0x000112a0 c296 add a3, a3, a6 ; arg4 +| `=< 0x000112a2 71f7 bnez a4, 0x1126e +| 0x000112a4 13070040 li a4, 0x400 +| .-> 0x000112a8 d777f70c vsetvli a5, a4, e0x10, mf2, ta, ma ; arg6 +| : 0x000112ac 87520502 vle16.v v5, (a0) ; arg1 +| : 0x000112b0 07d20502 vle16.v v4, (a1) ; arg2 +| : 0x000112b4 93961700 slli a3, a5, 1 ; arg6 +| : 0x000112b8 1d8f sub a4, a4, a5 ; arg6 +| : 0x000112ba 3695 add a0, a0, a3 ; arg1 +| : 0x000112bc b695 add a1, a1, a3 ; arg2 +| : 0x000112be d72052ce vwsub.vv v1, v5, v4 +| : 0x000112c2 5770000d vsetvli zero, zero, e0x20, m1, ta, ma +| : 0x000112c6 d780111e vmax.vv v1, v1, v3 +| : 0x000112ca d7001116 vmin.vv v1, v1, v2 +| : 0x000112ce 5770f00c vsetvli zero, zero, e0x10, mf2, ta, ma +| : 0x000112d2 d73010b2 vnsrl.wi v1, v1, 0 +| : 0x000112d6 a7500602 vse16.v v1, (a2) ; arg3 +| : 0x000112da 3696 add a2, a2, a3 ; arg3 +| `=< 0x000112dc 71f7 bnez a4, 0x112a8 +| 0x000112de 8280 ret +EOF +RUN + + +NAME=Vector instructions: vector unsigned operations +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x0001190a d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x0001190e 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x00011912 87600302 vle32.v v1, (t1) +| : 0x00011916 13982700 slli a6, a5, 2 ; arg6 +| : 0x0001191a 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001191c c298 add a7, a7, a6 ; arg8 +| : 0x0001191e 4293 add t1, t1, a6 +| : 0x00011920 d700111a vmaxu.vv v1, v1, v2 +| : 0x00011924 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x00011928 c296 add a3, a3, a6 ; arg4 +| `=< 0x0001192a 65f3 bnez a4, 0x1190a +| 0x0001192c 13070040 li a4, 0x400 +| .-> 0x00011930 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011934 07e10502 vle32.v v2, (a1) ; arg2 +| : 0x00011938 87600502 vle32.v v1, (a0) ; arg1 +| : 0x0001193c 93962700 slli a3, a5, 2 ; arg6 +| : 0x00011940 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011942 b695 add a1, a1, a3 ; arg2 +| : 0x00011944 3695 add a0, a0, a3 ; arg1 +| : 0x00011946 d7001112 vminu.vv v1, v1, v2 +| : 0x0001194a a7600602 vse32.v v1, (a2) ; arg3 +| : 0x0001194e 3696 add a2, a2, a3 ; arg3 +| `=< 0x00011950 65f3 bnez a4, 0x11930 +| 0x00011952 8280 ret +EOF +RUN + + +NAME=Vector instructions: vector minmax +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x000118b6 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000118ba 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x000118be 87600302 vle32.v v1, (t1) +| : 0x000118c2 13982700 slli a6, a5, 2 ; arg6 +| : 0x000118c6 1d8f sub a4, a4, a5 ; arg6 +| : 0x000118c8 c298 add a7, a7, a6 ; arg8 +| : 0x000118ca 4293 add t1, t1, a6 +| : 0x000118cc d700111e vmax.vv v1, v1, v2 +| : 0x000118d0 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000118d4 c296 add a3, a3, a6 ; arg4 +| `=< 0x000118d6 65f3 bnez a4, 0x118b6 +| 0x000118d8 13070040 li a4, 0x400 +| .-> 0x000118dc d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000118e0 07e10502 vle32.v v2, (a1) ; arg2 +| : 0x000118e4 87600502 vle32.v v1, (a0) ; arg1 +| : 0x000118e8 93962700 slli a3, a5, 2 ; arg6 +| : 0x000118ec 1d8f sub a4, a4, a5 ; arg6 +| : 0x000118ee b695 add a1, a1, a3 ; arg2 +| : 0x000118f0 3695 add a0, a0, a3 ; arg1 +| : 0x000118f2 d7001116 vmin.vv v1, v1, v2 +| : 0x000118f6 a7600602 vse32.v v1, (a2) ; arg3 +| : 0x000118fa 3696 add a2, a2, a3 ; arg3 +| `=< 0x000118fc 65f3 bnez a4, 0x118dc +| 0x000118fe 8280 ret +EOF +RUN + + +NAME=Vector instructions: vector fused multiply-add +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x00011422 d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 +| : 0x00011426 87600302 vle32.v v1, (t1) +| : 0x0001142a 87610e02 vle32.v v3, (t3) +| : 0x0001142e 07e10e02 vle32.v v2, (t4) +| : 0x00011432 13972700 slli a4, a5, 2 ; arg6 +| : 0x00011436 3308f840 sub a6, a6, a5 ; arg6 +| : 0x0001143a 3a93 add t1, t1, a4 +| : 0x0001143c 3a9e add t3, t3, a4 +| : 0x0001143e ba9e add t4, t4, a4 +| : 0x00011440 d79021a2 vfmadd.vv v1, v3, v2 +| : 0x00011444 a7e00802 vse32.v v1, (a7) ; arg8 +| : 0x00011448 ba98 add a7, a7, a4 ; arg8 +| `=< 0x0001144a e31c08fc bnez a6, 0x11422 +| 0x0001144e b688 mv a7, a3 +| 0x00011450 b28e mv t4, a2 +| 0x00011452 2e8e mv t3, a1 +| 0x00011454 2a83 mv t1, a0 +| 0x00011456 13080040 li a6, 0x400 +| .-> 0x0001145a d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 +| : 0x0001145e 87610302 vle32.v v3, (t1) +| : 0x00011462 87600e02 vle32.v v1, (t3) +| : 0x00011466 07e10e02 vle32.v v2, (t4) +| : 0x0001146a 13972700 slli a4, a5, 2 ; arg6 +| : 0x0001146e 3308f840 sub a6, a6, a5 ; arg6 +| : 0x00011472 3a93 add t1, t1, a4 +| : 0x00011474 3a9e add t3, t3, a4 +| : 0x00011476 ba9e add t4, t4, a4 +| : 0x00011478 d79021aa vfmsub.vv v1, v3, v2 +| : 0x0001147c a7e00802 vse32.v v1, (a7) ; arg8 +| : 0x00011480 ba98 add a7, a7, a4 ; arg8 +| `=< 0x00011482 e31c08fc bnez a6, 0x1145a +| 0x00011486 13080040 li a6, 0x400 +| .-> 0x0001148a d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 +| : 0x0001148e 07610602 vle32.v v2, (a2) ; arg3 +| : 0x00011492 87610502 vle32.v v3, (a0) ; arg1 +| : 0x00011496 87e00502 vle32.v v1, (a1) ; arg2 +| : 0x0001149a 13972700 slli a4, a5, 2 ; arg6 +| : 0x0001149e 3308f840 sub a6, a6, a5 ; arg6 +| : 0x000114a2 3a96 add a2, a2, a4 ; arg3 +| : 0x000114a4 3a95 add a0, a0, a4 ; arg1 +| : 0x000114a6 ba95 add a1, a1, a4 ; arg2 +| : 0x000114a8 d79021ae vfnmsub.vv v1, v3, v2 +| : 0x000114ac a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000114b0 ba96 add a3, a3, a4 ; arg4 +| `=< 0x000114b2 e31c08fc bnez a6, 0x1148a +| 0x000114b6 8280 ret +EOF +RUN + + +NAME=Vector instructions: vector float operations +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x0001136c d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011370 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x00011374 07610302 vle32.v v2, (t1) +| : 0x00011378 13982700 slli a6, a5, 2 ; arg6 +| : 0x0001137c 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001137e c298 add a7, a7, a6 ; arg8 +| : 0x00011380 4293 add t1, t1, a6 +| : 0x00011382 d7101102 vfadd.vv v1, v1, v2 +| : 0x00011386 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x0001138a c296 add a3, a3, a6 ; arg4 +| `=< 0x0001138c 65f3 bnez a4, 0x1136c +| 0x0001138e b286 mv a3, a2 +| 0x00011390 2e83 mv t1, a1 +| 0x00011392 aa88 mv a7, a0 +| 0x00011394 13070040 li a4, 0x400 +| .-> 0x00011398 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x0001139c 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x000113a0 07610302 vle32.v v2, (t1) +| : 0x000113a4 13982700 slli a6, a5, 2 ; arg6 +| : 0x000113a8 1d8f sub a4, a4, a5 ; arg6 +| : 0x000113aa c298 add a7, a7, a6 ; arg8 +| : 0x000113ac 4293 add t1, t1, a6 +| : 0x000113ae d710110a vfsub.vv v1, v1, v2 +| : 0x000113b2 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000113b6 c296 add a3, a3, a6 ; arg4 +| `=< 0x000113b8 65f3 bnez a4, 0x11398 +| 0x000113ba b286 mv a3, a2 +| 0x000113bc aa88 mv a7, a0 +| 0x000113be 13070040 li a4, 0x400 +| .-> 0x000113c2 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000113c6 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x000113ca 07e10502 vle32.v v2, (a1) ; arg2 +| : 0x000113ce 13982700 slli a6, a5, 2 ; arg6 +| : 0x000113d2 1d8f sub a4, a4, a5 ; arg6 +| : 0x000113d4 c298 add a7, a7, a6 ; arg8 +| : 0x000113d6 c295 add a1, a1, a6 ; arg2 +| : 0x000113d8 d7101182 vfdiv.vv v1, v1, v2 +| : 0x000113dc a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000113e0 c296 add a3, a3, a6 ; arg4 +| `=< 0x000113e2 65f3 bnez a4, 0x113c2 +| 0x000113e4 d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 +| 0x000113e8 5731005e vmv.v.i v2, 0 +| 0x000113ec 13070040 li a4, 0x400 +| .-> 0x000113f0 d7770705 vsetvli a5, a4, e0x20, m1, ta, mu ; arg6 +| : 0x000113f4 87600502 vle32.v v1, (a0) ; arg1 +| : 0x000113f8 d731209e vmv1r.v v3, v2 +| : 0x000113fc 93962700 slli a3, a5, 2 ; arg6 +| : 0x00011400 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011402 3695 add a0, a0, a3 ; arg1 +| : 0x00011404 5790206e vmflt.vv v0, v2, v1 +| : 0x00011408 d711104c vfsqrt.v v3, v1, v0.t +| : 0x0001140c a7610602 vse32.v v3, (a2) ; arg3 +| : 0x00011410 3696 add a2, a2, a3 ; arg3 +| `=< 0x00011412 79ff bnez a4, 0x113f0 +| 0x00011414 8280 ret +EOF +RUN + +NAME=Vector instructions: floating point operations +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x0001136c d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011370 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x00011374 07610302 vle32.v v2, (t1) +| : 0x00011378 13982700 slli a6, a5, 2 ; arg6 +| : 0x0001137c 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001137e c298 add a7, a7, a6 ; arg8 +| : 0x00011380 4293 add t1, t1, a6 +| : 0x00011382 d7101102 vfadd.vv v1, v1, v2 +| : 0x00011386 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x0001138a c296 add a3, a3, a6 ; arg4 +| `=< 0x0001138c 65f3 bnez a4, 0x1136c +| 0x0001138e b286 mv a3, a2 +| 0x00011390 2e83 mv t1, a1 +| 0x00011392 aa88 mv a7, a0 +| 0x00011394 13070040 li a4, 0x400 +| .-> 0x00011398 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x0001139c 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x000113a0 07610302 vle32.v v2, (t1) +| : 0x000113a4 13982700 slli a6, a5, 2 ; arg6 +| : 0x000113a8 1d8f sub a4, a4, a5 ; arg6 +| : 0x000113aa c298 add a7, a7, a6 ; arg8 +| : 0x000113ac 4293 add t1, t1, a6 +| : 0x000113ae d710110a vfsub.vv v1, v1, v2 +| : 0x000113b2 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000113b6 c296 add a3, a3, a6 ; arg4 +| `=< 0x000113b8 65f3 bnez a4, 0x11398 +| 0x000113ba b286 mv a3, a2 +| 0x000113bc aa88 mv a7, a0 +| 0x000113be 13070040 li a4, 0x400 +| .-> 0x000113c2 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000113c6 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x000113ca 07e10502 vle32.v v2, (a1) ; arg2 +| : 0x000113ce 13982700 slli a6, a5, 2 ; arg6 +| : 0x000113d2 1d8f sub a4, a4, a5 ; arg6 +| : 0x000113d4 c298 add a7, a7, a6 ; arg8 +| : 0x000113d6 c295 add a1, a1, a6 ; arg2 +| : 0x000113d8 d7101182 vfdiv.vv v1, v1, v2 +| : 0x000113dc a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000113e0 c296 add a3, a3, a6 ; arg4 +| `=< 0x000113e2 65f3 bnez a4, 0x113c2 +| 0x000113e4 d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 +| 0x000113e8 5731005e vmv.v.i v2, 0 +| 0x000113ec 13070040 li a4, 0x400 +| .-> 0x000113f0 d7770705 vsetvli a5, a4, e0x20, m1, ta, mu ; arg6 +| : 0x000113f4 87600502 vle32.v v1, (a0) ; arg1 +| : 0x000113f8 d731209e vmv1r.v v3, v2 +| : 0x000113fc 93962700 slli a3, a5, 2 ; arg6 +| : 0x00011400 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011402 3695 add a0, a0, a3 ; arg1 +| : 0x00011404 5790206e vmflt.vv v0, v2, v1 +| : 0x00011408 d711104c vfsqrt.v v3, v1, v0.t +| : 0x0001140c a7610602 vse32.v v3, (a2) ; arg3 +| : 0x00011410 3696 add a2, a2, a3 ; arg3 +| `=< 0x00011412 79ff bnez a4, 0x113f0 +| 0x00011414 8280 ret +EOF +RUN + +NAME=Vector instructions: widening operations +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x000112ea d777f70c vsetvli a5, a4, e0x10, mf2, ta, ma ; arg6 +| : 0x000112ee 87d10802 vle16.v v3, (a7) ; arg8 +| : 0x000112f2 07510802 vle16.v v2, (a6) ; arg7 +| : 0x000112f6 13931700 slli t1, a5, 1 ; arg6 +| : 0x000112fa 139e2700 slli t3, a5, 2 ; arg6 +| : 0x000112fe 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011300 1a98 add a6, a6, t1 ; arg7 +| : 0x00011302 9a98 add a7, a7, t1 ; arg8 +| : 0x00011304 d72031c6 vwadd.vv v1, v3, v2 +| : 0x00011308 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x0001130c f296 add a3, a3, t3 ; arg4 +| `=< 0x0001130e 71ff bnez a4, 0x112ea +| 0x00011310 13070040 li a4, 0x400 +| .-> 0x00011314 d777f70c vsetvli a5, a4, e0x10, mf2, ta, ma ; arg6 +| : 0x00011318 87d10502 vle16.v v3, (a1) ; arg2 +| : 0x0001131c 07510502 vle16.v v2, (a0) ; arg1 +| : 0x00011320 93961700 slli a3, a5, 1 ; arg6 +| : 0x00011324 13982700 slli a6, a5, 2 ; arg6 +| : 0x00011328 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001132a 3695 add a0, a0, a3 ; arg1 +| : 0x0001132c b695 add a1, a1, a3 ; arg2 +| : 0x0001132e d72031ee vwmul.vv v1, v3, v2 +| : 0x00011332 a7600602 vse32.v v1, (a2) ; arg3 +| : 0x00011336 4296 add a2, a2, a6 ; arg3 +| `=< 0x00011338 71ff bnez a4, 0x11314 +| 0x0001133a 8280 ret +EOF +RUN + + +NAME=Vector instructions: comparisons +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x00011074 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011078 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x0001107c 87600302 vle32.v v1, (t1) +| : 0x00011080 13982700 slli a6, a5, 2 ; arg6 +| : 0x00011084 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011086 c298 add a7, a7, a6 ; arg8 +| : 0x00011088 4293 add t1, t1, a6 +| : 0x0001108a d7001116 vmin.vv v1, v1, v2 +| : 0x0001108e a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x00011092 c296 add a3, a3, a6 ; arg4 +| `=< 0x00011094 65f3 bnez a4, 0x11074 +| 0x00011096 5773000d vsetvli t1, zero, e0x20, m1, ta, ma +| 0x0001109a 5731005e vmv.v.i v2, 0 +| 0x0001109e b286 mv a3, a2 +| 0x000110a0 aa88 mv a7, a0 +| 0x000110a2 13070040 li a4, 0x400 +| .-> 0x000110a6 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000110aa 87e00802 vle32.v v1, (a7) ; arg8 +| : 0x000110ae 07e00502 vle32.v v0, (a1) ; arg2 +| : 0x000110b2 13982700 slli a6, a5, 2 ; arg6 +| : 0x000110b6 1d8f sub a4, a4, a5 ; arg6 +| : 0x000110b8 c295 add a1, a1, a6 ; arg2 +| : 0x000110ba c298 add a7, a7, a6 ; arg8 +| : 0x000110bc 57800062 vmseq.vv v0, v0, v1 +| : 0x000110c0 d7b0205c vmerge.vim v1, v2, 1, v0 +| : 0x000110c4 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000110c8 c296 add a3, a3, a6 ; arg4 +| `=< 0x000110ca 71ff bnez a4, 0x110a6 +| 0x000110cc d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 +| 0x000110d0 5731005e vmv.v.i v2, 0 +| 0x000110d4 13073006 li a4, 0x63 +| 0x000110d8 d741075e vmv.v.x v3, a4 +| 0x000110dc 13070040 li a4, 0x400 +| .-> 0x000110e0 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000110e4 87600502 vle32.v v1, (a0) ; arg1 +| : 0x000110e8 93962700 slli a3, a5, 2 ; arg6 +| : 0x000110ec 1d8f sub a4, a4, a5 ; arg6 +| : 0x000110ee 3695 add a0, a0, a3 ; arg1 +| : 0x000110f0 5780306e vmslt.vv v0, v3, v1 +| : 0x000110f4 d780205c vmerge.vvm v1, v2, v1, v0 +| : 0x000110f8 a7600602 vse32.v v1, (a2) ; arg3 +| : 0x000110fc 3696 add a2, a2, a3 ; arg3 +| `=< 0x000110fe 6df3 bnez a4, 0x110e0 +| 0x00011100 8280 ret +EOF +RUN + +NAME=Vector instructions: clipping +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x00011840 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011844 87600502 vle32.v v1, (a0) ; arg1 +| : 0x00011848 93962700 slli a3, a5, 2 ; arg6 +| : 0x0001184c 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001184e 3695 add a0, a0, a3 ; arg1 +| : 0x00011850 d780111e vmax.vv v1, v1, v3 +| : 0x00011854 d7001116 vmin.vv v1, v1, v2 +| : 0x00011858 a7e00502 vse32.v v1, (a1) ; arg2 +| : 0x0001185c b695 add a1, a1, a3 ; arg2 +| `=< 0x0001185e 6df3 bnez a4, 0x11840 +| 0x00011860 8280 ret +EOF +RUN + +NAME=Vector instructions: conversions +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x00011528 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x0001152c 87600502 vle32.v v1, (a0) ; arg1 +| : 0x00011530 13982700 slli a6, a5, 2 ; arg6 +| : 0x00011534 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011536 4295 add a0, a0, a6 ; arg1 +| : 0x00011538 d790114a vfcvt.f.x.v v1, v1 +| : 0x0001153c a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x00011540 c296 add a3, a3, a6 ; arg4 +| `=< 0x00011542 7df3 bnez a4, 0x11528 +| 0x00011544 13070040 li a4, 0x400 +| .-> 0x00011548 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x0001154c 87e00502 vle32.v v1, (a1) ; arg2 +| : 0x00011550 93962700 slli a3, a5, 2 ; arg6 +| : 0x00011554 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011556 b695 add a1, a1, a3 ; arg2 +| : 0x00011558 d790134a vfcvt.rtz.x.f.v v1, v1 +| : 0x0001155c a7600602 vse32.v v1, (a2) ; arg3 +| : 0x00011560 3696 add a2, a2, a3 ; arg3 +| `=< 0x00011562 7df3 bnez a4, 0x11548 +| 0x00011564 8280 ret +EOF +RUN + +NAME=Vector instructions: narrowing +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x00011340 d777f70c vsetvli a5, a4, e0x10, mf2, ta, ma ; arg6 +| : 0x00011344 87600502 vle32.v v1, (a0) ; arg1 +| : 0x00011348 13962700 slli a2, a5, 2 ; arg6 +| : 0x0001134c 93961700 slli a3, a5, 1 ; arg6 +| : 0x00011350 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011352 3295 add a0, a0, a2 ; arg1 +| : 0x00011354 d73014b6 vnsra.wi v1, v1, 8 +| : 0x00011358 a7d00502 vse16.v v1, (a1) ; arg2 +| : 0x0001135c b695 add a1, a1, a3 ; arg2 +| `=< 0x0001135e 6df3 bnez a4, 0x11340 +| 0x00011360 8280 ret +EOF +RUN + +NAME=Vector instructions: average +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x0001180c d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011810 07610502 vle32.v v2, (a0) ; arg1 +| : 0x00011814 87e00502 vle32.v v1, (a1) ; arg2 +| : 0x00011818 93962700 slli a3, a5, 2 ; arg6 +| : 0x0001181c 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001181e 3695 add a0, a0, a3 ; arg1 +| : 0x00011820 b695 add a1, a1, a3 ; arg2 +| : 0x00011822 d7201122 vaaddu.vv v1, v1, v2 +| : 0x00011826 a7600602 vse32.v v1, (a2) ; arg3 +| : 0x0001182a 3696 add a2, a2, a3 ; arg3 +| `=< 0x0001182c 65f3 bnez a4, 0x1180c +| 0x0001182e 8280 ret +EOF +RUN + +NAME=Vector instructions: segment access +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x00011746 d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 +| : 0x0001174a 87610502 vle32.v v3, (a0) ; arg1 +| : 0x0001174e 07e10502 vle32.v v2, (a1) ; arg2 +| : 0x00011752 87600602 vle32.v v1, (a2) ; arg3 +| : 0x00011756 13972700 slli a4, a5, 2 ; arg6 +| : 0x0001175a 3308f840 sub a6, a6, a5 ; arg6 +| : 0x0001175e 3a95 add a0, a0, a4 ; arg1 +| : 0x00011760 ba95 add a1, a1, a4 ; arg2 +| : 0x00011762 57912102 vfadd.vv v2, v2, v3 +| : 0x00011766 3a96 add a2, a2, a4 ; arg3 +| : 0x00011768 d7101102 vfadd.vv v1, v1, v2 +| : 0x0001176c a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x00011770 ba96 add a3, a3, a4 ; arg4 +| `=< 0x00011772 e31a08fc bnez a6, 0x11746 +| 0x00011776 8280 ret +EOF +RUN + +NAME=Vector instructions: floating point comparisons +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x000114c2 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000114c6 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x000114ca 87600302 vle32.v v1, (t1) +| : 0x000114ce 13982700 slli a6, a5, 2 ; arg6 +| : 0x000114d2 1d8f sub a4, a4, a5 ; arg6 +| : 0x000114d4 c298 add a7, a7, a6 ; arg8 +| : 0x000114d6 4293 add t1, t1, a6 +| : 0x000114d8 5790206e vmflt.vv v0, v2, v1 +| : 0x000114dc d700115c vmerge.vvm v1, v1, v2, v0 +| : 0x000114e0 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000114e4 c296 add a3, a3, a6 ; arg4 +| `=< 0x000114e6 71ff bnez a4, 0x114c2 +| 0x000114e8 577e000d vsetvli t3, zero, e0x20, m1, ta, ma +| 0x000114ec d731005e vmv.v.i v3, 0 +| 0x000114f0 13070040 li a4, 0x400 +| .-> 0x000114f4 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000114f8 07610502 vle32.v v2, (a0) ; arg1 +| : 0x000114fc 07e00502 vle32.v v0, (a1) ; arg2 +| : 0x00011500 87a78180 flw fa5, -0x7f8(gp) +| : 0x00011504 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011506 93962700 slli a3, a5, 2 ; arg6 +| : 0x0001150a d7d0075e vfmv.v.f v1, fa5 +| : 0x0001150e 57100162 vmfeq.vv v0, v0, v2 +| : 0x00011512 b695 add a1, a1, a3 ; arg2 +| : 0x00011514 3695 add a0, a0, a3 ; arg1 +| : 0x00011516 d780305c vmerge.vvm v1, v3, v1, v0 +| : 0x0001151a a7600602 vse32.v v1, (a2) ; arg3 +| : 0x0001151e 3696 add a2, a2, a3 ; arg3 +| `=< 0x00011520 71fb bnez a4, 0x114f4 +| 0x00011522 8280 ret +EOF +RUN + +NAME=Vector instructions: multi byte +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x0001177c d777870d vsetvli a5, a4, e0x40, m1, ta, ma ; arg6 +| : 0x00011780 07710502 vle64.v v2, (a0) ; arg1 +| : 0x00011784 87f00502 vle64.v v1, (a1) ; arg2 +| : 0x00011788 93963700 slli a3, a5, 3 ; arg6 +| : 0x0001178c 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001178e 3695 add a0, a0, a3 ; arg1 +| : 0x00011790 b695 add a1, a1, a3 ; arg2 +| : 0x00011792 d7001102 vadd.vv v1, v1, v2 +| : 0x00011796 a7700602 vse64.v v1, (a2) ; arg3 +| : 0x0001179a 3696 add a2, a2, a3 ; arg3 +| `=< 0x0001179c 65f3 bnez a4, 0x1177c +| 0x0001179e 8280 ret +EOF +RUN + +NAME=Vector instructions: shifts +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x0001110a d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x0001110e 87600802 vle32.v v1, (a6) ; arg7 +| : 0x00011112 93982700 slli a7, a5, 2 ; arg6 +| : 0x00011116 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011118 4698 add a6, a6, a7 ; arg7 +| : 0x0001111a d7b01196 vsll.vi v1, v1, 3 +| : 0x0001111e a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x00011122 c696 add a3, a3, a7 ; arg4 +| `=< 0x00011124 7df3 bnez a4, 0x1110a +| 0x00011126 b286 mv a3, a2 +| 0x00011128 2a88 mv a6, a0 +| 0x0001112a 13070040 li a4, 0x400 +| .-> 0x0001112e d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011132 87600802 vle32.v v1, (a6) ; arg7 +| : 0x00011136 93982700 slli a7, a5, 2 ; arg6 +| : 0x0001113a 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001113c 4698 add a6, a6, a7 ; arg7 +| : 0x0001113e d73011a2 vsrl.vi v1, v1, 2 +| : 0x00011142 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x00011146 c696 add a3, a3, a7 ; arg4 +| `=< 0x00011148 7df3 bnez a4, 0x1112e +| 0x0001114a b286 mv a3, a2 +| 0x0001114c 13070040 li a4, 0x400 +| .-> 0x00011150 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011154 87e00502 vle32.v v1, (a1) ; arg2 +| : 0x00011158 13982700 slli a6, a5, 2 ; arg6 +| : 0x0001115c 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001115e c295 add a1, a1, a6 ; arg2 +| : 0x00011160 d73012a6 vsra.vi v1, v1, 4 +| : 0x00011164 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x00011168 c296 add a3, a3, a6 ; arg4 +| `=< 0x0001116a 7df3 bnez a4, 0x11150 +| 0x0001116c d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 +| 0x00011170 57a10852 vid.v v2 +| 0x00011174 13070040 li a4, 0x400 +| .-> 0x00011178 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x0001117c 87600502 vle32.v v1, (a0) ; arg1 +| : 0x00011180 57b22326 vand.vi v4, v2, 7 +| : 0x00011184 d775000d vsetvli a1, zero, e0x20, m1, ta, ma ; arg2 +| : 0x00011188 d7c1075e vmv.v.x v3, a5 +| : 0x0001118c 57f0070d vsetvli zero, a5, e0x20, m1, ta, ma ; arg6 +| : 0x00011190 93952700 slli a1, a5, 2 ; arg6 +| : 0x00011194 d7001296 vsll.vv v1, v1, v4 +| : 0x00011198 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001119a 2e95 add a0, a0, a1 ; arg1 +| : 0x0001119c a7600602 vse32.v v1, (a2) ; arg3 +| : 0x000111a0 d777000d vsetvli a5, zero, e0x20, m1, ta, ma ; arg6 +| : 0x000111a4 57812102 vadd.vv v2, v2, v3 +| : 0x000111a8 2e96 add a2, a2, a1 ; arg3 +| `=< 0x000111aa 79f7 bnez a4, 0x11178 +| 0x000111ac 8280 ret +EOF +RUN + +NAME=Vector instructions: strided access +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x000115ea d777670c vsetvli a5, a4, e8, mf4, ta, ma ; arg6 +| : 0x000115ee 07610622 vlseg2e32.v v2, (a2) ; arg3 +| : 0x000115f2 93983700 slli a7, a5, 3 ; arg6 +| : 0x000115f6 13982700 slli a6, a5, 2 ; arg6 +| : 0x000115fa 1d8f sub a4, a4, a5 ; arg6 +| : 0x000115fc 4696 add a2, a2, a7 ; arg3 +| : 0x000115fe 27e10602 vse32.v v2, (a3) ; arg4 +| : 0x00011602 c296 add a3, a3, a6 ; arg4 +| `=< 0x00011604 7df3 bnez a4, 0x115ea +| 0x00011606 0567 lui a4, 1 +| 0x00011608 b307e500 add a5, a0, a4 ; arg1 +| 0x0001160c 87a787ff flw fa5, -8(a5) +| 0x00011610 732620c2 csrr a2, vlenb +| 0x00011614 93582600 srli a7, a2, 2 ; arg3 +| 0x00011618 9387f8ff addi a5, a7, -1 +| 0x0001161c 27aef57e fsw fa5, 0x7fc(a1) ; arg2 +| 0x00011620 1b880700 sext.w a6, a5 +| 0x00011624 9306f03f li a3, 0x3ff +| ,=< 0x00011628 63e80611 bltu a3, a6, 0x11738 +| | 0x0001162c 5773000d vsetvli t1, zero, e0x20, m1, ta, ma +| | 0x00011630 d7a10852 vid.v v3 +| | 0x00011634 118f sub a4, a4, a2 ; arg3 +| | 0x00011636 33081041 neg a6, a7 +| | 0x0001163a d7c1370e vrsub.vx v3, v3, a5 +| | 0x0001163e 2e97 add a4, a4, a1 ; arg2 +| | 0x00011640 1b080840 addiw a6, a6, 0x400 +| | 0x00011644 aa86 mv a3, a0 +| | 0x00011646 8147 li a5, 0 +| .--> 0x00011648 07e18602 vl1re32.v v2, (a3) +| :| 0x0001164c bb871701 addw a5, a5, a7 +| :| 0x00011650 b296 add a3, a3, a2 ; arg3 +| :| 0x00011652 d7802132 vrgather.vv v1, v2, v3 +| :| 0x00011656 a7008702 vs1r.v v1, (a4) +| :| 0x0001165a 118f sub a4, a4, a2 ; arg3 +| `==< 0x0001165c e376f8fe bgeu a6, a5, 0x11648 +| | 0x00011660 93060040 li a3, 0x400 +| ,==< 0x00011664 6389d70c beq a5, a3, 0x11736 +| || 0x00011668 bb8ef640 subw t4, a3, a5 +| || 0x0001166c 3e88 mv a6, a5 +| || ; CODE XREF from sym.test_strided_access @ 0x11740 +| || 0x0001166e 732320c2 csrr t1, vlenb +| || 0x00011672 93563300 srli a3, t1, 3 +| || 0x00011676 9388f6ff addi a7, a3, -1 +| || 0x0001167a 1307f03f li a4, 0x3ff +| || 0x0001167e 1b860800 sext.w a2, a7 +| || 0x00011682 1d9f subw a4, a4, a5 +| ,===< 0x00011684 636cc706 bltu a4, a2, 0x116fc +| ||| 0x00011688 13970702 slli a4, a5, 0x20 +| ||| 0x0001168c 135ee701 srli t3, a4, 0x1e +| ||| 0x00011690 5776700d vsetvli a2, zero, e0x20, mf2, ta, ma +| ||| 0x00011694 330fc501 add t5, a0, t3 ; arg1 +| ||| 0x00011698 87610f02 vle32.v v3, (t5) +| ||| 0x0001169c d7a00852 vid.v v1 +| ||| 0x000116a0 935f1300 srli t6, t1, 1 +| ||| 0x000116a4 d7c0180e vrsub.vx v1, v1, a7 +| ||| 0x000116a8 0567 lui a4, 1 +| ||| 0x000116aa 3307f741 sub a4, a4, t6 +| ||| 0x000116ae 57813032 vrgather.vv v2, v3, v1 +| ||| 0x000116b2 3307c741 sub a4, a4, t3 +| ||| 0x000116b6 2e97 add a4, a4, a1 ; arg2 +| ||| 0x000116b8 27610702 vse32.v v2, (a4) +| ||| 0x000116bc b308d040 neg a7, a3 +| ||| 0x000116c0 93880840 addi a7, a7, 0x400 +| ||| 0x000116c4 bb88f840 subw a7, a7, a5 +| ||| 0x000116c8 130e0040 li t3, 0x400 +| ||| 0x000116cc 8126 sext.w a3, a3 +| ||| 0x000116ce bb07fe40 subw a5, t3, a5 +| ,====< 0x000116d2 63efd800 bltu a7, a3, 0x116f0 +| |||| 0x000116d6 7e9f add t5, t5, t6 +| |||| 0x000116d8 87610f02 vle32.v v3, (t5) +| |||| 0x000116dc 3307f741 sub a4, a4, t6 +| |||| 0x000116e0 13532300 srli t1, t1, 2 +| |||| 0x000116e4 9b060300 sext.w a3, t1 +| |||| 0x000116e8 57813032 vrgather.vv v2, v3, v1 +| |||| 0x000116ec 27610702 vse32.v v2, (a4) +| ,`----> 0x000116f0 6383d704 beq a5, a3, 0x11736 +| | ||| 0x000116f4 3b880601 addw a6, a3, a6 +| | ||| 0x000116f8 bb8ede40 subw t4, t4, a3 +| | `---> 0x000116fc 9b86feff addiw a3, t4, -1 +| | || 0x00011700 1387f57f addi a4, a1, 0x7ff ; arg2 +| | || 0x00011704 0a08 slli a6, a6, 2 +| | || 0x00011706 1307977f addi a4, a4, 0x7f9 +| | || 0x0001170a 13960602 slli a2, a3, 0x20 +| | || 0x0001170e 9387f57f addi a5, a1, 0x7ff ; arg2 +| | || 0x00011712 9356e601 srli a3, a2, 0x1e +| | || 0x00011716 33070741 sub a4, a4, a6 +| | || 0x0001171a 9387d77f addi a5, a5, 0x7fd +| | || 0x0001171e 4295 add a0, a0, a6 ; arg1 +| | || 0x00011720 158f sub a4, a4, a3 +| | || 0x00011722 b3870741 sub a5, a5, a6 +| | .---> 0x00011726 87270500 flw fa5, 0(a0) ; arg1 +| | :|| 0x0001172a f117 addi a5, a5, -4 +| | :|| 0x0001172c 1105 addi a0, a0, 4 ; arg1 +| | :|| 0x0001172e 27a2f700 fsw fa5, 4(a5) +| | `===< 0x00011732 e31af7fe bne a4, a5, 0x11726 +| `--`--> 0x00011736 8280 ret +| `-> 0x00011738 8147 li a5, 0 +| 0x0001173a 930e0040 li t4, 0x400 +| 0x0001173e 0148 li a6, 0 +| 0x00011740 3db7 j 0x1166e +EOF +RUN + +NAME=Vector instructions: absolute value and negation +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x0001186a d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x0001186e 87600602 vle32.v v1, (a2) ; arg3 +| : 0x00011872 13982700 slli a6, a5, 2 ; arg6 +| : 0x00011876 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011878 4296 add a2, a2, a6 ; arg3 +| : 0x0001187a 5731100e vrsub.vi v2, v1, 0 +| : 0x0001187e d700111e vmax.vv v1, v1, v2 +| : 0x00011882 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x00011886 c296 add a3, a3, a6 ; arg4 +| `=< 0x00011888 6df3 bnez a4, 0x1186a +| 0x0001188a 13070040 li a4, 0x400 +| .-> 0x0001188e d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011892 87600502 vle32.v v1, (a0) ; arg1 +| : 0x00011896 93962700 slli a3, a5, 2 ; arg6 +| : 0x0001189a 1d8f sub a4, a4, a5 ; arg6 +| : 0x0001189c 3695 add a0, a0, a3 ; arg1 +| : 0x0001189e d730100e vrsub.vi v1, v1, 0 +| : 0x000118a2 a7e00502 vse32.v v1, (a1) ; arg2 +| : 0x000118a6 b695 add a1, a1, a3 ; arg2 +| `=< 0x000118a8 7df3 bnez a4, 0x1188e +| 0x000118aa 8280 ret +EOF +RUN + +NAME=Vector instructions: main function +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x000105f2 0566 lui a2, 1 +| 0x000105f4 93050004 li a1, 0x40 +| 0x000105f8 0819 addi a0, sp, 0xb0 +| 0x000105fa eff07ff8 jal sym.imp.posix_memalign +| 0x000105fe 014b li s6, 0 +| ,=< 0x00010600 11e1 bnez a0, 0x10604 +| | 0x00010602 4a7b ld s6, 0xb0(sp) +| `-> 0x00010604 0566 lui a2, 1 +| 0x00010606 93050004 li a1, 0x40 +| 0x0001060a 2811 addi a0, sp, 0xa8 +| 0x0001060c eff05ff7 jal sym.imp.posix_memalign +| 0x00010610 02f0 sd zero, 0x20(sp) +| ,=< 0x00010612 19e1 bnez a0, 0x10618 +| | 0x00010614 aa77 ld a5, 0xa8(sp) +| | 0x00010616 3ef0 sd a5, 0x20(sp) +| `-> 0x00010618 0566 lui a2, 1 +| 0x0001061a 93050004 li a1, 0x40 +| 0x0001061e 0811 addi a0, sp, 0xa0 +| 0x00010620 eff01ff6 jal sym.imp.posix_memalign +| 0x00010624 014a li s4, 0 +| ,=< 0x00010626 11e1 bnez a0, 0x1062a +| | 0x00010628 0a7a ld s4, 0xa0(sp) +| `-> 0x0001062a 0566 lui a2, 1 +| 0x0001062c 13060680 addi a2, a2, -0x800 +| 0x00010630 93050004 li a1, 0x40 +| 0x00010634 2809 addi a0, sp, 0x98 +| 0x00010636 eff0bff4 jal sym.imp.posix_memalign +| 0x0001063a 814c li s9, 0 +| ,=< 0x0001063c 11e1 bnez a0, 0x10640 +| | 0x0001063e ea6c ld s9, 0x98(sp) +| `-> 0x00010640 0566 lui a2, 1 +| 0x00010642 13060680 addi a2, a2, -0x800 +| 0x00010646 93050004 li a1, 0x40 +| 0x0001064a 0809 addi a0, sp, 0x90 +| 0x0001064c eff05ff3 jal sym.imp.posix_memalign +| 0x00010650 814d li s11, 0 +| ,=< 0x00010652 11e1 bnez a0, 0x10656 +| | 0x00010654 ca6d ld s11, 0x90(sp) +| `-> 0x00010656 0566 lui a2, 1 +| 0x00010658 13060680 addi a2, a2, -0x800 +| 0x0001065c 93050004 li a1, 0x40 +| 0x00010660 2801 addi a0, sp, 0x88 +| 0x00010662 eff0fff1 jal sym.imp.posix_memalign +| 0x00010666 02ec sd zero, 0x18(sp) +| ,=< 0x00010668 19e1 bnez a0, 0x1066e +| | 0x0001066a aa67 ld a5, 0x88(sp) +| | 0x0001066c 3eec sd a5, 0x18(sp) +| `-> 0x0001066e 13060040 li a2, 0x400 +| 0x00010672 93050004 li a1, 0x40 +| 0x00010676 0801 addi a0, sp, 0x80 +| 0x00010678 eff09ff0 jal sym.imp.posix_memalign +| 0x0001067c 02e8 sd zero, 0x10(sp) +| ,=< 0x0001067e 19e1 bnez a0, 0x10684 +| | 0x00010680 8a67 ld a5, 0x80(sp) +| | 0x00010682 3ee8 sd a5, 0x10(sp) +| `-> 0x00010684 0966 lui a2, 2 +| 0x00010686 93050004 li a1, 0x40 +| 0x0001068a a818 addi a0, sp, 0x78 +| 0x0001068c eff05fef jal sym.imp.posix_memalign +| 0x00010690 02e4 sd zero, 8(sp) +| ,=< 0x00010692 19e1 bnez a0, 0x10698 +| | 0x00010694 e677 ld a5, 0x78(sp) +| | 0x00010696 3ee4 sd a5, 8(sp) +| `-> 0x00010698 0966 lui a2, 2 +| 0x0001069a 93050004 li a1, 0x40 +| 0x0001069e 8818 addi a0, sp, 0x70 +| 0x000106a0 eff01fee jal sym.imp.posix_memalign +| 0x000106a4 02e0 sd zero, 0(sp) +| ,=< 0x000106a6 19e1 bnez a0, 0x106ac +| | 0x000106a8 c677 ld a5, 0x70(sp) +| | 0x000106aa 3ee0 sd a5, 0(sp) +| `-> 0x000106ac 0966 lui a2, 2 +| 0x000106ae 93050004 li a1, 0x40 +| 0x000106b2 a810 addi a0, sp, 0x68 +| 0x000106b4 eff0dfec jal sym.imp.posix_memalign +| 0x000106b8 02f4 sd zero, 0x28(sp) +| ,=< 0x000106ba 19e1 bnez a0, 0x106c0 +| | 0x000106bc a677 ld a5, 0x68(sp) +| | 0x000106be 3ef4 sd a5, 0x28(sp) +| `-> 0x000106c0 0566 lui a2, 1 +| 0x000106c2 93050004 li a1, 0x40 +| 0x000106c6 8810 addi a0, sp, 0x60 +| 0x000106c8 eff09feb jal sym.imp.posix_memalign +| 0x000106cc 8144 li s1, 0 +| ,=< 0x000106ce 11e1 bnez a0, 0x106d2 +| | 0x000106d0 8674 ld s1, 0x60(sp) +| `-> 0x000106d2 0566 lui a2, 1 +| 0x000106d4 93050004 li a1, 0x40 +| 0x000106d8 a808 addi a0, sp, 0x58 +| 0x000106da eff07fea jal sym.imp.posix_memalign +| 0x000106de 8149 li s3, 0 +| ,=< 0x000106e0 11e1 bnez a0, 0x106e4 +| | 0x000106e2 e669 ld s3, 0x58(sp) +| `-> 0x000106e4 0566 lui a2, 1 +| 0x000106e6 93050004 li a1, 0x40 +| 0x000106ea 8808 addi a0, sp, 0x50 +| 0x000106ec eff05fe9 jal sym.imp.posix_memalign +| 0x000106f0 014d li s10, 0 +| ,=< 0x000106f2 11e1 bnez a0, 0x106f6 +| | 0x000106f4 466d ld s10, 0x50(sp) +| `-> 0x000106f6 0566 lui a2, 1 +| 0x000106f8 93050004 li a1, 0x40 +| 0x000106fc a800 addi a0, sp, 0x48 +| 0x000106fe eff03fe8 jal sym.imp.posix_memalign +| 0x00010702 0149 li s2, 0 +| ,=< 0x00010704 11e1 bnez a0, 0x10708 +| | 0x00010706 2669 ld s2, 0x48(sp) +| `-> 0x00010708 93050004 li a1, 0x40 +| 0x0001070c 0566 lui a2, 1 +| 0x0001070e 3305b100 add a0, sp, a1 +| 0x00010712 eff0ffe6 jal sym.imp.posix_memalign +| 0x00010716 814a li s5, 0 +| ,=< 0x00010718 11e1 bnez a0, 0x1071c +| | 0x0001071a 866a ld s5, 0x40(sp) +| `-> 0x0001071c 0566 lui a2, 1 +| 0x0001071e 93050004 li a1, 0x40 +| 0x00010722 2818 addi a0, sp, 0x38 +| 0x00010724 eff0dfe5 jal sym.imp.posix_memalign +| 0x00010728 014c li s8, 0 +| ,=< 0x0001072a 11e1 bnez a0, 0x1072e +| | 0x0001072c 627c ld s8, 0x38(sp) +| `-> 0x0001072e 0566 lui a2, 1 +| 0x00010730 93050004 li a1, 0x40 +| 0x00010734 0818 addi a0, sp, 0x30 +| 0x00010736 eff0bfe4 jal sym.imp.posix_memalign +| 0x0001073a 814b li s7, 0 +| ,=< 0x0001073c 11e1 bnez a0, 0x10740 +| | 0x0001073e c27b ld s7, 0x30(sp) +| `-> 0x00010740 5777000d vsetvli a4, zero, e0x20, m1, ta, ma +| 0x00010744 93064006 li a3, 0x64 +| 0x00010748 57c4065e vmv.v.x v8, a3 +| 0x0001074c 93060040 li a3, 0x400 +| 0x00010750 57c9065e vmv.v.x v18, a3 +| 0x00010754 9306f007 li a3, 0x7f +| 0x00010758 d7c8065e vmv.v.x v17, a3 +| 0x0001075c b787eb51 lui a5, 0x51eb8 +| 0x00010760 930600e0 li a3, -0x200 +| 0x00010764 57c8065e vmv.v.x v16, a3 +| 0x00010768 9b87f751 addiw a5, a5, 0x51f +| 0x0001076c 9306f00f li a3, 0xff +| 0x00010770 d7c7065e vmv.v.x v15, a3 +| 0x00010774 d7c9075e vmv.v.x v19, a5 +| 0x00010778 930600e0 li a3, -0x200 +| 0x0001077c 5770f00c vsetvli zero, zero, e0x10, mf2, ta, ma +| 0x00010780 57c7065e vmv.v.x v14, a3 +| 0x00010784 9306f007 li a3, 0x7f +| 0x00010788 5770600c vsetvli zero, zero, e8, mf4, ta, ma +| 0x0001078c d7c6065e vmv.v.x v13, a3 +| 0x00010790 87a70181 flw fa5, -0x7f0(gp) +| 0x00010794 5770000d vsetvli zero, zero, e0x20, m1, ta, ma +| 0x00010798 07a78180 flw fa4, -0x7f8(gp) +| 0x0001079c d7b5015e vmv.v.i v11, 3 +| 0x000107a0 57b5035e vmv.v.i v10, 7 +| 0x000107a4 d7b4065e vmv.v.i v9, 0xd +| 0x000107a8 4263 ld t1, 0x10(sp) +| 0x000107aa 0275 ld a0, 0x20(sp) +| 0x000107ac c546 li a3, 0x11 +| 0x000107ae d7a00852 vid.v v1 +| 0x000107b2 57c6065e vmv.v.x v12, a3 +| 0x000107b6 e282 mv t0, s8 +| 0x000107b8 d68f mv t6, s5 +| 0x000107ba 6a8f mv t5, s10 +| 0x000107bc ce8e mv t4, s3 +| 0x000107be 268e mv t3, s1 +| 0x000107c0 ee88 mv a7, s11 +| 0x000107c2 6688 mv a6, s9 +| 0x000107c4 da85 mv a1, s6 +| 0x000107c6 2286 mv a2, s0 +| 0x000107c8 93060040 li a3, 0x400 +| .-> 0x000107cc d7f7060d vsetvli a5, a3, e0x20, m1, ta, ma +| : 0x000107d0 d7011802 vadd.vv v3, v1, v16 +| : 0x000107d4 57211596 vmul.vv v2, v1, v10 +| : 0x000107d8 d7a31596 vmul.vv v7, v1, v11 +| : 0x000107dc a7610602 vse32.v v3, (a2) +| : 0x000107e0 5770f00c vsetvli zero, zero, e0x10, mf2, ta, ma +| : 0x000107e4 d73110b2 vnsrl.wi v3, v1, 0 +| : 0x000107e8 5770000d vsetvli zero, zero, e0x20, m1, ta, ma +| : 0x000107ec 57812726 vand.vv v2, v2, v15 +| : 0x000107f0 d7837826 vand.vv v7, v7, v17 +| : 0x000107f4 d792114a vfcvt.f.x.v v5, v1 +| : 0x000107f8 5770f00c vsetvli zero, zero, e0x10, mf2, ta, ma +| : 0x000107fc 27e10502 vse32.v v2, (a1) +| : 0x00010800 d70a3702 vadd.vv v21, v3, v14 +| : 0x00010804 5770000d vsetvli zero, zero, e0x20, m1, ta, ma +| : 0x00010808 5783200b vsub.vv v6, v18, v1 +| : 0x0001080c 57a1199e vmulh.vv v2, v1, v19 +| : 0x00010810 d7d25782 vfdiv.vf v5, v5, fa5 +| : 0x00010814 5770f00c vsetvli zero, zero, e0x10, mf2, ta, ma +| : 0x00010818 573a70b2 vnsrl.wi v20, v7, 0 +| : 0x0001081c 5770000d vsetvli zero, zero, e0x20, m1, ta, ma +| : 0x00010820 a7630502 vse32.v v7, (a0) +| : 0x00010824 a75a0802 vse16.v v21, (a6) +| : 0x00010828 5792614a vfcvt.f.x.v v4, v6 +| : 0x0001082c 57b122a6 vsra.vi v2, v2, 5 +| : 0x00010830 13972700 slli a4, a5, 2 +| : 0x00010834 57d24782 vfdiv.vf v4, v4, fa5 +| : 0x00010838 5770600c vsetvli zero, zero, e8, mf4, ta, ma +| : 0x0001083c d73130b2 vnsrl.wi v3, v3, 0 +| : 0x00010840 5770000d vsetvli zero, zero, e0x20, m1, ta, ma +| : 0x00010844 27da0802 vse16.v v20, (a7) +| : 0x00010848 572114ae vnmsub.vv v2, v8, v1 +| : 0x0001084c d7a31496 vmul.vv v7, v1, v9 +| : 0x00010850 5770600c vsetvli zero, zero, e8, mf4, ta, ma +| : 0x00010854 d7813626 vand.vv v3, v3, v13 +| : 0x00010858 5770000d vsetvli zero, zero, e0x20, m1, ta, ma +| : 0x0001085c 5791214a vfcvt.f.x.v v2, v2 +| : 0x00010860 a7010302 vse8.v v3, (t1) +| : 0x00010864 d7525702 vfadd.vf v5, v5, fa4 +| : 0x00010868 57d12782 vfdiv.vf v2, v2, fa5 +| : 0x0001086c 57236696 vmul.vv v6, v6, v12 +| : 0x00010870 d773000d vsetvli t2, zero, e0x20, m1, ta, ma +| : 0x00010874 57ca075e vmv.v.x v20, a5 +| : 0x00010878 57f0070d vsetvli zero, a5, e0x20, m1, ta, ma +| : 0x0001087c a7620e02 vse32.v v5, (t3) +| : 0x00010880 d7514702 vfadd.vf v3, v4, fa4 +| : 0x00010884 d773000d vsetvli t2, zero, e0x20, m1, ta, ma +| : 0x00010888 d7001a02 vadd.vv v1, v1, v20 +| : 0x0001088c 57f0070d vsetvli zero, a5, e0x20, m1, ta, ma +| : 0x00010890 93931700 slli t2, a5, 1 +| : 0x00010894 a7e10e02 vse32.v v3, (t4) +| : 0x00010898 9d8e sub a3, a3, a5 +| : 0x0001089a 3e93 add t1, t1, a5 +| : 0x0001089c 3a96 add a2, a2, a4 +| : 0x0001089e ba95 add a1, a1, a4 +| : 0x000108a0 3a95 add a0, a0, a4 +| : 0x000108a2 27610f02 vse32.v v2, (t5) +| : 0x000108a6 a7e30f02 vse32.v v7, (t6) +| : 0x000108aa 3a9e add t3, t3, a4 +| : 0x000108ac ba9e add t4, t4, a4 +| : 0x000108ae 3a9f add t5, t5, a4 +| : 0x000108b0 ba9f add t6, t6, a4 +| : 0x000108b2 1e98 add a6, a6, t2 +| : 0x000108b4 27e30202 vse32.v v6, (t0) +| : 0x000108b8 9e98 add a7, a7, t2 +| : 0x000108ba ba92 add t0, t0, a4 +| `=< 0x000108bc 81fa bnez a3, 0x107cc +| 0x000108be d777700d vsetvli a5, zero, e0x20, mf2, ta, ma +| 0x000108c2 1307803e li a4, 0x3e8 +| 0x000108c6 0266 ld a2, 0(sp) +| 0x000108c8 a266 ld a3, 8(sp) +| 0x000108ca d741075e vmv.v.x v3, a4 +| 0x000108ce d7a00852 vid.v v1 +| 0x000108d2 13070040 li a4, 0x400 +| 0x000108d6 5743075e vmv.v.x v6, a4 +| 0x000108da 13070020 li a4, 0x200 +| .-> 0x000108de d777770d vsetvli a5, a4, e0x20, mf2, ta, ma +| : 0x000108e2 57a21196 vmul.vv v4, v1, v3 +| : 0x000108e6 5781600a vsub.vv v2, v6, v1 +| : 0x000108ea 5770800d vsetvli zero, zero, e0x40, m1, ta, ma +| : 0x000108ee 13953700 slli a0, a5, 3 +| : 0x000108f2 d7a2434a vsext.vf2 v5, v4 +| : 0x000108f6 5770700d vsetvli zero, zero, e0x20, mf2, ta, ma +| : 0x000108fa 57a12196 vmul.vv v2, v2, v3 +| : 0x000108fe d775700d vsetvli a1, zero, e0x20, mf2, ta, ma +| : 0x00010902 57c2075e vmv.v.x v4, a5 +| : 0x00010906 57f0870d vsetvli zero, a5, e0x40, m1, ta, ma +| : 0x0001090a a7f20602 vse64.v v5, (a3) +| : 0x0001090e d7a2234a vsext.vf2 v5, v2 +| : 0x00010912 1d8f sub a4, a4, a5 +| : 0x00010914 aa96 add a3, a3, a0 +| : 0x00010916 a7720602 vse64.v v5, (a2) +| : 0x0001091a d775700d vsetvli a1, zero, e0x20, mf2, ta, ma +| : 0x0001091e d7001202 vadd.vv v1, v1, v4 +| : 0x00010922 2a96 add a2, a2, a0 +| `=< 0x00010924 4dff bnez a4, 0x108de +| 0x00010926 4965 lui a0, 0x12 +| 0x00010928 130585a2 addi a0, a0, -0x5d8 +| 0x0001092c eff05fc6 jal sym.imp.puts ; int puts(const char *s) +| 0x00010930 ce86 mv a3, s3 +| 0x00010932 2686 mv a2, s1 +| 0x00010934 da85 mv a1, s6 +| 0x00010936 2285 mv a0, s0 +| 0x00010938 ef00e031 jal sym.test_reductions +| 0x0001093c 5286 mv a2, s4 +| 0x0001093e da85 mv a1, s6 +| 0x00010940 2285 mv a0, s0 +| 0x00010942 ef008072 jal sym.test_comparisons +| 0x00010946 5e86 mv a2, s7 +| 0x00010948 a285 mv a1, s0 +| 0x0001094a 5685 mv a0, s5 +| 0x0001094c ef00607b jal sym.test_shifts +| 0x00010950 5e86 mv a2, s7 +| 0x00010952 e285 mv a1, s8 +| 0x00010954 5685 mv a0, s5 +| 0x00010956 ef009005 jal sym.test_bitwise +| 0x0001095a 6266 ld a2, 0x18(sp) +| 0x0001095c ee85 mv a1, s11 +| 0x0001095e 6685 mv a0, s9 +| 0x00010960 ef00300f jal sym.test_saturating +| 0x00010964 5286 mv a2, s4 +| 0x00010966 ee85 mv a1, s11 +| 0x00010968 6685 mv a0, s9 +| 0x0001096a ef007017 jal sym.test_widening +| 0x0001096e e266 ld a3, 0x18(sp) +| 0x00010970 2286 mv a2, s0 +| 0x00010972 13070040 li a4, 0x400 +| .-> 0x00010976 d777f70c vsetvli a5, a4, e0x10, mf2, ta, ma +| : 0x0001097a 87600602 vle32.v v1, (a2) +| : 0x0001097e 13952700 slli a0, a5, 2 +| : 0x00010982 93951700 slli a1, a5, 1 +| : 0x00010986 1d8f sub a4, a4, a5 +| : 0x00010988 2a96 add a2, a2, a0 +| : 0x0001098a d73014b6 vnsra.wi v1, v1, 8 +| : 0x0001098e a7d00602 vse16.v v1, (a3) +| : 0x00010992 ae96 add a3, a3, a1 +| `=< 0x00010994 6df3 bnez a4, 0x10976 +| 0x00010996 4a86 mv a2, s2 +| 0x00010998 ce85 mv a1, s3 +| 0x0001099a 2685 mv a0, s1 +| 0x0001099c ef00701c jal sym.test_float_ops +| 0x000109a0 ca86 mv a3, s2 +| 0x000109a2 6a86 mv a2, s10 +| 0x000109a4 ce85 mv a1, s3 +| 0x000109a6 2685 mv a0, s1 +| 0x000109a8 ef00f026 jal sym.test_fma +| 0x000109ac 4a86 mv a2, s2 +| 0x000109ae ce85 mv a1, s3 +| 0x000109b0 2685 mv a0, s1 +| 0x000109b2 ef007030 jal sym.test_float_comparisons +| 0x000109b6 ca86 mv a3, s2 +| 0x000109b8 2286 mv a2, s0 +| 0x000109ba 13070040 li a4, 0x400 +| .-> 0x000109be d777070d vsetvli a5, a4, e0x20, m1, ta, ma +| : 0x000109c2 87600602 vle32.v v1, (a2) +| : 0x000109c6 93952700 slli a1, a5, 2 +| : 0x000109ca 1d8f sub a4, a4, a5 +| : 0x000109cc 2e96 add a2, a2, a1 +| : 0x000109ce d790114a vfcvt.f.x.v v1, v1 +| : 0x000109d2 a7e00602 vse32.v v1, (a3) +| : 0x000109d6 ae96 add a3, a3, a1 +| `=< 0x000109d8 7df3 bnez a4, 0x109be +| 0x000109da d286 mv a3, s4 +| 0x000109dc 2686 mv a2, s1 +| 0x000109de 13070040 li a4, 0x400 +| .-> 0x000109e2 d777070d vsetvli a5, a4, e0x20, m1, ta, ma +| : 0x000109e6 87600602 vle32.v v1, (a2) +| : 0x000109ea 93952700 slli a1, a5, 2 +| : 0x000109ee 1d8f sub a4, a4, a5 +| : 0x000109f0 2e96 add a2, a2, a1 +| : 0x000109f2 d790134a vfcvt.rtz.x.f.v v1, v1 +| : 0x000109f6 a7e00602 vse32.v v1, (a3) +| : 0x000109fa ae96 add a3, a3, a1 +| `=< 0x000109fc 7df3 bnez a4, 0x109e2 +| 0x000109fe 4a86 mv a2, s2 +| 0x00010a00 ce85 mv a1, s3 +| 0x00010a02 2685 mv a0, s1 +| 0x00010a04 ef003036 jal sym.test_sign_injection +| 0x00010a08 ca85 mv a1, s2 +| 0x00010a0a 2685 mv a0, s1 +| 0x00010a0c ef00703d jal sym.test_strided_access +| 0x00010a10 4a86 mv a2, s2 +| 0x00010a12 6a88 mv a6, s10 +| 0x00010a14 4e85 mv a0, s3 +| 0x00010a16 a685 mv a1, s1 +| 0x00010a18 93060040 li a3, 0x400 +| .-> 0x00010a1c d7f7060d vsetvli a5, a3, e0x20, m1, ta, ma +| : 0x00010a20 87e10502 vle32.v v3, (a1) +| : 0x00010a24 07610502 vle32.v v2, (a0) +| : 0x00010a28 87600802 vle32.v v1, (a6) +| : 0x00010a2c 13972700 slli a4, a5, 2 +| : 0x00010a30 9d8e sub a3, a3, a5 +| : 0x00010a32 ba95 add a1, a1, a4 +| : 0x00010a34 3a95 add a0, a0, a4 +| : 0x00010a36 57912102 vfadd.vv v2, v2, v3 +| : 0x00010a3a 3a98 add a6, a6, a4 +| : 0x00010a3c d7101102 vfadd.vv v1, v1, v2 +| : 0x00010a40 a7600602 vse32.v v1, (a2) +| : 0x00010a44 3a96 add a2, a2, a4 +| `=< 0x00010a46 f9fa bnez a3, 0x10a1c +| 0x00010a48 a276 ld a3, 0x28(sp) +| 0x00010a4a 0265 ld a0, 0(sp) +| 0x00010a4c a265 ld a1, 8(sp) +| 0x00010a4e 13070020 li a4, 0x200 +| .-> 0x00010a52 d777870d vsetvli a5, a4, e0x40, m1, ta, ma +| : 0x00010a56 07f10502 vle64.v v2, (a1) +| : 0x00010a5a 87700502 vle64.v v1, (a0) +| : 0x00010a5e 13963700 slli a2, a5, 3 +| : 0x00010a62 1d8f sub a4, a4, a5 +| : 0x00010a64 b295 add a1, a1, a2 +| : 0x00010a66 3295 add a0, a0, a2 +| : 0x00010a68 d7001102 vadd.vv v1, v1, v2 +| : 0x00010a6c a7f00602 vse64.v v1, (a3) +| : 0x00010a70 b296 add a3, a3, a2 +| `=< 0x00010a72 65f3 bnez a4, 0x10a52 +| 0x00010a74 4265 ld a0, 0x10(sp) +| 0x00010a76 2286 mv a2, s0 +| 0x00010a78 e685 mv a1, s9 +| 0x00010a7a ef007052 jal sym.test_mixed_width +| 0x00010a7e 13064006 li a2, 0x64 +| 0x00010a82 d777000d vsetvli a5, zero, e0x20, m1, ta, ma +| 0x00010a86 5744065e vmv.v.x v8, a2 +| 0x00010a8a de86 mv a3, s7 +| 0x00010a8c 6285 mv a0, s8 +| 0x00010a8e d685 mv a1, s5 +| 0x00010a90 13070040 li a4, 0x400 +| .-> 0x00010a94 d777070d vsetvli a5, a4, e0x20, m1, ta, ma +| : 0x00010a98 07e10502 vle32.v v2, (a1) +| : 0x00010a9c 87600502 vle32.v v1, (a0) +| : 0x00010aa0 13962700 slli a2, a5, 2 +| : 0x00010aa4 1d8f sub a4, a4, a5 +| : 0x00010aa6 b295 add a1, a1, a2 +| : 0x00010aa8 3295 add a0, a0, a2 +| : 0x00010aaa d7201122 vaaddu.vv v1, v1, v2 +| : 0x00010aae a7e00602 vse32.v v1, (a3) +| : 0x00010ab2 b296 add a3, a3, a2 +| `=< 0x00010ab4 65f3 bnez a4, 0x10a94 +| 0x00010ab6 1307c0f9 li a4, -0x64 +| 0x00010aba d777000d vsetvli a5, zero, e0x20, m1, ta, ma +| 0x00010abe 5741075e vmv.v.x v2, a4 +| 0x00010ac2 d286 mv a3, s4 +| 0x00010ac4 2286 mv a2, s0 +| 0x00010ac6 13070040 li a4, 0x400 +| .-> 0x00010aca d777070d vsetvli a5, a4, e0x20, m1, ta, ma +| : 0x00010ace 87600602 vle32.v v1, (a2) +| : 0x00010ad2 93952700 slli a1, a5, 2 +| : 0x00010ad6 1d8f sub a4, a4, a5 +| : 0x00010ad8 2e96 add a2, a2, a1 +| : 0x00010ada d700111e vmax.vv v1, v1, v2 +| : 0x00010ade d7001416 vmin.vv v1, v1, v8 +| : 0x00010ae2 a7e00602 vse32.v v1, (a3) +| : 0x00010ae6 ae96 add a3, a3, a1 +| `=< 0x00010ae8 6df3 bnez a4, 0x10aca +| 0x00010aea d285 mv a1, s4 +| 0x00010aec 2285 mv a0, s0 +| 0x00010aee ef005057 jal sym.test_abs_neg +| 0x00010af2 5286 mv a2, s4 +| 0x00010af4 da85 mv a1, s6 +| 0x00010af6 2285 mv a0, s0 +| 0x00010af8 ef00505b jal sym.test_minmax +| 0x00010afc 5e86 mv a2, s7 +| 0x00010afe e285 mv a1, s8 +| 0x00010b00 5685 mv a0, s5 +| 0x00010b02 ef00f05f jal sym.test_unsigned_ops +| 0x00010b06 0276 ld a2, 0x20(sp) +| 0x00010b08 d286 mv a3, s4 +| 0x00010b0a da85 mv a1, s6 +| 0x00010b0c 2285 mv a0, s0 +| 0x00010b0e ef007064 jal sym.test_madd +| 0x00010b12 4965 lui a0, 0x12 +| 0x00010b14 130505a7 addi a0, a0, -0x590 +| 0x00010b18 eff09fa7 jal sym.imp.puts ; int puts(const char *s) +| 0x00010b1c 2285 mv a0, s0 +| 0x00010b1e eff03fa9 jal sym.imp.free ; void free(void *ptr) +| 0x00010b22 5a85 mv a0, s6 +| 0x00010b24 eff0dfa8 jal sym.imp.free ; void free(void *ptr) +| 0x00010b28 0275 ld a0, 0x20(sp) +| 0x00010b2a eff07fa8 jal sym.imp.free ; void free(void *ptr) +| 0x00010b2e 5285 mv a0, s4 +| 0x00010b30 eff01fa8 jal sym.imp.free ; void free(void *ptr) +| 0x00010b34 6685 mv a0, s9 +| 0x00010b36 eff0bfa7 jal sym.imp.free ; void free(void *ptr) +| 0x00010b3a 6e85 mv a0, s11 +| 0x00010b3c eff05fa7 jal sym.imp.free ; void free(void *ptr) +| 0x00010b40 6265 ld a0, 0x18(sp) +| 0x00010b42 eff0ffa6 jal sym.imp.free ; void free(void *ptr) +| 0x00010b46 4265 ld a0, 0x10(sp) +| 0x00010b48 eff09fa6 jal sym.imp.free ; void free(void *ptr) +| 0x00010b4c 2265 ld a0, 8(sp) +| 0x00010b4e eff03fa6 jal sym.imp.free ; void free(void *ptr) +| 0x00010b52 0265 ld a0, 0(sp) +| 0x00010b54 eff0dfa5 jal sym.imp.free ; void free(void *ptr) +| 0x00010b58 2275 ld a0, 0x28(sp) +| 0x00010b5a eff07fa5 jal sym.imp.free ; void free(void *ptr) +| 0x00010b5e 2685 mv a0, s1 +| 0x00010b60 eff01fa5 jal sym.imp.free ; void free(void *ptr) +| 0x00010b64 4e85 mv a0, s3 +| 0x00010b66 eff0bfa4 jal sym.imp.free ; void free(void *ptr) +| 0x00010b6a 6a85 mv a0, s10 +| 0x00010b6c eff05fa4 jal sym.imp.free ; void free(void *ptr) +| 0x00010b70 4a85 mv a0, s2 +| 0x00010b72 eff0ffa3 jal sym.imp.free ; void free(void *ptr) +| 0x00010b76 5685 mv a0, s5 +| 0x00010b78 eff09fa3 jal sym.imp.free ; void free(void *ptr) +| 0x00010b7c 6285 mv a0, s8 +| 0x00010b7e eff03fa3 jal sym.imp.free ; void free(void *ptr) +| 0x00010b82 5e85 mv a0, s7 +| 0x00010b84 eff0dfa2 jal sym.imp.free ; void free(void *ptr) +| 0x00010b88 b270 ld ra, 0x128(sp) +| 0x00010b8a 1274 ld s0, 0x120(sp) +| 0x00010b8c f264 ld s1, 0x118(sp) +| 0x00010b8e 5269 ld s2, 0x110(sp) +| 0x00010b90 b269 ld s3, 0x108(sp) +| 0x00010b92 126a ld s4, 0x100(sp) +| 0x00010b94 ee7a ld s5, 0xf8(sp) +| 0x00010b96 4e7b ld s6, 0xf0(sp) +| 0x00010b98 ae7b ld s7, 0xe8(sp) +| 0x00010b9a 0e7c ld s8, 0xe0(sp) +| 0x00010b9c ee6c ld s9, 0xd8(sp) +| 0x00010b9e 4e6d ld s10, 0xd0(sp) +| 0x00010ba0 ae6d ld s11, 0xc8(sp) +| 0x00010ba2 0145 li a0, 0 +| 0x00010ba4 5561 addi sp, sp, 0x130 +| 0x00010ba6 8280 ret +EOF +RUN + +NAME=Vector instructions: madd +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x00011960 d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 +| : 0x00011964 87610302 vle32.v v3, (t1) +| : 0x00011968 87600e02 vle32.v v1, (t3) +| : 0x0001196c 07e10e02 vle32.v v2, (t4) +| : 0x00011970 13972700 slli a4, a5, 2 ; arg6 +| : 0x00011974 3308f840 sub a6, a6, a5 ; arg6 +| : 0x00011978 3a93 add t1, t1, a4 +| : 0x0001197a 3a9e add t3, t3, a4 +| : 0x0001197c ba9e add t4, t4, a4 +| : 0x0001197e d7a021a6 vmadd.vv v1, v3, v2 +| : 0x00011982 a7e00802 vse32.v v1, (a7) ; arg8 +| : 0x00011986 ba98 add a7, a7, a4 ; arg8 +| `=< 0x00011988 e31c08fc bnez a6, 0x11960 +| 0x0001198c 13080040 li a6, 0x400 +| .-> 0x00011990 d777080d vsetvli a5, a6, e0x20, m1, ta, ma ; arg6 +| : 0x00011994 87610602 vle32.v v3, (a2) ; arg3 +| : 0x00011998 07610502 vle32.v v2, (a0) ; arg1 +| : 0x0001199c 87e00502 vle32.v v1, (a1) ; arg2 +| : 0x000119a0 13972700 slli a4, a5, 2 ; arg6 +| : 0x000119a4 3308f840 sub a6, a6, a5 ; arg6 +| : 0x000119a8 3a96 add a2, a2, a4 ; arg3 +| : 0x000119aa 3a95 add a0, a0, a4 ; arg1 +| : 0x000119ac ba95 add a1, a1, a4 ; arg2 +| : 0x000119ae d72031ae vnmsub.vv v1, v2, v3 +| : 0x000119b2 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000119b6 ba96 add a3, a3, a4 ; arg4 +| `=< 0x000119b8 e31c08fc bnez a6, 0x11990 +| 0x000119bc 8280 ret +EOF +RUN + +NAME=Vector instructions: bitwise +FILE=bins/elf/riscv_vec_arith +CMDS=< 0x000111b8 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000111bc 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x000111c0 87600302 vle32.v v1, (t1) +| : 0x000111c4 13982700 slli a6, a5, 2 ; arg6 +| : 0x000111c8 1d8f sub a4, a4, a5 ; arg6 +| : 0x000111ca c298 add a7, a7, a6 ; arg8 +| : 0x000111cc 4293 add t1, t1, a6 +| : 0x000111ce d7001126 vand.vv v1, v1, v2 +| : 0x000111d2 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x000111d6 c296 add a3, a3, a6 ; arg4 +| `=< 0x000111d8 65f3 bnez a4, 0x111b8 +| 0x000111da b286 mv a3, a2 +| 0x000111dc 2e83 mv t1, a1 +| 0x000111de aa88 mv a7, a0 +| 0x000111e0 13070040 li a4, 0x400 +| .-> 0x000111e4 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x000111e8 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x000111ec 87600302 vle32.v v1, (t1) +| : 0x000111f0 13982700 slli a6, a5, 2 ; arg6 +| : 0x000111f4 1d8f sub a4, a4, a5 ; arg6 +| : 0x000111f6 c298 add a7, a7, a6 ; arg8 +| : 0x000111f8 4293 add t1, t1, a6 +| : 0x000111fa d700112a vor.vv v1, v1, v2 +| : 0x000111fe a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x00011202 c296 add a3, a3, a6 ; arg4 +| `=< 0x00011204 65f3 bnez a4, 0x111e4 +| 0x00011206 b286 mv a3, a2 +| 0x00011208 aa88 mv a7, a0 +| 0x0001120a 13070040 li a4, 0x400 +| .-> 0x0001120e d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011212 07e10802 vle32.v v2, (a7) ; arg8 +| : 0x00011216 87e00502 vle32.v v1, (a1) ; arg2 +| : 0x0001121a 13982700 slli a6, a5, 2 ; arg6 +| : 0x0001121e 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011220 c298 add a7, a7, a6 ; arg8 +| : 0x00011222 c295 add a1, a1, a6 ; arg2 +| : 0x00011224 d700112e vxor.vv v1, v1, v2 +| : 0x00011228 a7e00602 vse32.v v1, (a3) ; arg4 +| : 0x0001122c c296 add a3, a3, a6 ; arg4 +| `=< 0x0001122e 65f3 bnez a4, 0x1120e +| 0x00011230 13070040 li a4, 0x400 +| .-> 0x00011234 d777070d vsetvli a5, a4, e0x20, m1, ta, ma ; arg6 +| : 0x00011238 87600502 vle32.v v1, (a0) ; arg1 +| : 0x0001123c 93962700 slli a3, a5, 2 ; arg6 +| : 0x00011240 1d8f sub a4, a4, a5 ; arg6 +| : 0x00011242 3695 add a0, a0, a3 ; arg1 +| : 0x00011244 d7b01f2e vnot.v v1, v1 +| : 0x00011248 a7600602 vse32.v v1, (a2) ; arg3 +| : 0x0001124c 3696 add a2, a2, a3 ; arg3 +| `=< 0x0001124e 7df3 bnez a4, 0x11234 +| 0x00011250 8280 ret +EOF +RUN + +NAME=rotate_right_var +FILE=bins/elf/riscv_bitmanip +CMDS=< 0x00010554 13050008 li a0, 0x80 +| |||,==< 0x00010558 638a0600 beqz a3, 0x1056c +| ||||| 0x0001055c 13051000 li a0, 1 +| ||||| 0x00010560 67800000 ret +| ||`---> 0x00010564 13050004 li a0, 0x40 +| ||,===< 0x00010568 63940600 bnez a3, 0x10570 +| .`--`--> 0x0001056c 67800000 ret +| : |`---> 0x00010570 13052000 li a0, 2 +| : | | 0x00010574 67800000 ret +| : `----> 0x00010578 13050002 li a0, 0x20 +| `======< 0x0001057c e38806fe beqz a3, 0x1056c +| | 0x00010580 13054000 li a0, 4 +| | 0x00010584 67800000 ret +| `-> 0x00010588 13050030 li a0, 0x300 +\ 0x0001058c 67800000 ret +EOF +RUN + + +NAME=fclass_h +FILE=bins/elf/riscv_float_rounding +CMDS=< 0x000105d8 13050008 li a0, 0x80 +| ||,==< 0x000105dc 63880700 beqz a5, 0x105ec +| |||| 0x000105e0 13051000 li a0, 1 +| |||| 0x000105e4 67800000 ret +| |||`-> 0x000105e8 13050030 li a0, 0x300 +| .`-`.-> 0x000105ec 67800000 ret +| : `---> 0x000105f0 d30700f0 fmv.w.x fa5, zero +| : : 0x000105f4 530707f0 fmv.w.x fa4, a4 +| : : 0x000105f8 5327f7a0 feq.s a4, fa4, fa5 +| : ,==< 0x000105fc 630a0700 beqz a4, 0x10610 +| : |: 0x00010600 13050001 li a0, 0x10 +| `=====< 0x00010604 e38407fe beqz a5, 0x105ec +| |: 0x00010608 13058000 li a0, 8 +| |: 0x0001060c 67800000 ret +| `--> 0x00010610 13050002 li a0, 0x20 +| `=< 0x00010614 e38c07fc beqz a5, 0x105ec +| 0x00010618 13054000 li a0, 4 +\ 0x0001061c 67800000 ret +EOF +RUN + + +NAME=fround_d_attr +FILE=bins/elf/riscv_float_rounding +CMDS=< 0x000104cc 13050008 li a0, 0x80 +| |||,==< 0x000104d0 638a0700 beqz a5, 0x104e4 +| ||||| 0x000104d4 13051000 li a0, 1 +| ||||| 0x000104d8 67800000 ret +| ||`---> 0x000104dc 13050004 li a0, 0x40 +| ||,===< 0x000104e0 63940700 bnez a5, 0x104e8 +| .`--`--> 0x000104e4 67800000 ret +| : |`---> 0x000104e8 13052000 li a0, 2 +| : | | 0x000104ec 67800000 ret +| : `----> 0x000104f0 13050002 li a0, 0x20 +| `======< 0x000104f4 e38807fe beqz a5, 0x104e4 +| | 0x000104f8 13054000 li a0, 4 +| | 0x000104fc 67800000 ret +| `-> 0x00010500 13050030 li a0, 0x300 +\ 0x00010504 67800000 ret +EOF +RUN + +NAME=fround_s +FILE=bins/elf/riscv_float_rounding +CMDS=< Date: Mon, 27 Oct 2025 02:32:10 +0300 Subject: [PATCH 2/3] modernize Capstone-based RISCV plugin and add huge test coverage --- librz/arch/meson.build | 5 +- librz/arch/p/analysis/analysis_riscv_cs.c | 1812 +++++++++++++- librz/arch/p/analysis/analysis_riscv_utils.h | 136 ++ librz/arch/p/arch_riscv_cs.c | 237 ++ librz/arch/p/arch_riscv_extension_parser.inc | 2146 +++++++++++++++++ librz/arch/p/asm/asm_riscv_cs.c | 6 +- librz/bin/format/elf/elf_info.c | 148 +- librz/bin/format/elf/elf_relocs_patching.c | 386 ++- librz/bin/format/elf/glibc_elf.h | 11 + librz/bin/p/bin_elf.inc | 1 + librz/include/rz_analysis.h | 3 + meson_options.txt | 2 +- .../capstone-capstone-riscv-updated.wrap | 6 + subprojects/capstone-next.wrap | 2 +- .../packagefiles/capstone-next/meson.build | 7 + .../capstone-riscv-updated/meson.build | 148 ++ sys/riscv_extension_parser_generator.py | 335 +++ test/db/analysis/riscv | 25 +- test/db/asm/riscv_32 | 156 +- test/db/esil/riscv_32 | 84 - test/db/esil/riscv_64 | 69 - test/db/formats/elf/elf-riscv64 | 106 +- test/db/formats/elf/riscv-relocs | 929 +++++++ test/unit/test_analysis_op.c | 4 +- 24 files changed, 6424 insertions(+), 340 deletions(-) create mode 100644 librz/arch/p/analysis/analysis_riscv_utils.h create mode 100644 librz/arch/p/arch_riscv_extension_parser.inc create mode 100644 subprojects/capstone-capstone-riscv-updated.wrap create mode 100644 subprojects/packagefiles/capstone-riscv-updated/meson.build create mode 100644 sys/riscv_extension_parser_generator.py delete mode 100644 test/db/esil/riscv_32 delete mode 100644 test/db/esil/riscv_64 create mode 100644 test/db/formats/elf/riscv-relocs diff --git a/librz/arch/meson.build b/librz/arch/meson.build index 430dcd0099a..702a36ffc54 100644 --- a/librz/arch/meson.build +++ b/librz/arch/meson.build @@ -315,7 +315,7 @@ arch_isa_includes = [ 'isa', ] -if capstone_dep.version() == 'next' or capstone_dep.version().split('.')[0].to_int() > 4 +if capstone_dep.version() == 'next' or capstone_dep.version().split('.')[0].to_int() > 6 # plugins arch_plugins_list += [ 'riscv_cs', @@ -388,9 +388,6 @@ if get_option('use_gpl') 'isa_gnu/cris/cris-opc.c', 'isa_gnu/lanai/lanai-dis.c', 'isa_gnu/lanai/lanai-opc.c', - # 'isa_gnu/riscv/riscv-opc.c', - # 'isa_gnu/riscv/riscv.c', - 'isa_gnu/sparc/sparc-opc.c', 'isa_gnu/vax/vax-dis.c', # 'isa_gnu/z80/expressions.c', # 'isa_gnu/z80/z80.c', diff --git a/librz/arch/p/analysis/analysis_riscv_cs.c b/librz/arch/p/analysis/analysis_riscv_cs.c index cd07add92ac..62a1141d745 100644 --- a/librz/arch/p/analysis/analysis_riscv_cs.c +++ b/librz/arch/p/analysis/analysis_riscv_cs.c @@ -1,13 +1,17 @@ // SPDX-FileCopyrightText: 2013-2020 pancake // SPDX-License-Identifier: LGPL-3.0-only +#include +#include "rz_reg.h" +#include "rz_util/rz_log.h" #include #include #include #include -// http://www.mrc.uidaho.edu/mrc/people/jff/digital/RISCVir.html +#include "analysis_riscv_utils.h" +#include #define OPERAND(x) insn->detail->riscv.operands[x] #define REGID(x) insn->detail->riscv.operands[x].reg @@ -19,10 +23,7 @@ #define OPCOUNT() insn->detail->riscv.op_count // TODO scale and disp -#define SET_VAL(op, i) \ - if ((i) < OPCOUNT() && OPERAND(i).type == RISCV_OP_IMM) { \ - (op)->val = OPERAND(i).imm; \ - } +#define NEXT_ADDRESS(op) (op->addr + op->size) #define CREATE_SRC_DST_3(op) \ (op)->src[0] = rz_analysis_value_new(); \ @@ -57,6 +58,8 @@ SET_SRC_DST_3_REGS(op); \ } +static void set_stack_effect(RzAnalysisOp *op, cs_insn *insn); + static RzStructuredData *riscv_opex(csh handle, cs_insn *insn) { if (!insn->detail) { return NULL; @@ -144,19 +147,29 @@ static void op_fillval(RzAnalysis *analysis, RzAnalysisOp *op, csh *handle, cs_i case RZ_ANALYSIS_OP_TYPE_LOAD: if (OPERAND(1).type == RISCV_OP_MEM) { ZERO_FILL(ctx->reg); + op->dst = rz_analysis_value_new(); + op->dst->type = RZ_ANALYSIS_VAL_REG; + op->dst->reg = rz_reg_get(analysis->reg, cs_reg_name(*handle, FIRST_WRITTEN_REGID(insn)), RZ_REG_TYPE_GPR); op->src[0] = rz_analysis_value_new(); + op->src[0]->type = RZ_ANALYSIS_VAL_MEM; op->src[0]->reg = &ctx->reg; parse_reg_name(op->src[0]->reg, *handle, insn, 1); op->src[0]->delta = OPERAND(1).mem.disp; + op->src[0]->memref = op->refptr; } break; case RZ_ANALYSIS_OP_TYPE_STORE: if (OPERAND(1).type == RISCV_OP_MEM) { ZERO_FILL(ctx->reg); op->dst = rz_analysis_value_new(); + op->dst->type = RZ_ANALYSIS_VAL_MEM; op->dst->reg = &ctx->reg; parse_reg_name(op->dst->reg, *handle, insn, 1); op->dst->delta = OPERAND(1).mem.disp; + op->dst->memref = op->refptr; + op->src[0] = rz_analysis_value_new(); + op->src[0]->type = RZ_ANALYSIS_VAL_REG; + op->src[0]->reg = rz_reg_get(analysis->reg, cs_reg_name(*handle, FIRST_READ_REGID(insn)), RZ_REG_TYPE_GPR); } break; case RZ_ANALYSIS_OP_TYPE_SHL: @@ -209,20 +222,561 @@ static void set_opdir(RzAnalysisOp *op) { } } -static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask) { +static inline bool group_exists_in(uint8_t *groups, uint8_t groups_count, uint8_t group) { + for (int i = 0; i < groups_count; i++) { + if (groups[i] == group) { + return true; + } + } + return false; +} + +static void set_op_sign(RzAnalysisOp *op, cs_insn *insn) { + switch (insn->id) { + // Signed loads + case RISCV_INS_LB: + case RISCV_INS_LH: + case RISCV_INS_LW: + case RISCV_INS_LD: + case RISCV_INS_TH_LRB: + case RISCV_INS_TH_LRH: + case RISCV_INS_TH_LRW: + case RISCV_INS_TH_LRD: + // Core-V loads + case RISCV_INS_CV_LB: + case RISCV_INS_CV_LBU: + case RISCV_INS_CV_LH: + case RISCV_INS_CV_LHU: + case RISCV_INS_CV_LW: + op->sign = true; + break; + // Signed Arithmetic & Comparison + case RISCV_INS_DIV: + case RISCV_INS_DIVW: + case RISCV_INS_REM: + case RISCV_INS_REMW: + case RISCV_INS_MULH: + case RISCV_INS_MULHSU: + case RISCV_INS_SLT: + case RISCV_INS_SLTI: + case RISCV_INS_SRA: + case RISCV_INS_SRAI: + case RISCV_INS_SRAW: + case RISCV_INS_SRAIW: + case RISCV_INS_C_SRAI64: + case RISCV_INS_BLT: + case RISCV_INS_BGE: + // Atomic signed (AMOMIN/MAX) + case RISCV_INS_AMOMAX_W: + case RISCV_INS_AMOMAX_D: + case RISCV_INS_AMOMIN_W: + case RISCV_INS_AMOMIN_D: + // Bitmanip signed + case RISCV_INS_MIN: + case RISCV_INS_MAX: + // Core-V signs + case RISCV_INS_CV_ABS: + case RISCV_INS_CV_ABS_B: + case RISCV_INS_CV_ABS_H: + case RISCV_INS_CV_ADD_B: + case RISCV_INS_CV_ADD_H: + case RISCV_INS_CV_AVG_B: + case RISCV_INS_CV_AVG_H: + case RISCV_INS_CV_MAX_B: + case RISCV_INS_CV_MAX_H: + case RISCV_INS_CV_MIN_B: + case RISCV_INS_CV_MIN_H: + case RISCV_INS_CV_SUB_B: + case RISCV_INS_CV_SUB_H: + op->sign = true; + break; + // RV64 "W" instructions (result is sign-extended to 64 bits) + case RISCV_INS_ADDW: + case RISCV_INS_ADDIW: + case RISCV_INS_SUBW: + case RISCV_INS_MULW: + case RISCV_INS_C_ADDW: + case RISCV_INS_C_ADDIW: + case RISCV_INS_C_SUBW: + op->sign = true; + break; + // FP Comparison & Sign-Aware Ops + case RISCV_INS_FEQ_S: + case RISCV_INS_FLT_S: + case RISCV_INS_FLE_S: + case RISCV_INS_FEQ_D: + case RISCV_INS_FLT_D: + case RISCV_INS_FLE_D: + case RISCV_INS_FEQ_H: + case RISCV_INS_FLT_H: + case RISCV_INS_FLE_H: + case RISCV_INS_FMIN_S: + case RISCV_INS_FMAX_S: + case RISCV_INS_FMIN_D: + case RISCV_INS_FMAX_D: + case RISCV_INS_FMIN_H: + case RISCV_INS_FMAX_H: + op->sign = true; + break; + // Explicit sign extensions + case RISCV_INS_SEXT_B: + case RISCV_INS_SEXT_H: + case RISCV_INS_C_SEXT_B: + case RISCV_INS_C_SEXT_H: + op->sign = true; + break; + default: + break; + } +} + +static void set_op_data_size(RzAnalysisOp *op, cs_insn *insn) { + switch (insn->id) { + // 1 byte + case RISCV_INS_LB: + case RISCV_INS_LBU: + case RISCV_INS_SB: + case RISCV_INS_C_LBU: + case RISCV_INS_C_SB: + case RISCV_INS_TH_LRB: + case RISCV_INS_TH_LRBU: + op->refptr = 1; + break; + // 2 bytes + case RISCV_INS_LH: + case RISCV_INS_LHU: + case RISCV_INS_SH: + case RISCV_INS_FLH: + case RISCV_INS_FSH: + case RISCV_INS_C_LH: + case RISCV_INS_C_LHU: + case RISCV_INS_C_SH: + case RISCV_INS_TH_LRH: + case RISCV_INS_TH_LRHU: + op->refptr = 2; + break; + // 4 bytes + case RISCV_INS_LW: + case RISCV_INS_LWU: + case RISCV_INS_SW: + case RISCV_INS_FLW: + case RISCV_INS_FSW: + case RISCV_INS_C_LW: + case RISCV_INS_C_LWSP: + case RISCV_INS_C_SW: + case RISCV_INS_C_SWSP: + case RISCV_INS_C_FLW: + case RISCV_INS_C_FLWSP: + case RISCV_INS_C_FSW: + case RISCV_INS_C_FSWSP: + case RISCV_INS_TH_LRW: + case RISCV_INS_TH_LRWU: + case RISCV_INS_LR_W: + case RISCV_INS_LR_W_AQ: + case RISCV_INS_LR_W_AQRL: + case RISCV_INS_LR_W_RL: + case RISCV_INS_SC_W: + case RISCV_INS_SC_W_AQ: + case RISCV_INS_SC_W_AQRL: + case RISCV_INS_SC_W_RL: + // Atomic 4-byte + case RISCV_INS_AMOSWAP_W: + case RISCV_INS_AMOADD_W: + case RISCV_INS_AMOAND_W: + case RISCV_INS_AMOOR_W: + case RISCV_INS_AMOXOR_W: + case RISCV_INS_AMOMAX_W: + case RISCV_INS_AMOMIN_W: + case RISCV_INS_AMOMAXU_W: + case RISCV_INS_AMOMINU_W: + case RISCV_INS_AMOCAS_W: + op->refptr = 4; + break; + // 8 bytes + case RISCV_INS_LD: + case RISCV_INS_SD: + case RISCV_INS_FLD: + case RISCV_INS_FSD: + case RISCV_INS_C_LD: + case RISCV_INS_C_LDSP: + case RISCV_INS_C_SD: + case RISCV_INS_C_SDSP: + case RISCV_INS_C_FLD: + case RISCV_INS_C_FLDSP: + case RISCV_INS_C_FSD: + case RISCV_INS_C_FSDSP: + case RISCV_INS_TH_LRD: + case RISCV_INS_LR_D: + case RISCV_INS_LR_D_AQ: + case RISCV_INS_LR_D_AQRL: + case RISCV_INS_LR_D_RL: + case RISCV_INS_SC_D: + case RISCV_INS_SC_D_AQ: + case RISCV_INS_SC_D_AQRL: + case RISCV_INS_SC_D_RL: + // Atomic 8-byte + case RISCV_INS_AMOSWAP_D: + case RISCV_INS_AMOADD_D: + case RISCV_INS_AMOAND_D: + case RISCV_INS_AMOOR_D: + case RISCV_INS_AMOXOR_D: + case RISCV_INS_AMOMAX_D: + case RISCV_INS_AMOMIN_D: + case RISCV_INS_AMOMAXU_D: + case RISCV_INS_AMOMINU_D: + case RISCV_INS_AMOCAS_D: + op->refptr = 8; + break; + // 16 bytes + case RISCV_INS_AMOCAS_Q: + op->refptr = 16; + break; + default: + break; + } +} + +static void set_op_val(RzAnalysisOp *op, cs_insn *insn) { + if (!insn->detail) { + return; + } + + uint8_t *groups = insn->detail->groups; + uint8_t groups_count = insn->detail->groups_count; + if (group_exists_in(groups, groups_count, RISCV_GRP_JUMP) || + group_exists_in(groups, groups_count, RISCV_GRP_CALL) || + group_exists_in(groups, groups_count, RISCV_GRP_BRANCH_RELATIVE)) { + return; + } + + // Exclude instructions where the immediate is a configuration bitfield + // to prevent misleading ASCII hints + switch (insn->id) { + case RISCV_INS_VSETVLI: + case RISCV_INS_VSETIVLI: + return; + } + + st64 imm = FIRST_IMM(insn); + if (imm != INT64_MAX) { + switch (insn->id) { + case RISCV_INS_LUI: + case RISCV_INS_C_LUI: + op->val = imm << 12; + break; + case RISCV_INS_AUIPC: + op->val = op->addr + (imm << 12); + break; + default: + op->val = imm; + break; + } + } +} + +static void set_op_eob(RzAnalysisOp *op, cs_insn *insn) { + switch (insn->id) { + case RISCV_INS_JAL: + case RISCV_INS_JALR: + case RISCV_INS_TAIL: + case RISCV_INS_JUMP: + case RISCV_INS_BEQ: + case RISCV_INS_BNE: + case RISCV_INS_BLT: + case RISCV_INS_BGE: + case RISCV_INS_BLTU: + case RISCV_INS_BGEU: + case RISCV_INS_ECALL: + case RISCV_INS_EBREAK: + case RISCV_INS_MRET: + case RISCV_INS_SRET: + case RISCV_INS_DRET: + case RISCV_INS_WFI: + case RISCV_INS_CM_POPRET: + case RISCV_INS_CM_POPRETZ: + case RISCV_INS_CM_JT: + case RISCV_INS_CM_JALT: + case RISCV_INS_C_J: + case RISCV_INS_C_JR: + case RISCV_INS_C_JAL: + case RISCV_INS_C_JALR: + case RISCV_INS_C_BEQZ: + case RISCV_INS_C_BNEZ: + case RISCV_INS_C_EBREAK: + // Core-V branches + case RISCV_INS_CV_BEQIMM: + case RISCV_INS_CV_BNEIMM: + op->eob = true; + break; + default: + break; + } +} + +static void set_op_cond(RzAnalysisOp *op, cs_insn *insn) { + switch (insn->id) { + case RISCV_INS_BEQ: + case RISCV_INS_C_BEQZ: + case RISCV_INS_CV_BEQIMM: + op->cond = RZ_TYPE_COND_EQ; + break; + case RISCV_INS_BNE: + case RISCV_INS_C_BNEZ: + case RISCV_INS_CV_BNEIMM: + op->cond = RZ_TYPE_COND_NE; + break; + case RISCV_INS_BLT: + op->cond = RZ_TYPE_COND_LT; + break; + case RISCV_INS_BGE: + op->cond = RZ_TYPE_COND_GE; + break; + case RISCV_INS_BLTU: + op->cond = RZ_TYPE_COND_LO; + break; + case RISCV_INS_BGEU: + op->cond = RZ_TYPE_COND_HS; + break; + default: + op->cond = RZ_TYPE_COND_AL; + break; + } +} + +static void set_op_family(RzAnalysisOp *op, cs_insn *insn) { + if (op->type & RZ_ANALYSIS_OP_TYPE_SIMD) { + op->family = RZ_ANALYSIS_OP_FAMILY_MMX; + return; + } + if (op->type & RZ_ANALYSIS_OP_TYPE_CRYPTO) { + op->family = RZ_ANALYSIS_OP_FAMILY_CRYPTO; + return; + } + + if (op->type & RZ_ANALYSIS_OP_TYPE_SYNC) { + op->family = RZ_ANALYSIS_OP_FAMILY_THREAD; + return; + } + + switch (insn->id) { + // Virtualization + case RISCV_INS_HFENCE_GVMA: + case RISCV_INS_HFENCE_VVMA: + case RISCV_INS_HLV_B: + case RISCV_INS_HLV_BU: + case RISCV_INS_HLV_D: + case RISCV_INS_HLV_H: + case RISCV_INS_HLV_HU: + case RISCV_INS_HLV_W: + case RISCV_INS_HLV_WU: + case RISCV_INS_HLVX_HU: + case RISCV_INS_HLVX_WU: + case RISCV_INS_HSV_B: + case RISCV_INS_HSV_D: + case RISCV_INS_HSV_H: + case RISCV_INS_HSV_W: + op->family = RZ_ANALYSIS_OP_FAMILY_VIRT; + break; + // Crypto (if not already handled by type check) + case RISCV_INS_AES32DSI: + case RISCV_INS_AES32DSMI: + case RISCV_INS_AES32ESI: + case RISCV_INS_AES32ESMI: + case RISCV_INS_AES64DS: + case RISCV_INS_AES64DSM: + case RISCV_INS_AES64ES: + case RISCV_INS_AES64ESM: + case RISCV_INS_AES64IM: + case RISCV_INS_AES64KS1I: + case RISCV_INS_AES64KS2: + case RISCV_INS_SHA256SIG0: + case RISCV_INS_SHA256SIG1: + case RISCV_INS_SHA256SUM0: + case RISCV_INS_SHA256SUM1: + case RISCV_INS_SHA512SIG0: + case RISCV_INS_SHA512SIG0H: + case RISCV_INS_SHA512SIG0L: + case RISCV_INS_SHA512SIG1: + case RISCV_INS_SHA512SIG1H: + case RISCV_INS_SHA512SIG1L: + case RISCV_INS_SHA512SUM0: + case RISCV_INS_SHA512SUM0R: + case RISCV_INS_SHA512SUM1: + case RISCV_INS_SHA512SUM1R: + case RISCV_INS_SM3P0: + case RISCV_INS_SM3P1: + case RISCV_INS_SM4ED: + case RISCV_INS_SM4KS: + op->family = RZ_ANALYSIS_OP_FAMILY_CRYPTO; + break; + // Floating Point + case RISCV_INS_FADD_S: + case RISCV_INS_FADD_D: + case RISCV_INS_FADD_H: + case RISCV_INS_FSUB_S: + case RISCV_INS_FSUB_D: + case RISCV_INS_FSUB_H: + case RISCV_INS_FMUL_S: + case RISCV_INS_FMUL_D: + case RISCV_INS_FMUL_H: + case RISCV_INS_FDIV_S: + case RISCV_INS_FDIV_D: + case RISCV_INS_FDIV_H: + case RISCV_INS_FSQRT_S: + case RISCV_INS_FSQRT_D: + case RISCV_INS_FSQRT_H: + case RISCV_INS_FMIN_S: + case RISCV_INS_FMIN_D: + case RISCV_INS_FMIN_H: + case RISCV_INS_FMAX_S: + case RISCV_INS_FMAX_D: + case RISCV_INS_FMAX_H: + case RISCV_INS_FEQ_S: + case RISCV_INS_FEQ_D: + case RISCV_INS_FEQ_H: + case RISCV_INS_FLT_S: + case RISCV_INS_FLT_D: + case RISCV_INS_FLT_H: + case RISCV_INS_FLE_S: + case RISCV_INS_FLE_D: + case RISCV_INS_FLE_H: + case RISCV_INS_FMADD_S: + case RISCV_INS_FMADD_D: + case RISCV_INS_FMADD_H: + case RISCV_INS_FMSUB_S: + case RISCV_INS_FMSUB_D: + case RISCV_INS_FMSUB_H: + case RISCV_INS_FNMADD_S: + case RISCV_INS_FNMADD_D: + case RISCV_INS_FNMADD_H: + case RISCV_INS_FNMSUB_S: + case RISCV_INS_FNMSUB_D: + case RISCV_INS_FNMSUB_H: + case RISCV_INS_FCVT_S_D: + case RISCV_INS_FCVT_D_S: + case RISCV_INS_FCVT_W_S: + case RISCV_INS_FCVT_WU_S: + case RISCV_INS_FCVT_S_W: + case RISCV_INS_FCVT_S_WU: + case RISCV_INS_FLW: + case RISCV_INS_FSW: + case RISCV_INS_FLD: + case RISCV_INS_FSD: + case RISCV_INS_FLH: + case RISCV_INS_FSH: + case RISCV_INS_C_FLW: + case RISCV_INS_C_FLWSP: + case RISCV_INS_C_FSW: + case RISCV_INS_C_FSWSP: + case RISCV_INS_C_FLD: + case RISCV_INS_C_FLDSP: + case RISCV_INS_C_FSD: + case RISCV_INS_C_FSDSP: + op->family = RZ_ANALYSIS_OP_FAMILY_FPU; + break; + // Privileged / System + case RISCV_INS_ECALL: + case RISCV_INS_EBREAK: + case RISCV_INS_MRET: + case RISCV_INS_SRET: + case RISCV_INS_DRET: + case RISCV_INS_WFI: + case RISCV_INS_CSRRW: + case RISCV_INS_CSRRS: + case RISCV_INS_CSRRC: + case RISCV_INS_CSRRWI: + case RISCV_INS_CSRRSI: + case RISCV_INS_CSRRCI: + case RISCV_INS_SFENCE_VMA: + case RISCV_INS_SINVAL_VMA: + case RISCV_INS_SFENCE_W_INVAL: + op->family = RZ_ANALYSIS_OP_FAMILY_PRIV; + break; + // Atomic (Thread/Sync) + case RISCV_INS_FENCE: + case RISCV_INS_FENCE_I: + case RISCV_INS_FENCE_TSO: + case RISCV_INS_ALIAS_PAUSE: + case RISCV_INS_LR_W: + case RISCV_INS_LR_D: + case RISCV_INS_SC_W: + case RISCV_INS_SC_D: + case RISCV_INS_AMOSWAP_W: + case RISCV_INS_AMOSWAP_D: + case RISCV_INS_AMOADD_W: + case RISCV_INS_AMOADD_D: + case RISCV_INS_AMOAND_W: + case RISCV_INS_AMOAND_D: + case RISCV_INS_AMOOR_W: + case RISCV_INS_AMOOR_D: + case RISCV_INS_AMOXOR_W: + case RISCV_INS_AMOXOR_D: + case RISCV_INS_AMOMAX_W: + case RISCV_INS_AMOMAX_D: + case RISCV_INS_AMOMIN_W: + case RISCV_INS_AMOMIN_D: + case RISCV_INS_AMOMAXU_W: + case RISCV_INS_AMOMAXU_D: + case RISCV_INS_AMOMINU_W: + case RISCV_INS_AMOMINU_D: + case RISCV_INS_AMOCAS_W: + case RISCV_INS_AMOCAS_D: + case RISCV_INS_AMOCAS_Q: + op->family = RZ_ANALYSIS_OP_FAMILY_THREAD; + break; + default: + op->family = RZ_ANALYSIS_OP_FAMILY_CPU; + break; + } +} + +static void set_op_extra_metadata(RzAnalysis *analysis, RzAnalysisOp *op, csh handle, cs_insn *insn) { + if (!insn->detail) { + return; + } + // Set destination register name + if (insn->detail->riscv.op_count > 0 && insn->detail->riscv.operands[0].type == RISCV_OP_REG && (insn->detail->riscv.operands[0].access & CS_AC_WRITE)) { + op->reg = cs_reg_name(handle, insn->detail->riscv.operands[0].reg); + } + + // Set indirect register name (base for loads/stores) + for (int i = 0; i < insn->detail->riscv.op_count; i++) { + if (insn->detail->riscv.operands[i].type == RISCV_OP_MEM) { + op->ireg = cs_reg_name(handle, insn->detail->riscv.operands[i].mem.base); + op->disp = insn->detail->riscv.operands[i].mem.disp; + break; + } + } + + // Set datatype + if (op->family == RZ_ANALYSIS_OP_FAMILY_FPU) { + op->datatype = RZ_ANALYSIS_DATATYPE_FLOAT; + } else if (op->type & RZ_ANALYSIS_OP_TYPE_LOAD || op->type & RZ_ANALYSIS_OP_TYPE_STORE) { + switch (op->refptr) { + case 2: op->datatype = RZ_ANALYSIS_DATATYPE_INT16; break; + case 4: op->datatype = RZ_ANALYSIS_DATATYPE_INT32; break; + case 8: op->datatype = RZ_ANALYSIS_DATATYPE_INT64; break; + default: break; + } + } +} + +int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask) { RiscvContext *ctx = (RiscvContext *)analysis->plugin_data; int n, ret, opsize = -1; cs_insn *insn; - int mode = (analysis->bits == 64) ? CS_MODE_RISCV64 : CS_MODE_RISCV32; - if (mode != ctx->omode || analysis->bits != ctx->obits) { + cs_mode mode = (analysis->bits == 64) ? CS_MODE_RISCV64 : CS_MODE_RISCV32; + mode |= mode_from_arch_string(analysis->cpu); + + if (mode != ctx->omode || analysis->bits != ctx->obits || cs_option(ctx->hndl, CS_OPT_DETAIL, CS_OPT_ON | CS_OPT_DETAIL_REAL) != CS_ERR_OK) { cs_close(&ctx->hndl); ctx->hndl = 0; ctx->omode = mode; ctx->obits = analysis->bits; } - // XXX no arch->cpu ?!?! CS_MODE_MICRO, N64 + op->addr = addr; - if (len < 4) { + if (len < 2) { return -1; } op->size = 4; @@ -234,39 +788,1132 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u cs_option(ctx->hndl, CS_OPT_DETAIL, CS_OPT_ON); } n = cs_disasm(ctx->hndl, (ut8 *)buf, len, addr, 1, &insn); + if (n < 1 || insn->size < 1) { goto beach; } op->id = insn->id; opsize = op->size = insn->size; + switch (insn->id) { case RISCV_INS_C_NOP: + case RISCV_INS_CMOP_1: + case RISCV_INS_CMOP_3: + case RISCV_INS_CMOP_5: + case RISCV_INS_CMOP_7: + case RISCV_INS_CMOP_9: + case RISCV_INS_CMOP_11: + case RISCV_INS_CMOP_13: + case RISCV_INS_CMOP_15: op->type = RZ_ANALYSIS_OP_TYPE_NOP; break; + case RISCV_INS_INVALID: + case RISCV_INS_UNIMP: + case RISCV_INS_C_UNIMP: op->type = RZ_ANALYSIS_OP_TYPE_ILL; break; + case RISCV_INS_C_JALR: - op->type = RZ_ANALYSIS_OP_TYPE_UCALL; + op->type = RZ_ANALYSIS_OP_TYPE_RCALL; + op->fail = UINT64_MAX; break; + case RISCV_INS_C_JR: - op->type = RZ_ANALYSIS_OP_TYPE_UJMP; + if (group_exists_in(insn->detail->groups, insn->detail->groups_count, RISCV_GRP_RET)) { + op->type = RZ_ANALYSIS_OP_TYPE_RET; + } else { + op->type = RZ_ANALYSIS_OP_TYPE_RJMP; + } + op->fail = UINT64_MAX; + break; + + case RISCV_INS_JUMP: + op->type = RZ_ANALYSIS_OP_TYPE_JMP; + break; + + case RISCV_INS_C_J: + case RISCV_INS_C_JAL: { + bool is_call = insn->id == RISCV_INS_C_JAL; + op->type = is_call ? RZ_ANALYSIS_OP_TYPE_CALL : RZ_ANALYSIS_OP_TYPE_JMP; + op->jump = SINGLE_IMM(insn); + op->fail = UINT64_MAX; + break; + } + + case RISCV_INS_JALR: + // special case (TODO: move to capstone and depend only on the groups API) + if (insn->detail->riscv.op_count == 0) { + op->type = RZ_ANALYSIS_OP_TYPE_RET; + break; + } + // no fallthrough + op->fail = UINT64_MAX; + // special case: known base register, namely the always-0 register + bool is_known_base = FIRST_READ_REGID(insn) == RISCV_REG_X0; + + if (group_exists_in(insn->detail->groups, insn->detail->groups_count, RISCV_GRP_CALL)) { + op->type = is_known_base ? RZ_ANALYSIS_OP_TYPE_CALL : RZ_ANALYSIS_OP_TYPE_RCALL; + } else { + op->type = is_known_base ? RZ_ANALYSIS_OP_TYPE_JMP : RZ_ANALYSIS_OP_TYPE_RJMP; + } + if (is_known_base) { + op->jump = SINGLE_IMM(insn); + } break; + + case RISCV_INS_JAL: { + bool is_call = group_exists_in(insn->detail->groups, insn->detail->groups_count, RISCV_GRP_CALL); + op->type = is_call ? RZ_ANALYSIS_OP_TYPE_CALL : RZ_ANALYSIS_OP_TYPE_JMP; + + op->jump = SINGLE_IMM(insn); + op->fail = UINT64_MAX; + break; + } + + case RISCV_INS_CM_JALT: + op->type = RZ_ANALYSIS_OP_TYPE_ICALL; + break; + + case RISCV_INS_CM_JT: + op->type = RZ_ANALYSIS_OP_TYPE_IJMP; + break; + + case RISCV_INS_AUIPC: + case RISCV_INS_ADD: + case RISCV_INS_ADDW: + case RISCV_INS_ADDI: + case RISCV_INS_ADDIW: + case RISCV_INS_C_ADD: + case RISCV_INS_C_ADDI: + case RISCV_INS_C_ADDW: + case RISCV_INS_C_ADDIW: + case RISCV_INS_C_ADDI16SP: + case RISCV_INS_C_ADDI4SPN: + case RISCV_INS_FADD_H: + case RISCV_INS_FADD_S: + case RISCV_INS_FADD_D: + case RISCV_INS_TH_ADDSL: + op->type = RZ_ANALYSIS_OP_TYPE_ADD; + break; + case RISCV_INS_SUB: + case RISCV_INS_SUBW: + case RISCV_INS_C_SUB: + case RISCV_INS_C_SUBW: + case RISCV_INS_FSUB_H: + case RISCV_INS_FSUB_S: + case RISCV_INS_FSUB_D: + op->type = RZ_ANALYSIS_OP_TYPE_SUB; + break; + case RISCV_INS_MUL: + case RISCV_INS_MULW: + case RISCV_INS_MULH: + case RISCV_INS_MULHU: + case RISCV_INS_MULHSU: + case RISCV_INS_C_MUL: + case RISCV_INS_FMUL_H: + case RISCV_INS_FMUL_S: + case RISCV_INS_FMUL_D: + case RISCV_INS_CLMUL: + case RISCV_INS_CLMULH: + case RISCV_INS_CLMULR: + op->type = RZ_ANALYSIS_OP_TYPE_MUL; + break; + + case RISCV_INS_DIV: + case RISCV_INS_DIVU: + case RISCV_INS_DIVW: + case RISCV_INS_DIVUW: + case RISCV_INS_FDIV_H: + case RISCV_INS_FDIV_S: + case RISCV_INS_FDIV_D: + op->type = RZ_ANALYSIS_OP_TYPE_DIV; + break; + case RISCV_INS_REM: + case RISCV_INS_REMU: + case RISCV_INS_REMW: + case RISCV_INS_REMUW: + op->type = RZ_ANALYSIS_OP_TYPE_MOD; + break; + case RISCV_INS_C_MV: + case RISCV_INS_LUI: + case RISCV_INS_LI: + case RISCV_INS_LA: op->type = RZ_ANALYSIS_OP_TYPE_MOV; break; - case RISCV_INS_JAL: - op->type = RZ_ANALYSIS_OP_TYPE_CALL; - op->jump = IMM(0); - op->fail = op->addr + op->size; + + // normal loads of various sizes + case RISCV_INS_LB: + case RISCV_INS_LBU: + case RISCV_INS_LH: + case RISCV_INS_LHU: + case RISCV_INS_LW: + case RISCV_INS_LWU: + case RISCV_INS_LD: + case RISCV_INS_C_LBU: + case RISCV_INS_C_LH: + case RISCV_INS_C_LHU: + case RISCV_INS_C_LW: + case RISCV_INS_C_LWSP: + case RISCV_INS_C_LD: + case RISCV_INS_C_LDSP: + // FP loads + case RISCV_INS_FLH: + case RISCV_INS_FLW: + case RISCV_INS_FLD: + case RISCV_INS_C_FLD: + case RISCV_INS_C_FLDSP: + case RISCV_INS_C_FLW: + case RISCV_INS_C_FLWSP: + // atomic loads + case RISCV_INS_LR_D: + case RISCV_INS_LR_D_AQ: + case RISCV_INS_LR_D_AQRL: + case RISCV_INS_LR_D_RL: + case RISCV_INS_LR_W: + case RISCV_INS_LR_W_AQ: + case RISCV_INS_LR_W_AQRL: + case RISCV_INS_LR_W_RL: + // T-Head loads + case RISCV_INS_TH_LRB: + case RISCV_INS_TH_LRBU: + case RISCV_INS_TH_LRD: + case RISCV_INS_TH_LRH: + case RISCV_INS_TH_LRHU: + case RISCV_INS_TH_LRW: + case RISCV_INS_TH_LRWU: + op->type = RZ_ANALYSIS_OP_TYPE_LOAD; break; + + case RISCV_INS_SB: + case RISCV_INS_SH: + case RISCV_INS_SW: + case RISCV_INS_SD: + case RISCV_INS_FSH: + case RISCV_INS_FSW: + case RISCV_INS_FSD: + case RISCV_INS_C_FSD: + case RISCV_INS_C_FSDSP: + case RISCV_INS_C_FSW: + case RISCV_INS_C_FSWSP: + case RISCV_INS_C_SB: + case RISCV_INS_C_SH: + case RISCV_INS_C_SW: + case RISCV_INS_C_SD: + case RISCV_INS_C_SWSP: + case RISCV_INS_C_SDSP: + case RISCV_INS_SC_D: + case RISCV_INS_SC_D_AQ: + case RISCV_INS_SC_D_AQRL: + case RISCV_INS_SC_D_RL: + case RISCV_INS_SC_W: + case RISCV_INS_SC_W_AQ: + case RISCV_INS_SC_W_AQRL: + case RISCV_INS_SC_W_RL: + + case RISCV_INS_WRS_NTO: + case RISCV_INS_WRS_STO: + op->type = RZ_ANALYSIS_OP_TYPE_STORE; + break; + case RISCV_INS_AND: + case RISCV_INS_ANDI: + op->type = RZ_ANALYSIS_OP_TYPE_AND; + break; + case RISCV_INS_OR: + case RISCV_INS_ORI: + op->type = RZ_ANALYSIS_OP_TYPE_OR; + break; + + case RISCV_INS_XOR: + case RISCV_INS_XORI: + case RISCV_INS_C_NOT: + case RISCV_INS_XNOR: + case RISCV_INS_C_XOR: + op->type = RZ_ANALYSIS_OP_TYPE_XOR; + break; + + case RISCV_INS_SLL: + case RISCV_INS_SLLI: + case RISCV_INS_SLLW: + case RISCV_INS_SLLIW: + case RISCV_INS_C_SLLI64: + op->type = RZ_ANALYSIS_OP_TYPE_SHL; + break; + case RISCV_INS_SRL: + case RISCV_INS_SRLI: + case RISCV_INS_SRLW: + case RISCV_INS_SRLIW: + case RISCV_INS_C_SRLI64: + op->type = RZ_ANALYSIS_OP_TYPE_SHR; + break; + case RISCV_INS_SRA: + case RISCV_INS_SRAI: + case RISCV_INS_SRAW: + case RISCV_INS_SRAIW: + case RISCV_INS_C_SRAI64: + op->type = RZ_ANALYSIS_OP_TYPE_SAR; + break; + + case RISCV_INS_ROL: + case RISCV_INS_ROLW: + op->type = RZ_ANALYSIS_OP_TYPE_ROL; + break; + + case RISCV_INS_ROR: + case RISCV_INS_RORI: + case RISCV_INS_RORIW: + case RISCV_INS_RORW: + op->type = RZ_ANALYSIS_OP_TYPE_ROR; + break; + case RISCV_INS_BCLR: + case RISCV_INS_BCLRI: + case RISCV_INS_CV_BCLR: + case RISCV_INS_CV_BCLRR: + op->type = RZ_ANALYSIS_OP_TYPE_AND; // Clear bit is like AND with mask + break; + + case RISCV_INS_BSET: + case RISCV_INS_BSETI: + case RISCV_INS_CV_BSET: + case RISCV_INS_CV_BSETR: + op->type = RZ_ANALYSIS_OP_TYPE_OR; // Set bit is like OR with mask + break; + + case RISCV_INS_BINV: + case RISCV_INS_BINVI: + op->type = RZ_ANALYSIS_OP_TYPE_XOR; // Invert bit is like XOR with mask + break; + + case RISCV_INS_BEXT: + case RISCV_INS_BEXTI: + case RISCV_INS_CV_EXTRACT: + case RISCV_INS_CV_EXTRACTR: + case RISCV_INS_CV_EXTRACTU: + case RISCV_INS_CV_EXTRACTUR: + case RISCV_INS_CV_EXTRACT_B: + case RISCV_INS_CV_EXTRACT_H: + case RISCV_INS_CV_EXTRACTU_B: + case RISCV_INS_CV_EXTRACTU_H: + case RISCV_INS_TH_EXT: + case RISCV_INS_TH_EXTU: + op->type = RZ_ANALYSIS_OP_TYPE_AND; // Extract is masking operation + break; + + case RISCV_INS_CV_INSERT: + case RISCV_INS_CV_INSERTR: + case RISCV_INS_CV_INSERT_B: + case RISCV_INS_CV_INSERT_H: + + case RISCV_INS_ORC_B: + + case RISCV_INS_TH_TSTNBZ: + case RISCV_INS_TH_TST: + op->type = RZ_ANALYSIS_OP_TYPE_OR; // Insert is OR-ing bits + break; + + case RISCV_INS_CLZ: + case RISCV_INS_CLZW: + case RISCV_INS_CTZ: + case RISCV_INS_CTZW: + case RISCV_INS_CPOP: + case RISCV_INS_CPOPW: + case RISCV_INS_CV_CNT: + case RISCV_INS_CV_CLB: + case RISCV_INS_CV_FF1: + case RISCV_INS_CV_FL1: + case RISCV_INS_TH_FF0: + case RISCV_INS_TH_FF1: + op->type = RZ_ANALYSIS_OP_TYPE_BCNT; + break; + + case RISCV_INS_VCLZ_V: + case RISCV_INS_VCPOP_V: + case RISCV_INS_VCTZ_V: + op->type = RZ_ANALYSIS_OP_TYPE_BCNT; + break; + + case RISCV_INS_REV8: + case RISCV_INS_BREV8: + case RISCV_INS_CV_BITREV: + case RISCV_INS_TH_REV: + case RISCV_INS_TH_REVW: + op->type = RZ_ANALYSIS_OP_TYPE_REV; + break; + + case RISCV_INS_PACK: + case RISCV_INS_PACKH: + case RISCV_INS_PACKW: + case RISCV_INS_CV_PACK: + case RISCV_INS_CV_PACK_H: + case RISCV_INS_CV_PACKHI_B: + case RISCV_INS_CV_PACKLO_B: + case RISCV_INS_UNZIP: + case RISCV_INS_ZIP: + op->type = RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_MIN: + case RISCV_INS_MINU: + case RISCV_INS_MAX: + case RISCV_INS_MAXU: + case RISCV_INS_CV_MIN: + case RISCV_INS_CV_MINU: + case RISCV_INS_CV_MAX: + case RISCV_INS_CV_MAXU: + op->type = RZ_ANALYSIS_OP_TYPE_CMP; + break; + case RISCV_INS_FMIN_S: + case RISCV_INS_FMIN_D: + case RISCV_INS_FMIN_H: + case RISCV_INS_FMAX_S: + case RISCV_INS_FMAX_D: + case RISCV_INS_FMAX_H: + case RISCV_INS_FMINM_S: + case RISCV_INS_FMINM_D: + case RISCV_INS_FMINM_H: + case RISCV_INS_FMAXM_S: + case RISCV_INS_FMAXM_D: + case RISCV_INS_FMAXM_H: + op->type = RZ_ANALYSIS_OP_TYPE_CMP; + break; + + case RISCV_INS_FLEQ_D: + case RISCV_INS_FLEQ_H: + case RISCV_INS_FLEQ_S: + case RISCV_INS_FLTQ_D: + case RISCV_INS_FLTQ_H: + case RISCV_INS_FLTQ_S: + case RISCV_INS_FEQ_D: + case RISCV_INS_FEQ_H: + case RISCV_INS_FEQ_S: + case RISCV_INS_FLE_H: + case RISCV_INS_FLT_H: + case RISCV_INS_VMFLE_VF: + case RISCV_INS_VMFLT_VF: + case RISCV_INS_VMFNE_VF: + case RISCV_INS_VMFGE_VF: + case RISCV_INS_VMFGT_VF: + case RISCV_INS_VMFEQ_VF: + case RISCV_INS_VMFLE_VV: + case RISCV_INS_VMFLT_VV: + case RISCV_INS_VMFNE_VV: + case RISCV_INS_VMFEQ_VV: + op->type = RZ_ANALYSIS_OP_TYPE_CMP; + break; + + case RISCV_INS_FSGNJ_S: + case RISCV_INS_FSGNJ_D: + case RISCV_INS_FSGNJ_H: + case RISCV_INS_FSGNJN_S: + case RISCV_INS_FSGNJN_D: + case RISCV_INS_FSGNJN_H: + case RISCV_INS_FSGNJX_S: + case RISCV_INS_FSGNJX_D: + case RISCV_INS_FSGNJX_H: + op->type = RZ_ANALYSIS_OP_TYPE_MOV; + break; + + case RISCV_INS_FCVT_W_S: + case RISCV_INS_FCVT_WU_S: + case RISCV_INS_FCVT_L_S: + case RISCV_INS_FCVT_LU_S: + case RISCV_INS_FCVT_W_D: + case RISCV_INS_FCVT_WU_D: + case RISCV_INS_FCVT_L_D: + case RISCV_INS_FCVT_LU_D: + case RISCV_INS_FCVT_W_H: + case RISCV_INS_FCVT_WU_H: + case RISCV_INS_FCVT_L_H: + case RISCV_INS_FCVT_LU_H: + case RISCV_INS_FCVT_S_W: + case RISCV_INS_FCVT_S_WU: + case RISCV_INS_FCVT_S_L: + case RISCV_INS_FCVT_S_LU: + case RISCV_INS_FCVT_D_W: + case RISCV_INS_FCVT_D_WU: + case RISCV_INS_FCVT_D_L: + case RISCV_INS_FCVT_D_LU: + case RISCV_INS_FCVT_H_W: + case RISCV_INS_FCVT_H_WU: + case RISCV_INS_FCVT_H_L: + case RISCV_INS_FCVT_H_LU: + case RISCV_INS_FCVT_S_D: + case RISCV_INS_FCVT_D_S: + case RISCV_INS_FCVT_S_H: + case RISCV_INS_FCVT_H_S: + case RISCV_INS_FCVT_D_H: + case RISCV_INS_FCVT_H_D: + case RISCV_INS_FCVT_S_BF16: + case RISCV_INS_FCVT_BF16_S: + case RISCV_INS_FCVTMOD_W_D: + op->type = RZ_ANALYSIS_OP_TYPE_CAST; + break; + + case RISCV_INS_FCLASS_S: + case RISCV_INS_FCLASS_D: + case RISCV_INS_FCLASS_H: + op->type = RZ_ANALYSIS_OP_TYPE_CMP; + break; + + case RISCV_INS_FROUND_S: + case RISCV_INS_FROUND_D: + case RISCV_INS_FROUND_H: + case RISCV_INS_FROUNDNX_S: + case RISCV_INS_FROUNDNX_D: + case RISCV_INS_FROUNDNX_H: + op->type = RZ_ANALYSIS_OP_TYPE_CAST; + break; + + case RISCV_INS_SLT: + case RISCV_INS_SLTI: + case RISCV_INS_SLTU: + case RISCV_INS_SLTIU: + op->type = RZ_ANALYSIS_OP_TYPE_CMP; + break; + + case RISCV_INS_BEQ: + case RISCV_INS_BNE: + case RISCV_INS_BLT: + case RISCV_INS_BGE: + case RISCV_INS_BLTU: + case RISCV_INS_BGEU: + case RISCV_INS_C_BEQZ: + case RISCV_INS_C_BNEZ: + op->type = RZ_ANALYSIS_OP_TYPE_CJMP; + if (insn->id == RISCV_INS_C_BEQZ || insn->id == RISCV_INS_C_BNEZ) { + op->jump = IMM(1); + } else { + op->jump = IMM(2); + } + op->fail = NEXT_ADDRESS(op); + break; + + case RISCV_INS_ECALL: + case RISCV_INS_C_EBREAK: + case RISCV_INS_EBREAK: + op->type = RZ_ANALYSIS_OP_TYPE_SWI; + break; + + case RISCV_INS_FENCE: + case RISCV_INS_FENCE_I: + case RISCV_INS_FENCE_TSO: + case RISCV_INS_HFENCE_GVMA: + case RISCV_INS_HFENCE_VVMA: + case RISCV_INS_SFENCE_INVAL_IR: + case RISCV_INS_SFENCE_VMA: + case RISCV_INS_SFENCE_W_INVAL: + case RISCV_INS_TH_SFENCE_VMAS: + case RISCV_INS_HINVAL_GVMA: + case RISCV_INS_HINVAL_VVMA: + case RISCV_INS_SINVAL_VMA: + case RISCV_INS_WFI: + case RISCV_INS_CBO_CLEAN: + case RISCV_INS_CBO_FLUSH: + case RISCV_INS_CBO_INVAL: + case RISCV_INS_CBO_ZERO: + case RISCV_INS_TH_DCACHE_CALL: + case RISCV_INS_TH_DCACHE_CIALL: + case RISCV_INS_TH_DCACHE_CIPA: + case RISCV_INS_TH_DCACHE_CISW: + case RISCV_INS_TH_DCACHE_CIVA: + case RISCV_INS_TH_DCACHE_CPA: + case RISCV_INS_TH_DCACHE_CPAL1: + case RISCV_INS_TH_DCACHE_CSW: + case RISCV_INS_TH_DCACHE_CVA: + case RISCV_INS_TH_DCACHE_CVAL1: + case RISCV_INS_TH_DCACHE_IALL: + case RISCV_INS_TH_DCACHE_IPA: + case RISCV_INS_TH_DCACHE_ISW: + case RISCV_INS_TH_DCACHE_IVA: + case RISCV_INS_TH_ICACHE_IALL: + case RISCV_INS_TH_ICACHE_IALLS: + case RISCV_INS_TH_ICACHE_IPA: + case RISCV_INS_TH_ICACHE_IVA: + case RISCV_INS_TH_L2CACHE_CALL: + case RISCV_INS_TH_L2CACHE_CIALL: + case RISCV_INS_TH_L2CACHE_IALL: + op->type = RZ_ANALYSIS_OP_TYPE_SYNC; + break; + + case RISCV_INS_AES32DSI: + case RISCV_INS_AES32DSMI: + case RISCV_INS_AES32ESI: + case RISCV_INS_AES32ESMI: + case RISCV_INS_AES64DS: + case RISCV_INS_AES64DSM: + case RISCV_INS_AES64ES: + case RISCV_INS_AES64ESM: + case RISCV_INS_AES64IM: + case RISCV_INS_AES64KS1I: + case RISCV_INS_AES64KS2: + case RISCV_INS_SHA256SIG0: + case RISCV_INS_SHA256SIG1: + case RISCV_INS_SHA256SUM0: + case RISCV_INS_SHA256SUM1: + case RISCV_INS_SHA512SIG0: + case RISCV_INS_SHA512SIG0H: + case RISCV_INS_SHA512SIG0L: + case RISCV_INS_SHA512SIG1: + case RISCV_INS_SHA512SIG1H: + case RISCV_INS_SHA512SIG1L: + case RISCV_INS_SHA512SUM0: + case RISCV_INS_SHA512SUM0R: + case RISCV_INS_SHA512SUM1: + case RISCV_INS_SHA512SUM1R: + op->type = RZ_ANALYSIS_OP_TYPE_CRYPTO; + break; + + case RISCV_INS_SEXT_B: + case RISCV_INS_SEXT_H: + case RISCV_INS_C_SEXT_B: + case RISCV_INS_C_SEXT_H: + case RISCV_INS_CV_EXTHS: + case RISCV_INS_CV_EXTBS: + op->type = RZ_ANALYSIS_OP_TYPE_CAST; + break; + + case RISCV_INS_ZEXT_H: + case RISCV_INS_ZEXT_W: + case RISCV_INS_C_ZEXT_B: + case RISCV_INS_C_ZEXT_H: + case RISCV_INS_C_ZEXT_W: + case RISCV_INS_CV_EXTHZ: + case RISCV_INS_CV_EXTBZ: + op->type = RZ_ANALYSIS_OP_TYPE_CAST; + break; + + case RISCV_INS_CM_PUSH: + case RISCV_INS_C_SSPUSH: + case RISCV_INS_SSPUSH: + op->type = RZ_ANALYSIS_OP_TYPE_PUSH; + break; + + case RISCV_INS_CM_POP: + case RISCV_INS_C_SSPOPCHK: + case RISCV_INS_SSPOPCHK: + op->type = RZ_ANALYSIS_OP_TYPE_POP; + break; + + case RISCV_INS_VSETVL: + case RISCV_INS_VSETVLI: + case RISCV_INS_VSETIVLI: + op->type = RZ_ANALYSIS_OP_TYPE_MOV | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + // ============================================================ + // VECTOR LOADS + // ============================================================ + case RISCV_INS_VLE8_V: + case RISCV_INS_VLE16_V: + case RISCV_INS_VLE32_V: + case RISCV_INS_VLE64_V: + case RISCV_INS_VLE8FF_V: + case RISCV_INS_VLE16FF_V: + case RISCV_INS_VLE32FF_V: + case RISCV_INS_VLE64FF_V: + case RISCV_INS_VLSE8_V: + case RISCV_INS_VLSE16_V: + case RISCV_INS_VLSE32_V: + case RISCV_INS_VLSE64_V: + case RISCV_INS_VLOXEI8_V: + case RISCV_INS_VLOXEI16_V: + case RISCV_INS_VLOXEI32_V: + case RISCV_INS_VLOXEI64_V: + case RISCV_INS_VLUXEI8_V: + case RISCV_INS_VLUXEI16_V: + case RISCV_INS_VLUXEI32_V: + case RISCV_INS_VLUXEI64_V: + case RISCV_INS_VLM_V: + case RISCV_INS_VL1RE8_V: + case RISCV_INS_VL1RE16_V: + case RISCV_INS_VL1RE32_V: + case RISCV_INS_VL1RE64_V: + case RISCV_INS_VL2RE8_V: + case RISCV_INS_VL2RE16_V: + case RISCV_INS_VL2RE32_V: + case RISCV_INS_VL2RE64_V: + case RISCV_INS_VL4RE8_V: + case RISCV_INS_VL4RE16_V: + case RISCV_INS_VL4RE32_V: + case RISCV_INS_VL4RE64_V: + case RISCV_INS_VL8RE8_V: + case RISCV_INS_VL8RE16_V: + case RISCV_INS_VL8RE32_V: + case RISCV_INS_VL8RE64_V: + // vector segment loads + case RISCV_INS_VLSEG2E8_V: + case RISCV_INS_VLSEG2E16_V: + case RISCV_INS_VLSEG2E32_V: + case RISCV_INS_VLSEG2E64_V: + case RISCV_INS_VLSEG3E8_V: + case RISCV_INS_VLSEG3E16_V: + case RISCV_INS_VLSEG3E32_V: + case RISCV_INS_VLSEG3E64_V: + case RISCV_INS_VLSEG4E8_V: + case RISCV_INS_VLSEG4E16_V: + case RISCV_INS_VLSEG4E32_V: + case RISCV_INS_VLSEG4E64_V: + case RISCV_INS_VLSEG5E8_V: + case RISCV_INS_VLSEG5E16_V: + case RISCV_INS_VLSEG5E32_V: + case RISCV_INS_VLSEG5E64_V: + case RISCV_INS_VLSEG6E8_V: + case RISCV_INS_VLSEG6E16_V: + case RISCV_INS_VLSEG6E32_V: + case RISCV_INS_VLSEG6E64_V: + case RISCV_INS_VLSEG7E8_V: + case RISCV_INS_VLSEG7E16_V: + case RISCV_INS_VLSEG7E32_V: + case RISCV_INS_VLSEG7E64_V: + case RISCV_INS_VLSEG8E8_V: + case RISCV_INS_VLSEG8E16_V: + case RISCV_INS_VLSEG8E32_V: + case RISCV_INS_VLSEG8E64_V: + + case RISCV_INS_HLVX_HU: + case RISCV_INS_HLVX_WU: + case RISCV_INS_HLV_B: + case RISCV_INS_HLV_BU: + case RISCV_INS_HLV_D: + case RISCV_INS_HLV_H: + case RISCV_INS_HLV_HU: + case RISCV_INS_HLV_W: + case RISCV_INS_HLV_WU: + op->type = RZ_ANALYSIS_OP_TYPE_LOAD | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + // ============================================================ + // VECTOR STORES + // ============================================================ + case RISCV_INS_VSE8_V: + case RISCV_INS_VSE16_V: + case RISCV_INS_VSE32_V: + case RISCV_INS_VSE64_V: + case RISCV_INS_VSSE8_V: + case RISCV_INS_VSSE16_V: + case RISCV_INS_VSSE32_V: + case RISCV_INS_VSSE64_V: + case RISCV_INS_VSOXEI8_V: + case RISCV_INS_VSOXEI16_V: + case RISCV_INS_VSOXEI32_V: + case RISCV_INS_VSOXEI64_V: + case RISCV_INS_VSUXEI8_V: + case RISCV_INS_VSUXEI16_V: + case RISCV_INS_VSUXEI32_V: + case RISCV_INS_VSUXEI64_V: + case RISCV_INS_VSM_V: + case RISCV_INS_VS1R_V: + case RISCV_INS_VS2R_V: + case RISCV_INS_VS4R_V: + case RISCV_INS_VS8R_V: + case RISCV_INS_VSSEG2E8_V: + case RISCV_INS_VSSEG2E16_V: + case RISCV_INS_VSSEG2E32_V: + case RISCV_INS_VSSEG2E64_V: + case RISCV_INS_VSSEG3E8_V: + case RISCV_INS_VSSEG3E16_V: + case RISCV_INS_VSSEG3E32_V: + case RISCV_INS_VSSEG3E64_V: + case RISCV_INS_VSSEG4E8_V: + case RISCV_INS_VSSEG4E16_V: + case RISCV_INS_VSSEG4E32_V: + case RISCV_INS_VSSEG4E64_V: + case RISCV_INS_VSSEG5E8_V: + case RISCV_INS_VSSEG5E16_V: + case RISCV_INS_VSSEG5E32_V: + case RISCV_INS_VSSEG5E64_V: + case RISCV_INS_VSSEG6E8_V: + case RISCV_INS_VSSEG6E16_V: + case RISCV_INS_VSSEG6E32_V: + case RISCV_INS_VSSEG6E64_V: + case RISCV_INS_VSSEG7E8_V: + case RISCV_INS_VSSEG7E16_V: + case RISCV_INS_VSSEG7E32_V: + case RISCV_INS_VSSEG7E64_V: + case RISCV_INS_VSSEG8E8_V: + case RISCV_INS_VSSEG8E16_V: + case RISCV_INS_VSSEG8E32_V: + case RISCV_INS_VSSEG8E64_V: + case RISCV_INS_HSV_B: + case RISCV_INS_HSV_D: + case RISCV_INS_HSV_H: + case RISCV_INS_HSV_W: + op->type = RZ_ANALYSIS_OP_TYPE_STORE | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + // ============================================================ + // VECTOR ARITHMETIC - ADD/SUB + // ============================================================ + case RISCV_INS_VADD_VV: + case RISCV_INS_VADD_VX: + case RISCV_INS_VADD_VI: + case RISCV_INS_VWADDU_VV: + case RISCV_INS_VWADDU_VX: + case RISCV_INS_VWADDU_WV: + case RISCV_INS_VWADDU_WX: + case RISCV_INS_VWADD_VV: + case RISCV_INS_VWADD_VX: + case RISCV_INS_VWADD_WV: + case RISCV_INS_VWADD_WX: + case RISCV_INS_VSADDU_VV: + case RISCV_INS_VSADDU_VX: + case RISCV_INS_VSADDU_VI: + case RISCV_INS_VSADD_VV: + case RISCV_INS_VSADD_VX: + case RISCV_INS_VSADD_VI: + case RISCV_INS_VAADD_VV: + case RISCV_INS_VAADD_VX: + case RISCV_INS_VAADDU_VV: + case RISCV_INS_VAADDU_VX: + + case RISCV_INS_VADC_VIM: + case RISCV_INS_VADC_VVM: + case RISCV_INS_VADC_VXM: + case RISCV_INS_VMADC_VI: + case RISCV_INS_VMADC_VIM: + case RISCV_INS_VMADC_VV: + case RISCV_INS_VMADC_VVM: + case RISCV_INS_VMADC_VX: + case RISCV_INS_VMADC_VXM: + op->type = RZ_ANALYSIS_OP_TYPE_ADD | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_VSUB_VV: + case RISCV_INS_VSUB_VX: + case RISCV_INS_VWSUBU_VV: + case RISCV_INS_VWSUBU_VX: + case RISCV_INS_VWSUBU_WV: + case RISCV_INS_VWSUBU_WX: + case RISCV_INS_VWSUB_VV: + case RISCV_INS_VWSUB_VX: + case RISCV_INS_VWSUB_WV: + case RISCV_INS_VWSUB_WX: + case RISCV_INS_VSSUBU_VV: + case RISCV_INS_VSSUBU_VX: + case RISCV_INS_VSSUB_VV: + case RISCV_INS_VSSUB_VX: + case RISCV_INS_VASUB_VV: + case RISCV_INS_VASUB_VX: + case RISCV_INS_VASUBU_VV: + case RISCV_INS_VASUBU_VX: + case RISCV_INS_VRSUB_VX: + case RISCV_INS_VRSUB_VI: + + case RISCV_INS_VMSBC_VV: + case RISCV_INS_VMSBC_VVM: + case RISCV_INS_VMSBC_VX: + case RISCV_INS_VMSBC_VXM: + case RISCV_INS_VSBC_VVM: + case RISCV_INS_VSBC_VXM: + op->type = RZ_ANALYSIS_OP_TYPE_SUB | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + // ============================================================ + // VECTOR ARITHMETIC - MULTIPLY + // ============================================================ + case RISCV_INS_VMUL_VV: + case RISCV_INS_VMUL_VX: + case RISCV_INS_VMULH_VV: + case RISCV_INS_VMULH_VX: + case RISCV_INS_VMULHU_VV: + case RISCV_INS_VMULHU_VX: + case RISCV_INS_VMULHSU_VV: + case RISCV_INS_VMULHSU_VX: + case RISCV_INS_VWMUL_VV: + case RISCV_INS_VWMUL_VX: + case RISCV_INS_VWMULU_VV: + case RISCV_INS_VWMULU_VX: + case RISCV_INS_VWMULSU_VV: + case RISCV_INS_VWMULSU_VX: + case RISCV_INS_VSMUL_VV: + case RISCV_INS_VSMUL_VX: + case RISCV_INS_VMACC_VV: + case RISCV_INS_VMACC_VX: + case RISCV_INS_VMADD_VV: + case RISCV_INS_VMADD_VX: + case RISCV_INS_VNMSAC_VV: + case RISCV_INS_VNMSAC_VX: + case RISCV_INS_VNMSUB_VV: + case RISCV_INS_VNMSUB_VX: + case RISCV_INS_VWMACC_VV: + case RISCV_INS_VWMACC_VX: + case RISCV_INS_VWMACCU_VV: + case RISCV_INS_VWMACCU_VX: + case RISCV_INS_VWMACCSU_VV: + case RISCV_INS_VWMACCSU_VX: + case RISCV_INS_VWMACCUS_VX: + op->type = RZ_ANALYSIS_OP_TYPE_MUL | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + // ============================================================ + // VECTOR ARITHMETIC - DIVIDE + // ============================================================ + case RISCV_INS_VDIVU_VV: + case RISCV_INS_VDIVU_VX: + case RISCV_INS_VDIV_VV: + case RISCV_INS_VDIV_VX: + case RISCV_INS_VFREC7_V: + op->type = RZ_ANALYSIS_OP_TYPE_DIV | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_VREMU_VV: + case RISCV_INS_VREMU_VX: + case RISCV_INS_VREM_VV: + case RISCV_INS_VREM_VX: + op->type = RZ_ANALYSIS_OP_TYPE_MOD | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + // ============================================================ + // VECTOR LOGICAL + // ============================================================ + case RISCV_INS_VAND_VV: + case RISCV_INS_VAND_VX: + case RISCV_INS_VAND_VI: + case RISCV_INS_VANDN_VV: + case RISCV_INS_VANDN_VX: + op->type = RZ_ANALYSIS_OP_TYPE_AND | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_VOR_VV: + case RISCV_INS_VOR_VX: + case RISCV_INS_VOR_VI: + op->type = RZ_ANALYSIS_OP_TYPE_OR | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_VXOR_VV: + case RISCV_INS_VXOR_VX: + case RISCV_INS_VXOR_VI: + op->type = RZ_ANALYSIS_OP_TYPE_XOR | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + // ============================================================ + // VECTOR SHIFT + // ============================================================ + case RISCV_INS_VSLL_VV: + case RISCV_INS_VSLL_VX: + case RISCV_INS_VSLL_VI: + case RISCV_INS_VWSLL_VV: + case RISCV_INS_VWSLL_VX: + case RISCV_INS_VWSLL_VI: + op->type = RZ_ANALYSIS_OP_TYPE_SHL | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_VSRL_VV: + case RISCV_INS_VSRL_VX: + case RISCV_INS_VSRL_VI: + case RISCV_INS_VNSRL_WV: + case RISCV_INS_VNSRL_WX: + case RISCV_INS_VNSRL_WI: + case RISCV_INS_VSSRL_VV: + case RISCV_INS_VSSRL_VX: + case RISCV_INS_VSSRL_VI: + op->type = RZ_ANALYSIS_OP_TYPE_SHR | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_VSRA_VV: + case RISCV_INS_VSRA_VX: + case RISCV_INS_VSRA_VI: + case RISCV_INS_VNSRA_WV: + case RISCV_INS_VNSRA_WX: + case RISCV_INS_VNSRA_WI: + case RISCV_INS_VSSRA_VV: + case RISCV_INS_VSSRA_VX: + case RISCV_INS_VSSRA_VI: + op->type = RZ_ANALYSIS_OP_TYPE_SAR | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + // ============================================================ + // VECTOR ROTATE + // ============================================================ + case RISCV_INS_VROR_VV: + case RISCV_INS_VROR_VX: + case RISCV_INS_VROR_VI: + op->type = RZ_ANALYSIS_OP_TYPE_ROR | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_VROL_VV: + case RISCV_INS_VROL_VX: + op->type = RZ_ANALYSIS_OP_TYPE_ROL | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + // ============================================================ + // VECTOR COMPARE + // ============================================================ + case RISCV_INS_VMSEQ_VV: + case RISCV_INS_VMSEQ_VX: + case RISCV_INS_VMSEQ_VI: + case RISCV_INS_VMSNE_VV: + case RISCV_INS_VMSNE_VX: + case RISCV_INS_VMSNE_VI: + case RISCV_INS_VMSLTU_VV: + case RISCV_INS_VMSLTU_VX: + case RISCV_INS_VMSLT_VV: + case RISCV_INS_VMSLT_VX: + case RISCV_INS_VMSLEU_VV: + case RISCV_INS_VMSLEU_VX: + case RISCV_INS_VMSLEU_VI: + case RISCV_INS_VMSLE_VV: + case RISCV_INS_VMSLE_VX: + case RISCV_INS_VMSLE_VI: + case RISCV_INS_VMSGTU_VX: + case RISCV_INS_VMSGTU_VI: + case RISCV_INS_VMSGT_VX: + case RISCV_INS_VMSGT_VI: + case RISCV_INS_VMSGEU_VX: + case RISCV_INS_VMSGEU_VI: + case RISCV_INS_VMSGE_VX: + case RISCV_INS_VMSGE_VI: + op->type = RZ_ANALYSIS_OP_TYPE_CMP | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + // ============================================================ + // VECTOR MIN/MAX + // ============================================================ + case RISCV_INS_VMIN_VV: + case RISCV_INS_VMIN_VX: + case RISCV_INS_VMINU_VV: + case RISCV_INS_VMINU_VX: + case RISCV_INS_VMAX_VV: + case RISCV_INS_VMAX_VX: + case RISCV_INS_VMAXU_VV: + case RISCV_INS_VMAXU_VX: + op->type = RZ_ANALYSIS_OP_TYPE_CMP | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + // ============================================================ + // VECTOR MOVE/MERGE + // ============================================================ + case RISCV_INS_VMV_V_V: + case RISCV_INS_VMV_V_X: + case RISCV_INS_VMV_V_I: + case RISCV_INS_VMV_X_S: + case RISCV_INS_VMV_S_X: + case RISCV_INS_VMV1R_V: + case RISCV_INS_VMV2R_V: + case RISCV_INS_VMV4R_V: + case RISCV_INS_VMV8R_V: + case RISCV_INS_VMERGE_VVM: + case RISCV_INS_VMERGE_VXM: + case RISCV_INS_VMERGE_VIM: + case RISCV_INS_VFMV_F_S: + case RISCV_INS_VFMV_S_F: + case RISCV_INS_VFMV_V_F: + op->type = RZ_ANALYSIS_OP_TYPE_MOV | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + // ============================================================ + // VECTOR MASK OPERATIONS + // ============================================================ + case RISCV_INS_VMAND_MM: + case RISCV_INS_VMANDN_MM: + op->type = RZ_ANALYSIS_OP_TYPE_AND | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_VMOR_MM: + case RISCV_INS_VMORN_MM: + case RISCV_INS_VMNOR_MM: + op->type = RZ_ANALYSIS_OP_TYPE_OR | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_VMXOR_MM: + case RISCV_INS_VMXNOR_MM: + case RISCV_INS_VMNAND_MM: + op->type = RZ_ANALYSIS_OP_TYPE_XOR | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + // ============================================================ + // VECTOR REDUCTIONS + // ============================================================ + case RISCV_INS_VREDSUM_VS: + case RISCV_INS_VREDMAXU_VS: + case RISCV_INS_VREDMAX_VS: + case RISCV_INS_VREDMINU_VS: + case RISCV_INS_VREDMIN_VS: + case RISCV_INS_VREDAND_VS: + case RISCV_INS_VREDOR_VS: + case RISCV_INS_VREDXOR_VS: + case RISCV_INS_VWREDSUM_VS: + op->type = RZ_ANALYSIS_OP_TYPE_REDUCE | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + // ============================================================ + // VECTOR CRYPTO + // ============================================================ + case RISCV_INS_VCLMUL_VV: + case RISCV_INS_VCLMUL_VX: + case RISCV_INS_VCLMULH_VV: + case RISCV_INS_VCLMULH_VX: + case RISCV_INS_VAESDF_VS: + case RISCV_INS_VAESDF_VV: + case RISCV_INS_VAESDM_VS: + case RISCV_INS_VAESDM_VV: + case RISCV_INS_VAESEF_VS: + case RISCV_INS_VAESEF_VV: + case RISCV_INS_VAESEM_VS: + case RISCV_INS_VAESEM_VV: + case RISCV_INS_VAESKF1_VI: + case RISCV_INS_VAESKF2_VI: + case RISCV_INS_VAESZ_VS: + case RISCV_INS_VSHA2CH_VV: + case RISCV_INS_VSHA2CL_VV: + case RISCV_INS_VSHA2MS_VV: + case RISCV_INS_VSM3C_VI: + case RISCV_INS_VSM3ME_VV: + case RISCV_INS_VSM4K_VI: + case RISCV_INS_VSM4R_VS: + case RISCV_INS_VSM4R_VV: + case RISCV_INS_VGHSH_VV: + case RISCV_INS_VGMUL_VV: + op->type = RZ_ANALYSIS_OP_TYPE_CRYPTO | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_VFCVT_F_XU_V: + case RISCV_INS_VFCVT_F_X_V: + case RISCV_INS_VFCVT_RTZ_XU_F_V: + case RISCV_INS_VFCVT_RTZ_X_F_V: + case RISCV_INS_VFCVT_XU_F_V: + case RISCV_INS_VFCVT_X_F_V: + case RISCV_INS_VFWCVT_F_F_V: + case RISCV_INS_VFWCVT_F_XU_V: + case RISCV_INS_VFWCVT_F_X_V: + case RISCV_INS_VFWCVT_RTZ_XU_F_V: + case RISCV_INS_VFWCVT_RTZ_X_F_V: + case RISCV_INS_VFWCVT_XU_F_V: + case RISCV_INS_VFWCVT_X_F_V: + case RISCV_INS_VFNCVT_F_F_W: + case RISCV_INS_VFNCVT_F_XU_W: + case RISCV_INS_VFNCVT_F_X_W: + case RISCV_INS_VFNCVT_ROD_F_F_W: + case RISCV_INS_VFNCVT_RTZ_XU_F_W: + case RISCV_INS_VFNCVT_RTZ_X_F_W: + case RISCV_INS_VFNCVT_XU_F_W: + case RISCV_INS_VFNCVT_X_F_W: + case RISCV_INS_VFNCVTBF16_F_F_W: + case RISCV_INS_VFWCVTBF16_F_F_V: + op->type = RZ_ANALYSIS_OP_TYPE_CAST | RZ_ANALYSIS_OP_TYPE_SIMD; + break; + + case RISCV_INS_CZERO_EQZ: + case RISCV_INS_CZERO_NEZ: + op->type = RZ_ANALYSIS_OP_TYPE_CMOV; + break; + + case RISCV_INS_CM_POPRET: + case RISCV_INS_CM_POPRETZ: case RISCV_INS_MRET: case RISCV_INS_SRET: - case RISCV_INS_URET: + case RISCV_INS_DRET: op->type = RZ_ANALYSIS_OP_TYPE_RET; break; } beach: + if (insn) { + set_op_sign(op, insn); + set_op_data_size(op, insn); + set_op_val(op, insn); + set_op_eob(op, insn); + set_op_cond(op, insn); + set_op_family(op, insn); + set_op_extra_metadata(analysis, op, ctx->hndl, insn); + set_stack_effect(op, insn); + } set_opdir(op); if (insn && mask & RZ_ANALYSIS_OP_MASK_OPEX) { op->opex = riscv_opex(ctx->hndl, insn); @@ -291,6 +1938,12 @@ static char *get_reg_profile(RzAnalysis *analysis) { "=BP s0\n" // ABI: frame pointer "=A0 a0\n" "=A1 a1\n" + "=A2 a2\n" + "=A3 a3\n" + "=A4 a4\n" + "=A5 a5\n" + "=A6 a6\n" + "=A7 a7\n" "gpr pc .32 0 0\n" // RV32I regs (ABI names) @@ -367,8 +2020,42 @@ static char *get_reg_profile(RzAnalysis *analysis) { "flg of .1 3074 0\n" "flg dz .1 3075 0\n" "flg nv .1 3076 0\n" - "flg frm .3 3077 0\n"; - + "flg frm .3 3077 0\n" + // vector registers + // assume each register is 512 bits (64 bytes) for maximum compatibility + // TODO: make the width accurately reflect the exact width defined in the binary + "gpr v0 .512 4096 0\n" + "gpr v1 .512 4160 0\n" + "gpr v2 .512 4224 0\n" + "gpr v3 .512 4288 0\n" + "gpr v4 .512 4352 0\n" + "gpr v5 .512 4416 0\n" + "gpr v6 .512 4480 0\n" + "gpr v7 .512 4544 0\n" + "gpr v8 .512 4608 0\n" + "gpr v9 .512 4672 0\n" + "gpr v10 .512 4736 0\n" + "gpr v11 .512 4800 0\n" + "gpr v12 .512 4864 0\n" + "gpr v13 .512 4928 0\n" + "gpr v14 .512 4992 0\n" + "gpr v15 .512 5056 0\n" + "gpr v16 .512 5120 0\n" + "gpr v17 .512 5184 0\n" + "gpr v18 .512 5248 0\n" + "gpr v19 .512 5312 0\n" + "gpr v20 .512 5376 0\n" + "gpr v21 .512 5440 0\n" + "gpr v22 .512 5504 0\n" + "gpr v23 .512 5568 0\n" + "gpr v24 .512 5632 0\n" + "gpr v25 .512 5696 0\n" + "gpr v26 .512 5760 0\n" + "gpr v27 .512 5824 0\n" + "gpr v28 .512 5888 0\n" + "gpr v29 .512 5952 0\n" + "gpr v30 .512 6016 0\n" + "gpr v31 .512 6080 0\n"; break; case 64: p = @@ -378,6 +2065,12 @@ static char *get_reg_profile(RzAnalysis *analysis) { "=BP s0\n" // ABI: frame pointer "=A0 a0\n" "=A1 a1\n" + "=A2 a2\n" + "=A3 a3\n" + "=A4 a4\n" + "=A5 a5\n" + "=A6 a6\n" + "=A7 a7\n" "gpr pc .64 0 0\n" // RV64I regs (ABI names) @@ -448,6 +2141,41 @@ static char *get_reg_profile(RzAnalysis *analysis) { "gpr ft10 .64 496 0\n" // =f30 "gpr ft11 .64 504 0\n" // =f31 "gpr fcsr .32 512 0\n" + // vector registers + // assume each register is 512 bits (64 bytes) for maximum compatibility + // TODO: make the width accurately reflect the exact width defined in the binary + "gpr v0 .512 1024 0\n" + "gpr v1 .512 1088 0\n" + "gpr v2 .512 1152 0\n" + "gpr v3 .512 1216 0\n" + "gpr v4 .512 1280 0\n" + "gpr v5 .512 1344 0\n" + "gpr v6 .512 1408 0\n" + "gpr v7 .512 1472 0\n" + "gpr v8 .512 1536 0\n" + "gpr v9 .512 1600 0\n" + "gpr v10 .512 1664 0\n" + "gpr v11 .512 1728 0\n" + "gpr v12 .512 1792 0\n" + "gpr v13 .512 1856 0\n" + "gpr v14 .512 1920 0\n" + "gpr v15 .512 1984 0\n" + "gpr v16 .512 2048 0\n" + "gpr v17 .512 2112 0\n" + "gpr v18 .512 2176 0\n" + "gpr v19 .512 2240 0\n" + "gpr v20 .512 2304 0\n" + "gpr v21 .512 2368 0\n" + "gpr v22 .512 2432 0\n" + "gpr v23 .512 2496 0\n" + "gpr v24 .512 2560 0\n" + "gpr v25 .512 2624 0\n" + "gpr v26 .512 2688 0\n" + "gpr v27 .512 2752 0\n" + "gpr v28 .512 2816 0\n" + "gpr v29 .512 2880 0\n" + "gpr v30 .512 2944 0\n" + "gpr v31 .512 3008 0\n" "flg nx .1 4096 0\n" "flg uf .1 4097 0\n" "flg of .1 4098 0\n" @@ -469,7 +2197,7 @@ static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) { case RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE: return 6; case RZ_ANALYSIS_ARCHINFO_TEXT_ALIGN: - /* fall-thru */ + return 2; case RZ_ANALYSIS_ARCHINFO_DATA_ALIGN: return 4; case RZ_ANALYSIS_ARCHINFO_CAN_USE_POINTERS: @@ -479,6 +2207,48 @@ static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) { } } +static void set_stack_effect(RzAnalysisOp *op, cs_insn *insn) { + op->stackop = RZ_ANALYSIS_STACK_NOP; + if (!IS_REG_WRITTEN(insn, RISCV_REG_X2)) { + return; + } + + // x2 i.e. SP is written, but how ? + + // incremented or decremented ? + switch (op->type) { + case RZ_ANALYSIS_OP_TYPE_ADD: + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = -MAYBE_IMM(insn); + return; + + case RZ_ANALYSIS_OP_TYPE_SUB: + op->stackop = RZ_ANALYSIS_STACK_DEC; + op->stackptr = MAYBE_IMM(insn); + return; + + case RZ_ANALYSIS_OP_TYPE_LOAD: + if (MEM_BASE(insn, RISCV_REG_X2)) { + op->stackop = RZ_ANALYSIS_STACK_GET; + op->stackptr = op->refptr; + } + return; + + case RZ_ANALYSIS_OP_TYPE_STORE: + if (MEM_BASE(insn, RISCV_REG_X2)) { + op->stackop = RZ_ANALYSIS_STACK_SET; + op->stackptr = op->refptr; + } + return; + + // TODO: Add RESET and ALIGN + + default: + break; + } + return; +} + static bool riscv_fini(void *user) { RiscvContext *ctx = (RiscvContext *)user; if (ctx) { @@ -488,7 +2258,7 @@ static bool riscv_fini(void *user) { } RzAnalysisPlugin rz_analysis_plugin_riscv_cs = { - .name = "riscv.cs", + .name = "riscv", .desc = "Capstone RISCV analyzer", .license = "BSD", .esil = false, diff --git a/librz/arch/p/analysis/analysis_riscv_utils.h b/librz/arch/p/analysis/analysis_riscv_utils.h new file mode 100644 index 00000000000..105f301ddfa --- /dev/null +++ b/librz/arch/p/analysis/analysis_riscv_utils.h @@ -0,0 +1,136 @@ +#include + +#include "cs_operand.h" +#include "rz_util/rz_log.h" + +#include +#include +#include + +// A more high-level alternative to direct indexing that can get immediates and operands without exact +// indices +// While also enforcing high-level constraints such as "exactly one immediate operand is present" +// or "at most one operand is present" or "get the single register that is read/written" + +static inline int find_at_most_one_op(cs_riscv_op *operands, uint8_t op_count, riscv_op_type type, const char *type_str) { + int first = -1; + for (int i = 0; i < op_count; i++) { + if (operands[i].type == type) { + if (first == -1) { + first = i; + } else { + RZ_LOG_FATAL("Expected exactly one %s operand, two elements matched (the %ith and %ith elements)", type_str, first, i); + exit(-1); + } + } + } + return first; +} + +static inline int find_at_most_one_imm(cs_riscv_op *operands, uint8_t op_count) { + return find_at_most_one_op(operands, op_count, RISCV_OP_IMM, "immediate"); +} + +static inline int find_exactly_one_op(cs_riscv_op *operands, uint8_t op_count, riscv_op_type type, const char *type_str) { + int first = find_at_most_one_op(operands, op_count, type, type_str); + if (first == -1) { + RZ_LOG_FATAL("Expected exactly one %s operand, found none", type_str); + exit(-1); + } + return first; +} + +static inline int find_exactly_one_imm(cs_riscv_op *operands, uint8_t op_count) { + return find_exactly_one_op(operands, op_count, RISCV_OP_IMM, "immediate"); +} + +static inline int64_t get_exactly_one_immediate(cs_riscv_op *operands, uint8_t op_count) { + return operands[find_exactly_one_imm(operands, op_count)].imm; +} + +static inline int64_t get_at_most_one_immediate(cs_riscv_op *operands, uint8_t op_count) { + int64_t idx = find_at_most_one_imm(operands, op_count); + if (idx == -1) { + return INT64_MAX; + } + return operands[idx].imm; +} + +#define SINGLE_IMM(insn) get_exactly_one_immediate(insn->detail->riscv.operands, insn->detail->riscv.op_count); +#define MAYBE_IMM(insn) get_at_most_one_immediate(insn->detail->riscv.operands, insn->detail->riscv.op_count); + +static inline int find_first_op(cs_riscv_op *operands, uint8_t op_count, riscv_op_type type) { + for (int i = 0; i < op_count; i++) { + if (operands[i].type == type) { + return i; + } + } + return -1; +} + +static inline int find_first_imm(cs_riscv_op *operands, uint8_t op_count) { + return find_first_op(operands, op_count, RISCV_OP_IMM); +} + +static inline int64_t get_first_immediate(cs_riscv_op *operands, uint8_t op_count) { + int idx = find_first_imm(operands, op_count); + if (idx == -1) { + return INT64_MAX; + } + return operands[idx].imm; +} + +#define FIRST_IMM(insn) get_first_immediate(insn->detail->riscv.operands, insn->detail->riscv.op_count); + +static inline unsigned int get_any_reg_accessed_as(cs_riscv_op *operands, uint8_t op_count, cs_ac_type access) { + for (int i = 0; i < op_count; i++) { + if (operands[i].type == RISCV_OP_REG && (operands[i].access & access)) { + return operands[i].reg; + } + } + RZ_LOG_FATAL("Expected at least one register with %s access, found none", access == CS_AC_READ ? "read" : "write"); + exit(-1); + return 0; // dummy for type checking, never reached +} + +static inline unsigned int first_read_register(cs_riscv_op *operands, uint8_t op_count) { + return get_any_reg_accessed_as(operands, op_count, CS_AC_READ); +} + +static inline unsigned int first_written_register(cs_riscv_op *operands, uint8_t op_count) { + return get_any_reg_accessed_as(operands, op_count, CS_AC_WRITE); +} + +#define FIRST_READ_REGID(insn) first_read_register(insn->detail->riscv.operands, insn->detail->riscv.op_count) +#define FIRST_WRITTEN_REGID(insn) first_written_register(insn->detail->riscv.operands, insn->detail->riscv.op_count) + +// check if a certain reg is ever accessed as read/write register +static inline bool is_any_reg_accessed_as(cs_riscv_op *operands, uint8_t op_count, unsigned int reg, cs_ac_type access) { + for (int i = 0; i < op_count; i++) { + if (operands[i].type == RISCV_OP_REG && operands[i].reg == reg && (operands[i].access & access)) { + return true; + } + } + return false; +} + +static inline bool is_reg_written(cs_riscv_op *operands, uint8_t op_count, unsigned int reg) { + return is_any_reg_accessed_as(operands, op_count, reg, CS_AC_WRITE); +} +static inline bool is_reg_read(cs_riscv_op *operands, uint8_t op_count, unsigned int reg) { + return is_any_reg_accessed_as(operands, op_count, reg, CS_AC_READ); +} + +#define IS_REG_WRITTEN(insn, reg) is_reg_written(insn->detail->riscv.operands, insn->detail->riscv.op_count, reg) +#define IS_REG_READ(insn, reg) is_reg_read(insn->detail->riscv.operands, insn->detail->riscv.op_count, reg) + +static inline bool is_any_reg_memory_base(cs_riscv_op *operands, uint8_t op_count, unsigned int reg) { + for (int i = 0; i < op_count; i++) { + if (operands[i].type == RISCV_OP_MEM && operands[i].mem.base == reg) { + return true; + } + } + return false; +} + +#define MEM_BASE(insn, reg) is_any_reg_memory_base(insn->detail->riscv.operands, insn->detail->riscv.op_count, reg) \ No newline at end of file diff --git a/librz/arch/p/arch_riscv_cs.c b/librz/arch/p/arch_riscv_cs.c index d58b5ddcca8..6022513638d 100644 --- a/librz/arch/p/arch_riscv_cs.c +++ b/librz/arch/p/arch_riscv_cs.c @@ -3,6 +3,243 @@ // SPDX-License-Identifier: LGPL-3.0-only #include +#include +#include +#include +#include "capstone.h" +#include "rz_util/rz_log.h" +#include "arch_riscv_extension_parser.inc" + +cs_mode cs_mode_from_feature_flag(ut64 feature_flag) { + switch (feature_flag) { + case RISCV_FeatureStdExtF: + case RISCV_FeatureStdExtD: + return CS_MODE_RISCV_FD; + case RISCV_FeatureStdExtV: + return CS_MODE_RISCV_V; + case RISCV_FeatureStdExtZfinx: + case RISCV_FeatureStdExtZdinx: + case RISCV_FeatureStdExtZhinx: + case RISCV_FeatureStdExtZhinxmin: + return CS_MODE_RISCV_ZFINX; + case RISCV_FeatureStdExtC: + return CS_MODE_RISCV_C; + case RISCV_FeatureStdExtZcmp: + case RISCV_FeatureStdExtZcmt: + case RISCV_FeatureStdExtZce: + return CS_MODE_RISCV_ZCMP_ZCMT_ZCE; + case RISCV_FeatureStdExtZicfiss: + return CS_MODE_RISCV_ZICFISS; + case RISCV_FeatureStdExtA: + return CS_MODE_RISCV_A; + case RISCV_FeatureStdExtZba: + return CS_MODE_RISCV_ZBA; + case RISCV_FeatureStdExtZbb: + return CS_MODE_RISCV_ZBB; + case RISCV_FeatureStdExtZbc: + return CS_MODE_RISCV_ZBC; + case RISCV_FeatureStdExtZbkb: + return CS_MODE_RISCV_ZBKB; + case RISCV_FeatureStdExtZbkc: + return CS_MODE_RISCV_ZBKC; + case RISCV_FeatureStdExtZbkx: + return CS_MODE_RISCV_ZBKX; + case RISCV_FeatureStdExtZbs: + return CS_MODE_RISCV_ZBS; + } + + return 0; +} + +size_t expect_str(const char *arch_str, const char *expected, size_t curr) { + size_t l = strlen(expected); + if (strncmp(&arch_str[curr], expected, l) != 0) { + RZ_LOG_ERROR("Invalid architecture string: expected %s to equal %s", + arch_str, expected); + return curr; + } + + return curr + l; +} + +size_t expect_char(const char *arch_str, char c, size_t curr) { + if (arch_str[curr] == '\0') { + RZ_LOG_ERROR("Invalid architecture string: expected %c, found end of string\n", + c); + return curr; + } + + if (arch_str[curr] != c) { + RZ_LOG_ERROR("Invalid architecture string: expected %c to equal %c\n", + arch_str[curr], c); + return curr; + } + + return curr + 1; +} + +size_t expect_any_str_of(const char *arch_str, const char **expected, size_t curr) { + size_t i = 0; + while (expected[i] != NULL) { + if (strncmp(&arch_str[curr], expected[i], strlen(expected[i])) == 0) { + return curr + strlen(expected[i]); + } + i++; + } + + i = 0; + RZ_LOG_ERROR("Invalid architecture string: expected %s to equal any string from [", + arch_str); + while (expected[i] != NULL) { + RZ_LOG_ERROR("%s,", expected[i]); + i++; + } + RZ_LOG_ERROR("]\n"); + + return curr; +} + +size_t skip_digit_sequence(const char *arch_str, size_t curr) { + while (arch_str[curr] != '\0') { + if (!isdigit(arch_str[curr])) { + break; + } + curr++; + } + + return curr; +} + +size_t skip_extension_version(const char *arch_str, size_t curr) { + curr = skip_digit_sequence(arch_str, curr); + // now reached the 'p' in the middle of the 2 version numbers + size_t curr1 = expect_char(arch_str, 'p', curr); + if (curr1 == curr) { + // error, expected p + RZ_LOG_ERROR("Invalid architecture string: expected the version separator 'p' at index %zu in archiecture string %s, found %c instead\n", + curr, arch_str, arch_str[curr]); + return curr; + } + + return skip_digit_sequence(arch_str, curr1); +} + +size_t skip_till_char(const char *arch_str, char c, size_t curr) { + while (arch_str[curr] != '\0') { + if (arch_str[curr] == c) { + return curr; + } + curr++; + } + + return curr; +} + +#define CHECK_BAD_HEADER(before, after) \ + if (before == after) { \ + RZ_LOG_ERROR("Bad architecture string header at index %zu in archiecture string %s" \ + "\n Will continue parsing the rest of the string from the next '_'\n", \ + before, arch_str); \ + return skip_till_char(arch_str, '_', before); \ + } + +size_t expect_architecture_string_header(const char *arch_str) { + size_t curr = 0; + size_t curr1 = expect_str(arch_str, "rv", curr); + CHECK_BAD_HEADER(curr, curr1); + size_t curr2 = expect_any_str_of(arch_str, (const char *[]){ "32", "64", NULL }, curr1); + CHECK_BAD_HEADER(curr1, curr2); + size_t curr3 = expect_char(arch_str, 'i', curr2); + CHECK_BAD_HEADER(curr2, curr3); + size_t curr4 = skip_extension_version(arch_str, curr3); + CHECK_BAD_HEADER(curr3, curr4) + size_t curr5 = expect_char(arch_str, '_', curr4); + CHECK_BAD_HEADER(curr4, curr5) + + return curr5; +} + +bool expect_extension(const char *arch_str, size_t *curr, cs_mode *cs_mode) { + ut64 flag = ~0; + + switch (try_consume_riscv_ext_from(arch_str, curr, &flag)) { + case RISCV_EXT_PARSE_END_OF_STRING: + *cs_mode |= cs_mode_from_feature_flag(flag); + return true; + + case RISCV_EXT_PARSE_STOPPED_AT_NUMBER: + *cs_mode |= cs_mode_from_feature_flag(flag); + *curr = skip_extension_version(arch_str, *curr); + return false; + + // weird, this means the extension is malformed as it has no version + // but we can still continue with the next underscore + case RISCV_EXT_PARSE_STOPPED_AT_UNDERSCORE: + *curr = expect_char(arch_str, '_', *curr); + *cs_mode |= cs_mode_from_feature_flag(flag); + *curr = skip_extension_version(arch_str, *curr); + return false; + + // bad mode, don't accumulate into result + // but keep ignoring chars till the underscore or end of string + case RISCV_EXT_PARSE_STOPPED_AT_UNEXPECTED: + *curr = skip_till_char(arch_str, '_', *curr); + return false; + + case RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING: + return true; + + case RISCV_EXT_PARSE_NO_MATCH_NUMBER: + *curr = skip_extension_version(arch_str, *curr); + return false; + + case RISCV_EXT_PARSE_NO_MATCH_UNDERSCORE: + *curr = expect_char(arch_str, '_', *curr); + *curr = skip_extension_version(arch_str, *curr); + return false; + + case RISCV_EXT_PARSE_NO_MATCH_UNEXPECTED: + *curr = skip_till_char(arch_str, '_', *curr); + return false; + } + + // unreachable + RZ_LOG_ERROR("UNREACHABLE STATE WHEN PARSING RISCV ARCH STRING"); + return true; // done, this is a bad state and we should terminate parsing immediately +} + +cs_mode expect_extensions(const char *arch_str, size_t curr) { + cs_mode cs_mode = 0; + bool done = false; + while (arch_str[curr] != '\0' && !done) { + done = expect_extension(arch_str, &curr, &cs_mode); + if (arch_str[curr] != '\0') { + curr = expect_char(arch_str, '_', curr); + } + } + + return cs_mode; +} + +bool check_all_whitespace(const char *str) { + while (*str) { + if (!isspace(*str)) { + return false; + } + str++; + } + + return true; +} +size_t mode_from_arch_string(const char *arch_str) { + if (!arch_str || check_all_whitespace(arch_str)) { + RZ_LOG_WARN("RISCV: empty architecture string, no non-default extensions enabled\n"); + return 0; + } + size_t curr = expect_architecture_string_header(arch_str); + + return expect_extensions(arch_str, curr); +} #include "analysis/analysis_riscv_cs.c" #include "asm/asm_riscv_cs.c" diff --git a/librz/arch/p/arch_riscv_extension_parser.inc b/librz/arch/p/arch_riscv_extension_parser.inc new file mode 100644 index 00000000000..6044552620a --- /dev/null +++ b/librz/arch/p/arch_riscv_extension_parser.inc @@ -0,0 +1,2146 @@ +/* + * + + *********************************************** AUTO-GENERATED CODE, DO NOT EDIT BY HAND! * *********************************************** + + * RISC-V Extension Parser Using a Trie trick + * Generated from arch/RISCV/RISCVGenSubtargetInfo.inc in Capstone sources + * + * This function parses a single RISC-V extension name and ORs the corresponding + * feature flags with an accumulator 'mode'. + * + * Trie Diagram: + * ROOT + * ├── a [RISCV_FeatureStdExtA] + * ├── c [RISCV_FeatureStdExtC] + * ├── d [RISCV_FeatureStdExtD] + * ├── f [RISCV_FeatureStdExtF] + * ├── h [RISCV_FeatureStdExtH] + * ├── i [RISCV_FeatureStdExtI] + * ├── m [RISCV_FeatureStdExtM] + * ├── s + * │ ├── m + * │ │ ├── a + * │ │ │ └── i + * │ │ │ └── a [RISCV_FeatureStdExtSmaia] + * │ │ └── e + * │ │ └── p + * │ │ └── m + * │ │ └── p [RISCV_FeatureStdExtSmepmp] + * │ ├── s + * │ │ └── a + * │ │ └── i + * │ │ └── a [RISCV_FeatureStdExtSsaia] + * │ └── v + * │ ├── i + * │ │ └── n + * │ │ └── v + * │ │ └── a + * │ │ └── l [RISCV_FeatureStdExtSvinval] + * │ ├── n + * │ │ └── a + * │ │ └── p + * │ │ └── o + * │ │ └── t [RISCV_FeatureStdExtSvnapot] + * │ └── p + * │ └── b + * │ └── m + * │ └── t [RISCV_FeatureStdExtSvpbmt] + * ├── v [RISCV_FeatureStdExtV] + * └── z + * ├── a + * │ ├── 1 + * │ │ └── 2 + * │ │ └── 8 + * │ │ └── r + * │ │ └── s [RISCV_FeatureStdExtZa128rs] + * │ ├── 6 + * │ │ └── 4 + * │ │ └── r + * │ │ └── s [RISCV_FeatureStdExtZa64rs] + * │ ├── c + * │ │ └── a + * │ │ └── s [RISCV_FeatureStdExtZacas] + * │ └── w + * │ └── r + * │ └── s [RISCV_FeatureStdExtZawrs] + * ├── b + * │ ├── a [RISCV_FeatureStdExtZba] + * │ ├── b [RISCV_FeatureStdExtZbb] + * │ ├── c [RISCV_FeatureStdExtZbc] + * │ ├── k + * │ │ ├── b [RISCV_FeatureStdExtZbkb] + * │ │ ├── c [RISCV_FeatureStdExtZbkc] + * │ │ └── x [RISCV_FeatureStdExtZbkx] + * │ └── s [RISCV_FeatureStdExtZbs] + * ├── c + * │ ├── a [RISCV_FeatureStdExtZca] + * │ ├── b [RISCV_FeatureStdExtZcb] + * │ ├── d [RISCV_FeatureStdExtZcd] + * │ ├── e [RISCV_FeatureStdExtZce] + * │ ├── f [RISCV_FeatureStdExtZcf] + * │ └── m + * │ ├── o + * │ │ └── p [RISCV_FeatureStdExtZcmop] + * │ ├── p [RISCV_FeatureStdExtZcmp] + * │ └── t [RISCV_FeatureStdExtZcmt] + * ├── d + * │ └── i + * │ └── n + * │ └── x [RISCV_FeatureStdExtZdinx] + * ├── f + * │ ├── a [RISCV_FeatureStdExtZfa] + * │ ├── b + * │ │ └── f + * │ │ └── m + * │ │ └── i + * │ │ └── n [RISCV_FeatureStdExtZfbfmin] + * │ ├── h [RISCV_FeatureStdExtZfh] + * │ │ └── m + * │ │ └── i + * │ │ └── n [RISCV_FeatureStdExtZfhmin] + * │ └── i + * │ └── n + * │ └── x [RISCV_FeatureStdExtZfinx] + * ├── h + * │ └── i + * │ └── n + * │ └── x [RISCV_FeatureStdExtZhinx] + * │ └── m + * │ └── i + * │ └── n [RISCV_FeatureStdExtZhinxmin] + * ├── i + * │ ├── c + * │ │ ├── 6 + * │ │ │ └── 4 + * │ │ │ └── b [RISCV_FeatureStdExtZic64b] + * │ │ ├── b + * │ │ │ └── o + * │ │ │ ├── m [RISCV_FeatureStdExtZicbom] + * │ │ │ ├── p [RISCV_FeatureStdExtZicbop] + * │ │ │ └── z [RISCV_FeatureStdExtZicboz] + * │ │ ├── c + * │ │ │ ├── a + * │ │ │ │ └── m + * │ │ │ │ └── o + * │ │ │ │ └── a [RISCV_FeatureStdExtZiccamoa] + * │ │ │ ├── i + * │ │ │ │ └── f [RISCV_FeatureStdExtZiccif] + * │ │ │ ├── l + * │ │ │ │ └── s + * │ │ │ │ └── m [RISCV_FeatureStdExtZicclsm] + * │ │ │ └── r + * │ │ │ └── s + * │ │ │ └── e [RISCV_FeatureStdExtZiccrse] + * │ │ ├── f + * │ │ │ └── i + * │ │ │ ├── l + * │ │ │ │ └── p [RISCV_FeatureStdExtZicfilp] + * │ │ │ └── s + * │ │ │ └── s [RISCV_FeatureStdExtZicfiss] + * │ │ ├── n + * │ │ │ └── t + * │ │ │ └── r [RISCV_FeatureStdExtZicntr] + * │ │ ├── o + * │ │ │ └── n + * │ │ │ └── d [RISCV_FeatureStdExtZicond] + * │ │ └── s + * │ │ └── r [RISCV_FeatureStdExtZicsr] + * │ ├── f + * │ │ └── e + * │ │ └── n + * │ │ └── c + * │ │ └── e + * │ │ └── i [RISCV_FeatureStdExtZifencei] + * │ ├── h + * │ │ ├── i + * │ │ │ └── n + * │ │ │ └── t + * │ │ │ ├── n + * │ │ │ │ └── t + * │ │ │ │ └── l [RISCV_FeatureStdExtZihintntl] + * │ │ │ └── p + * │ │ │ └── a + * │ │ │ └── u + * │ │ │ └── s + * │ │ │ └── e [RISCV_FeatureStdExtZihintpause] + * │ │ └── p + * │ │ └── m [RISCV_FeatureStdExtZihpm] + * │ └── m + * │ └── o + * │ └── p [RISCV_FeatureStdExtZimop] + * ├── k [RISCV_FeatureStdExtZk] + * │ ├── n [RISCV_FeatureStdExtZkn] + * │ │ ├── d [RISCV_FeatureStdExtZknd] + * │ │ ├── e [RISCV_FeatureStdExtZkne] + * │ │ └── h [RISCV_FeatureStdExtZknh] + * │ ├── r [RISCV_FeatureStdExtZkr] + * │ ├── s [RISCV_FeatureStdExtZks] + * │ │ ├── e + * │ │ │ └── d [RISCV_FeatureStdExtZksed] + * │ │ └── h [RISCV_FeatureStdExtZksh] + * │ └── t [RISCV_FeatureStdExtZkt] + * ├── m + * │ └── m + * │ └── u + * │ └── l [RISCV_FeatureStdExtZmmul] + * ├── t + * │ └── s + * │ └── o [RISCV_FeatureStdExtZtso] + * └── v + * ├── b + * │ ├── b [RISCV_FeatureStdExtZvbb] + * │ └── c [RISCV_FeatureStdExtZvbc] + * ├── e + * │ ├── 3 + * │ │ └── 2 + * │ │ ├── f [RISCV_FeatureStdExtZve32f] + * │ │ └── x [RISCV_FeatureStdExtZve32x] + * │ └── 6 + * │ └── 4 + * │ ├── d [RISCV_FeatureStdExtZve64d] + * │ ├── f [RISCV_FeatureStdExtZve64f] + * │ └── x [RISCV_FeatureStdExtZve64x] + * ├── f + * │ ├── b + * │ │ └── f + * │ │ ├── m + * │ │ │ └── i + * │ │ │ └── n [RISCV_FeatureStdExtZvfbfmin] + * │ │ └── w + * │ │ └── m + * │ │ └── a [RISCV_FeatureStdExtZvfbfwma] + * │ └── h [RISCV_FeatureStdExtZvfh] + * │ └── m + * │ └── i + * │ └── n [RISCV_FeatureStdExtZvfhmin] + * ├── k + * │ ├── b [RISCV_FeatureStdExtZvkb] + * │ ├── g [RISCV_FeatureStdExtZvkg] + * │ ├── n [RISCV_FeatureStdExtZvkn] + * │ │ ├── c [RISCV_FeatureStdExtZvknc] + * │ │ ├── e + * │ │ │ └── d [RISCV_FeatureStdExtZvkned] + * │ │ ├── g [RISCV_FeatureStdExtZvkng] + * │ │ └── h + * │ │ ├── a [RISCV_FeatureStdExtZvknha] + * │ │ └── b [RISCV_FeatureStdExtZvknhb] + * │ ├── s [RISCV_FeatureStdExtZvks] + * │ │ ├── c [RISCV_FeatureStdExtZvksc] + * │ │ ├── e + * │ │ │ └── d [RISCV_FeatureStdExtZvksed] + * │ │ ├── g [RISCV_FeatureStdExtZvksg] + * │ │ └── h [RISCV_FeatureStdExtZvksh] + * │ └── t [RISCV_FeatureStdExtZvkt] + * └── l + * ├── 1 + * │ ├── 0 + * │ │ └── 2 + * │ │ └── 4 + * │ │ └── b [RISCV_FeatureStdExtZvl1024b] + * │ ├── 2 + * │ │ └── 8 + * │ │ └── b [RISCV_FeatureStdExtZvl128b] + * │ └── 6 + * │ └── 3 + * │ └── 8 + * │ └── 4 + * │ └── b [RISCV_FeatureStdExtZvl16384b] + * ├── 2 + * │ ├── 0 + * │ │ └── 4 + * │ │ └── 8 + * │ │ └── b [RISCV_FeatureStdExtZvl2048b] + * │ └── 5 + * │ └── 6 + * │ └── b [RISCV_FeatureStdExtZvl256b] + * ├── 3 + * │ └── 2 + * │ ├── 7 + * │ │ └── 6 + * │ │ └── 8 + * │ │ └── b [RISCV_FeatureStdExtZvl32768b] + * │ └── b [RISCV_FeatureStdExtZvl32b] + * ├── 4 + * │ └── 0 + * │ └── 9 + * │ └── 6 + * │ └── b [RISCV_FeatureStdExtZvl4096b] + * ├── 5 + * │ └── 1 + * │ └── 2 + * │ └── b [RISCV_FeatureStdExtZvl512b] + * ├── 6 + * │ ├── 4 + * │ │ └── b [RISCV_FeatureStdExtZvl64b] + * │ └── 5 + * │ └── 5 + * │ └── 3 + * │ └── 6 + * │ └── b [RISCV_FeatureStdExtZvl65536b] + * └── 8 + * └── 1 + * └── 9 + * └── 2 + * └── b [RISCV_FeatureStdExtZvl8192b] + */ + +#define RISCV_FeatureStdExtA 0 + +#define RISCV_FeatureStdExtC 1 + +#define RISCV_FeatureStdExtD 2 + +#define RISCV_FeatureStdExtF 3 + +#define RISCV_FeatureStdExtH 4 + +#define RISCV_FeatureStdExtI 5 + +#define RISCV_FeatureStdExtM 6 + +#define RISCV_FeatureStdExtSmaia 7 + +#define RISCV_FeatureStdExtSmepmp 8 + +#define RISCV_FeatureStdExtSsaia 9 + +#define RISCV_FeatureStdExtSvinval 10 + +#define RISCV_FeatureStdExtSvnapot 11 + +#define RISCV_FeatureStdExtSvpbmt 12 + +#define RISCV_FeatureStdExtV 13 + +#define RISCV_FeatureStdExtZa64rs 14 + +#define RISCV_FeatureStdExtZa128rs 15 + +#define RISCV_FeatureStdExtZacas 16 + +#define RISCV_FeatureStdExtZawrs 17 + +#define RISCV_FeatureStdExtZba 18 + +#define RISCV_FeatureStdExtZbb 19 + +#define RISCV_FeatureStdExtZbc 20 + +#define RISCV_FeatureStdExtZbkb 21 + +#define RISCV_FeatureStdExtZbkc 22 + +#define RISCV_FeatureStdExtZbkx 23 + +#define RISCV_FeatureStdExtZbs 24 + +#define RISCV_FeatureStdExtZca 25 + +#define RISCV_FeatureStdExtZcb 26 + +#define RISCV_FeatureStdExtZcd 27 + +#define RISCV_FeatureStdExtZce 28 + +#define RISCV_FeatureStdExtZcf 29 + +#define RISCV_FeatureStdExtZcmop 30 + +#define RISCV_FeatureStdExtZcmp 31 + +#define RISCV_FeatureStdExtZcmt 32 + +#define RISCV_FeatureStdExtZdinx 33 + +#define RISCV_FeatureStdExtZfa 34 + +#define RISCV_FeatureStdExtZfbfmin 35 + +#define RISCV_FeatureStdExtZfh 36 + +#define RISCV_FeatureStdExtZfhmin 37 + +#define RISCV_FeatureStdExtZfinx 38 + +#define RISCV_FeatureStdExtZhinx 39 + +#define RISCV_FeatureStdExtZhinxmin 40 + +#define RISCV_FeatureStdExtZic64b 41 + +#define RISCV_FeatureStdExtZicbom 42 + +#define RISCV_FeatureStdExtZicbop 43 + +#define RISCV_FeatureStdExtZicboz 44 + +#define RISCV_FeatureStdExtZiccamoa 45 + +#define RISCV_FeatureStdExtZiccif 46 + +#define RISCV_FeatureStdExtZicclsm 47 + +#define RISCV_FeatureStdExtZiccrse 48 + +#define RISCV_FeatureStdExtZicfilp 49 + +#define RISCV_FeatureStdExtZicfiss 50 + +#define RISCV_FeatureStdExtZicntr 51 + +#define RISCV_FeatureStdExtZicond 52 + +#define RISCV_FeatureStdExtZicsr 53 + +#define RISCV_FeatureStdExtZifencei 54 + +#define RISCV_FeatureStdExtZihintntl 55 + +#define RISCV_FeatureStdExtZihintpause 56 + +#define RISCV_FeatureStdExtZihpm 57 + +#define RISCV_FeatureStdExtZimop 58 + +#define RISCV_FeatureStdExtZk 59 + +#define RISCV_FeatureStdExtZkn 60 + +#define RISCV_FeatureStdExtZknd 61 + +#define RISCV_FeatureStdExtZkne 62 + +#define RISCV_FeatureStdExtZknh 63 + +#define RISCV_FeatureStdExtZkr 64 + +#define RISCV_FeatureStdExtZks 65 + +#define RISCV_FeatureStdExtZksed 66 + +#define RISCV_FeatureStdExtZksh 67 + +#define RISCV_FeatureStdExtZkt 68 + +#define RISCV_FeatureStdExtZmmul 69 + +#define RISCV_FeatureStdExtZtso 70 + +#define RISCV_FeatureStdExtZvbb 71 + +#define RISCV_FeatureStdExtZvbc 72 + +#define RISCV_FeatureStdExtZve32f 73 + +#define RISCV_FeatureStdExtZve32x 74 + +#define RISCV_FeatureStdExtZve64d 75 + +#define RISCV_FeatureStdExtZve64f 76 + +#define RISCV_FeatureStdExtZve64x 77 + +#define RISCV_FeatureStdExtZvfbfmin 78 + +#define RISCV_FeatureStdExtZvfbfwma 79 + +#define RISCV_FeatureStdExtZvfh 80 + +#define RISCV_FeatureStdExtZvfhmin 81 + +#define RISCV_FeatureStdExtZvkb 82 + +#define RISCV_FeatureStdExtZvkg 83 + +#define RISCV_FeatureStdExtZvkn 84 + +#define RISCV_FeatureStdExtZvknc 85 + +#define RISCV_FeatureStdExtZvkned 86 + +#define RISCV_FeatureStdExtZvkng 87 + +#define RISCV_FeatureStdExtZvknha 88 + +#define RISCV_FeatureStdExtZvknhb 89 + +#define RISCV_FeatureStdExtZvks 90 + +#define RISCV_FeatureStdExtZvksc 91 + +#define RISCV_FeatureStdExtZvksed 92 + +#define RISCV_FeatureStdExtZvksg 93 + +#define RISCV_FeatureStdExtZvksh 94 + +#define RISCV_FeatureStdExtZvkt 95 + +#define RISCV_FeatureStdExtZvl32b 96 + +#define RISCV_FeatureStdExtZvl64b 97 + +#define RISCV_FeatureStdExtZvl128b 98 + +#define RISCV_FeatureStdExtZvl256b 99 + +#define RISCV_FeatureStdExtZvl512b 100 + +#define RISCV_FeatureStdExtZvl1024b 101 + +#define RISCV_FeatureStdExtZvl2048b 102 + +#define RISCV_FeatureStdExtZvl4096b 103 + +#define RISCV_FeatureStdExtZvl8192b 104 + +#define RISCV_FeatureStdExtZvl16384b 105 + +#define RISCV_FeatureStdExtZvl32768b 106 + +#define RISCV_FeatureStdExtZvl65536b 107 +/* Parse result enum - indicates why parsing stopped */ +typedef enum { + RISCV_EXT_PARSE_END_OF_STRING, /* Stopped at '\0' - valid extension found */ + RISCV_EXT_PARSE_STOPPED_AT_NUMBER, /* Stopped at a digit - valid extension found */ + RISCV_EXT_PARSE_STOPPED_AT_UNDERSCORE, /* Stopped at '_' - valid extension found */ + RISCV_EXT_PARSE_STOPPED_AT_UNEXPECTED, /* Stopped at unexpected char - valid extension found */ + RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING, /* Reached '\0' - no valid extension */ + RISCV_EXT_PARSE_NO_MATCH_NUMBER, /* Hit number - no valid extension at this point */ + RISCV_EXT_PARSE_NO_MATCH_UNDERSCORE, /* Hit underscore - no valid extension at this point */ + RISCV_EXT_PARSE_NO_MATCH_UNEXPECTED, /* Hit unexpected char - no valid extension */ +} riscv_extension_parse_result_t; + +/* Macro: Stop parsing with a matched extension */ +#ifndef MATCH_CALLBACK +#define MATCH_CALLBACK(feature_enum) +#endif + +#ifndef FINI_EXT_CALLBACKS +#define FINI_EXT_CALLBACKS() +#endif + +#define STOP_WITH_MATCH(feature_enum) \ + do { \ + MATCH_CALLBACK(feature_enum); \ + *idx = (size_t)(p - ext_name); \ + *mode = feature_enum; \ + FINI_EXT_CALLBACKS(); \ + if (*p == '\0') { \ + return RISCV_EXT_PARSE_END_OF_STRING; \ + } else if (*p >= '0' && *p <= '9') { \ + return RISCV_EXT_PARSE_STOPPED_AT_NUMBER; \ + } else if (*p == '_') { \ + return RISCV_EXT_PARSE_STOPPED_AT_UNDERSCORE; \ + } else { \ + return RISCV_EXT_PARSE_STOPPED_AT_UNEXPECTED; \ + } \ + } while (0) + +/* Macro: Stop parsing without a match */ +#define STOP_WITHOUT_MATCH() \ + do { \ + *idx = (size_t)(p - ext_name); \ + if (*p == '\0') { \ + return RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING; \ + } else if (*p >= '0' && *p <= '9') { \ + return RISCV_EXT_PARSE_NO_MATCH_NUMBER; \ + } else if (*p == '_') { \ + return RISCV_EXT_PARSE_NO_MATCH_UNDERSCORE; \ + } else { \ + return RISCV_EXT_PARSE_NO_MATCH_UNEXPECTED; \ + } \ + } while (0) + +/** + * Main parse routine: Try to consume a RISC-V extension name from the architecture string at a given position. + * + * @param arch_str: The full architecture string + * @param idx: Pointer to current index (will be updated to show consumed length) + * @param mode: Pointer to the feature accumulator (will be ORed with the feature flag if extension found) + * @return: Parse result indicating why parsing stopped and whether a match was found + * + * Stopping conditions: + * - '\0' (end of string) + * - '0'-'9' (version number) + * - '_' (extension separator) + * - Any unexpected character + * + * The function uses a trie-based approach for efficient parsing. + * State comments show the current position in the trie: + * 'abc...' means we've matched 'abc' and are looking for more + * 'abc(!x)' means we've matched 'abc' but encountered unexpected char instead of 'x' + */ +#ifndef INIT_EXT_CALLBACKS +#define INIT_EXT_CALLBACKS() +#endif + +static inline riscv_extension_parse_result_t +try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode) { + if (!ext_name || !idx || !mode) { + return RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING; + } + + INIT_EXT_CALLBACKS(); + const char *p = ext_name + *idx; + + if (*p == '\0') { + return RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING; + } + + /* State: '' expecting [acdfhimsvz] */ + if (*p == 'a') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtA); + } else if (*p == 'c') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtC); + } else if (*p == 'd') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtD); + } else if (*p == 'f') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtF); + } else if (*p == 'h') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtH); + } else if (*p == 'i') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtI); + } else if (*p == 'm') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtM); + } else if (*p == 's') { + p++; + /* State: 's' expecting [msv] */ + if (*p == 'm') { + p++; + /* State: 'sm' expecting [ae] */ + if (*p == 'a') { + p++; + /* State: 'sma' expecting [i] */ + if (*p == 'i') { + p++; + /* State: 'smai' expecting [a] */ + if (*p == 'a') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtSmaia); + } else { + /* Unexpected char at 'smai', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'sma', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'e') { + p++; + /* State: 'sme' expecting [p] */ + if (*p == 'p') { + p++; + /* State: 'smep' expecting [m] */ + if (*p == 'm') { + p++; + /* State: 'smepm' expecting [p] */ + if (*p == 'p') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtSmepmp); + } else { + /* Unexpected char at 'smepm', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'smep', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'sme', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'sm', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 's') { + p++; + /* State: 'ss' expecting [a] */ + if (*p == 'a') { + p++; + /* State: 'ssa' expecting [i] */ + if (*p == 'i') { + p++; + /* State: 'ssai' expecting [a] */ + if (*p == 'a') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtSsaia); + } else { + /* Unexpected char at 'ssai', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'ssa', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'ss', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'v') { + p++; + /* State: 'sv' expecting [inp] */ + if (*p == 'i') { + p++; + /* State: 'svi' expecting [n] */ + if (*p == 'n') { + p++; + /* State: 'svin' expecting [v] */ + if (*p == 'v') { + p++; + /* State: 'svinv' expecting [a] */ + if (*p == 'a') { + p++; + /* State: 'svinva' expecting [l] */ + if (*p == 'l') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtSvinval); + } else { + /* Unexpected char at 'svinva', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'svinv', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'svin', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'svi', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'n') { + p++; + /* State: 'svn' expecting [a] */ + if (*p == 'a') { + p++; + /* State: 'svna' expecting [p] */ + if (*p == 'p') { + p++; + /* State: 'svnap' expecting [o] */ + if (*p == 'o') { + p++; + /* State: 'svnapo' expecting [t] */ + if (*p == 't') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtSvnapot); + } else { + /* Unexpected char at 'svnapo', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'svnap', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'svna', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'svn', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'p') { + p++; + /* State: 'svp' expecting [b] */ + if (*p == 'b') { + p++; + /* State: 'svpb' expecting [m] */ + if (*p == 'm') { + p++; + /* State: 'svpbm' expecting [t] */ + if (*p == 't') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtSvpbmt); + } else { + /* Unexpected char at 'svpbm', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'svpb', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'svp', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'sv', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 's', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'v') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtV); + } else if (*p == 'z') { + p++; + /* State: 'z' expecting [abcdfhikmtv] */ + if (*p == 'a') { + p++; + /* State: 'za' expecting [16cw] */ + if (*p == '1') { + p++; + /* State: 'za1' expecting [2] */ + if (*p == '2') { + p++; + /* State: 'za12' expecting [8] */ + if (*p == '8') { + p++; + /* State: 'za128' expecting [r] */ + if (*p == 'r') { + p++; + /* State: 'za128r' expecting [s] */ + if (*p == 's') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZa128rs); + } else { + /* Unexpected char at 'za128r', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'za128', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'za12', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'za1', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '6') { + p++; + /* State: 'za6' expecting [4] */ + if (*p == '4') { + p++; + /* State: 'za64' expecting [r] */ + if (*p == 'r') { + p++; + /* State: 'za64r' expecting [s] */ + if (*p == 's') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZa64rs); + } else { + /* Unexpected char at 'za64r', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'za64', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'za6', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'c') { + p++; + /* State: 'zac' expecting [a] */ + if (*p == 'a') { + p++; + /* State: 'zaca' expecting [s] */ + if (*p == 's') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZacas); + } else { + /* Unexpected char at 'zaca', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zac', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'w') { + p++; + /* State: 'zaw' expecting [r] */ + if (*p == 'r') { + p++; + /* State: 'zawr' expecting [s] */ + if (*p == 's') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZawrs); + } else { + /* Unexpected char at 'zawr', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zaw', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'za', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'b') { + p++; + /* State: 'zb' expecting [abcks] */ + if (*p == 'a') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZba); + } else if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZbb); + } else if (*p == 'c') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZbc); + } else if (*p == 'k') { + p++; + /* State: 'zbk' expecting [bcx] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZbkb); + } else if (*p == 'c') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZbkc); + } else if (*p == 'x') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZbkx); + } else { + /* Unexpected char at 'zbk', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 's') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZbs); + } else { + /* Unexpected char at 'zb', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'c') { + p++; + /* State: 'zc' expecting [abdefm] */ + if (*p == 'a') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZca); + } else if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZcb); + } else if (*p == 'd') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZcd); + } else if (*p == 'e') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZce); + } else if (*p == 'f') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZcf); + } else if (*p == 'm') { + p++; + /* State: 'zcm' expecting [opt] */ + if (*p == 'o') { + p++; + /* State: 'zcmo' expecting [p] */ + if (*p == 'p') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZcmop); + } else { + /* Unexpected char at 'zcmo', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'p') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZcmp); + } else if (*p == 't') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZcmt); + } else { + /* Unexpected char at 'zcm', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zc', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'd') { + p++; + /* State: 'zd' expecting [i] */ + if (*p == 'i') { + p++; + /* State: 'zdi' expecting [n] */ + if (*p == 'n') { + p++; + /* State: 'zdin' expecting [x] */ + if (*p == 'x') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZdinx); + } else { + /* Unexpected char at 'zdin', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zdi', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zd', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'f') { + p++; + /* State: 'zf' expecting [abhi] */ + if (*p == 'a') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZfa); + } else if (*p == 'b') { + p++; + /* State: 'zfb' expecting [f] */ + if (*p == 'f') { + p++; + /* State: 'zfbf' expecting [m] */ + if (*p == 'm') { + p++; + /* State: 'zfbfm' expecting [i] */ + if (*p == 'i') { + p++; + /* State: 'zfbfmi' expecting [n] */ + if (*p == 'n') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZfbfmin); + } else { + /* Unexpected char at 'zfbfmi', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zfbfm', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zfbf', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zfb', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'h') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZfh); + + /* State: 'zfh' expecting [m] */ + if (*p == 'm') { + p++; + /* State: 'zfhm' expecting [i] */ + if (*p == 'i') { + p++; + /* State: 'zfhmi' expecting [n] */ + if (*p == 'n') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZfhmin); + } else { + /* Unexpected char at 'zfhmi', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zfhm', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char, but 'zfh' was valid */ + STOP_WITH_MATCH(RISCV_FeatureStdExtZfh); + } + } else if (*p == 'i') { + p++; + /* State: 'zfi' expecting [n] */ + if (*p == 'n') { + p++; + /* State: 'zfin' expecting [x] */ + if (*p == 'x') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZfinx); + } else { + /* Unexpected char at 'zfin', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zfi', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zf', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'h') { + p++; + /* State: 'zh' expecting [i] */ + if (*p == 'i') { + p++; + /* State: 'zhi' expecting [n] */ + if (*p == 'n') { + p++; + /* State: 'zhin' expecting [x] */ + if (*p == 'x') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZhinx); + + /* State: 'zhinx' expecting [m] */ + if (*p == 'm') { + p++; + /* State: 'zhinxm' expecting [i] */ + if (*p == 'i') { + p++; + /* State: 'zhinxmi' expecting [n] */ + if (*p == 'n') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZhinxmin); + } else { + /* Unexpected char at 'zhinxmi', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zhinxm', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char, but 'zhinx' was valid */ + STOP_WITH_MATCH(RISCV_FeatureStdExtZhinx); + } + } else { + /* Unexpected char at 'zhin', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zhi', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zh', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'i') { + p++; + /* State: 'zi' expecting [cfhm] */ + if (*p == 'c') { + p++; + /* State: 'zic' expecting [6bcfnos] */ + if (*p == '6') { + p++; + /* State: 'zic6' expecting [4] */ + if (*p == '4') { + p++; + /* State: 'zic64' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZic64b); + } else { + /* Unexpected char at 'zic64', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zic6', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'b') { + p++; + /* State: 'zicb' expecting [o] */ + if (*p == 'o') { + p++; + /* State: 'zicbo' expecting [mpz] */ + if (*p == 'm') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZicbom); + } else if (*p == 'p') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZicbop); + } else if (*p == 'z') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZicboz); + } else { + /* Unexpected char at 'zicbo', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zicb', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'c') { + p++; + /* State: 'zicc' expecting [ailr] */ + if (*p == 'a') { + p++; + /* State: 'zicca' expecting [m] */ + if (*p == 'm') { + p++; + /* State: 'ziccam' expecting [o] */ + if (*p == 'o') { + p++; + /* State: 'ziccamo' expecting [a] */ + if (*p == 'a') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZiccamoa); + } else { + /* Unexpected char at 'ziccamo', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'ziccam', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zicca', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'i') { + p++; + /* State: 'zicci' expecting [f] */ + if (*p == 'f') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZiccif); + } else { + /* Unexpected char at 'zicci', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'l') { + p++; + /* State: 'ziccl' expecting [s] */ + if (*p == 's') { + p++; + /* State: 'ziccls' expecting [m] */ + if (*p == 'm') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZicclsm); + } else { + /* Unexpected char at 'ziccls', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'ziccl', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'r') { + p++; + /* State: 'ziccr' expecting [s] */ + if (*p == 's') { + p++; + /* State: 'ziccrs' expecting [e] */ + if (*p == 'e') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZiccrse); + } else { + /* Unexpected char at 'ziccrs', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'ziccr', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zicc', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'f') { + p++; + /* State: 'zicf' expecting [i] */ + if (*p == 'i') { + p++; + /* State: 'zicfi' expecting [ls] */ + if (*p == 'l') { + p++; + /* State: 'zicfil' expecting [p] */ + if (*p == 'p') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZicfilp); + } else { + /* Unexpected char at 'zicfil', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 's') { + p++; + /* State: 'zicfis' expecting [s] */ + if (*p == 's') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZicfiss); + } else { + /* Unexpected char at 'zicfis', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zicfi', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zicf', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'n') { + p++; + /* State: 'zicn' expecting [t] */ + if (*p == 't') { + p++; + /* State: 'zicnt' expecting [r] */ + if (*p == 'r') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZicntr); + } else { + /* Unexpected char at 'zicnt', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zicn', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'o') { + p++; + /* State: 'zico' expecting [n] */ + if (*p == 'n') { + p++; + /* State: 'zicon' expecting [d] */ + if (*p == 'd') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZicond); + } else { + /* Unexpected char at 'zicon', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zico', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 's') { + p++; + /* State: 'zics' expecting [r] */ + if (*p == 'r') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZicsr); + } else { + /* Unexpected char at 'zics', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zic', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'f') { + p++; + /* State: 'zif' expecting [e] */ + if (*p == 'e') { + p++; + /* State: 'zife' expecting [n] */ + if (*p == 'n') { + p++; + /* State: 'zifen' expecting [c] */ + if (*p == 'c') { + p++; + /* State: 'zifenc' expecting [e] */ + if (*p == 'e') { + p++; + /* State: 'zifence' expecting [i] */ + if (*p == 'i') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZifencei); + } else { + /* Unexpected char at 'zifence', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zifenc', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zifen', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zife', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zif', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'h') { + p++; + /* State: 'zih' expecting [ip] */ + if (*p == 'i') { + p++; + /* State: 'zihi' expecting [n] */ + if (*p == 'n') { + p++; + /* State: 'zihin' expecting [t] */ + if (*p == 't') { + p++; + /* State: 'zihint' expecting [np] */ + if (*p == 'n') { + p++; + /* State: 'zihintn' expecting [t] */ + if (*p == 't') { + p++; + /* State: 'zihintnt' expecting [l] */ + if (*p == 'l') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZihintntl); + } else { + /* Unexpected char at 'zihintnt', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zihintn', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'p') { + p++; + /* State: 'zihintp' expecting [a] */ + if (*p == 'a') { + p++; + /* State: 'zihintpa' expecting [u] */ + if (*p == 'u') { + p++; + /* State: 'zihintpau' expecting [s] */ + if (*p == 's') { + p++; + /* State: 'zihintpaus' expecting [e] */ + if (*p == 'e') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZihintpause); + } else { + /* Unexpected char at 'zihintpaus', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zihintpau', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zihintpa', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zihintp', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zihint', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zihin', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zihi', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'p') { + p++; + /* State: 'zihp' expecting [m] */ + if (*p == 'm') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZihpm); + } else { + /* Unexpected char at 'zihp', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zih', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'm') { + p++; + /* State: 'zim' expecting [o] */ + if (*p == 'o') { + p++; + /* State: 'zimo' expecting [p] */ + if (*p == 'p') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZimop); + } else { + /* Unexpected char at 'zimo', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zim', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zi', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'k') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZk); + + /* State: 'zk' expecting [nrst] */ + if (*p == 'n') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZkn); + + /* State: 'zkn' expecting [deh] */ + if (*p == 'd') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZknd); + } else if (*p == 'e') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZkne); + } else if (*p == 'h') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZknh); + } else { + /* Unexpected char, but 'zkn' was valid */ + STOP_WITH_MATCH(RISCV_FeatureStdExtZkn); + } + } else if (*p == 'r') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZkr); + } else if (*p == 's') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZks); + + /* State: 'zks' expecting [eh] */ + if (*p == 'e') { + p++; + /* State: 'zkse' expecting [d] */ + if (*p == 'd') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZksed); + } else { + /* Unexpected char at 'zkse', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'h') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZksh); + } else { + /* Unexpected char, but 'zks' was valid */ + STOP_WITH_MATCH(RISCV_FeatureStdExtZks); + } + } else if (*p == 't') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZkt); + } else { + /* Unexpected char, but 'zk' was valid */ + STOP_WITH_MATCH(RISCV_FeatureStdExtZk); + } + } else if (*p == 'm') { + p++; + /* State: 'zm' expecting [m] */ + if (*p == 'm') { + p++; + /* State: 'zmm' expecting [u] */ + if (*p == 'u') { + p++; + /* State: 'zmmu' expecting [l] */ + if (*p == 'l') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZmmul); + } else { + /* Unexpected char at 'zmmu', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zmm', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zm', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 't') { + p++; + /* State: 'zt' expecting [s] */ + if (*p == 's') { + p++; + /* State: 'zts' expecting [o] */ + if (*p == 'o') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZtso); + } else { + /* Unexpected char at 'zts', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zt', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'v') { + p++; + /* State: 'zv' expecting [befkl] */ + if (*p == 'b') { + p++; + /* State: 'zvb' expecting [bc] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvbb); + } else if (*p == 'c') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvbc); + } else { + /* Unexpected char at 'zvb', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'e') { + p++; + /* State: 'zve' expecting [36] */ + if (*p == '3') { + p++; + /* State: 'zve3' expecting [2] */ + if (*p == '2') { + p++; + /* State: 'zve32' expecting [fx] */ + if (*p == 'f') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZve32f); + } else if (*p == 'x') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZve32x); + } else { + /* Unexpected char at 'zve32', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zve3', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '6') { + p++; + /* State: 'zve6' expecting [4] */ + if (*p == '4') { + p++; + /* State: 'zve64' expecting [dfx] */ + if (*p == 'd') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZve64d); + } else if (*p == 'f') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZve64f); + } else if (*p == 'x') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZve64x); + } else { + /* Unexpected char at 'zve64', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zve6', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zve', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'f') { + p++; + /* State: 'zvf' expecting [bh] */ + if (*p == 'b') { + p++; + /* State: 'zvfb' expecting [f] */ + if (*p == 'f') { + p++; + /* State: 'zvfbf' expecting [mw] */ + if (*p == 'm') { + p++; + /* State: 'zvfbfm' expecting [i] */ + if (*p == 'i') { + p++; + /* State: 'zvfbfmi' expecting [n] */ + if (*p == 'n') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvfbfmin); + } else { + /* Unexpected char at 'zvfbfmi', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvfbfm', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'w') { + p++; + /* State: 'zvfbfw' expecting [m] */ + if (*p == 'm') { + p++; + /* State: 'zvfbfwm' expecting [a] */ + if (*p == 'a') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvfbfwma); + } else { + /* Unexpected char at 'zvfbfwm', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvfbfw', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvfbf', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvfb', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'h') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvfh); + + /* State: 'zvfh' expecting [m] */ + if (*p == 'm') { + p++; + /* State: 'zvfhm' expecting [i] */ + if (*p == 'i') { + p++; + /* State: 'zvfhmi' expecting [n] */ + if (*p == 'n') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvfhmin); + } else { + /* Unexpected char at 'zvfhmi', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvfhm', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char, but 'zvfh' was valid */ + STOP_WITH_MATCH(RISCV_FeatureStdExtZvfh); + } + } else { + /* Unexpected char at 'zvf', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'k') { + p++; + /* State: 'zvk' expecting [bgnst] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvkb); + } else if (*p == 'g') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvkg); + } else if (*p == 'n') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvkn); + + /* State: 'zvkn' expecting [cegh] */ + if (*p == 'c') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvknc); + } else if (*p == 'e') { + p++; + /* State: 'zvkne' expecting [d] */ + if (*p == 'd') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvkned); + } else { + /* Unexpected char at 'zvkne', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'g') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvkng); + } else if (*p == 'h') { + p++; + /* State: 'zvknh' expecting [ab] */ + if (*p == 'a') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvknha); + } else if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvknhb); + } else { + /* Unexpected char at 'zvknh', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char, but 'zvkn' was valid */ + STOP_WITH_MATCH(RISCV_FeatureStdExtZvkn); + } + } else if (*p == 's') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvks); + + /* State: 'zvks' expecting [cegh] */ + if (*p == 'c') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvksc); + } else if (*p == 'e') { + p++; + /* State: 'zvkse' expecting [d] */ + if (*p == 'd') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvksed); + } else { + /* Unexpected char at 'zvkse', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'g') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvksg); + } else if (*p == 'h') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvksh); + } else { + /* Unexpected char, but 'zvks' was valid */ + STOP_WITH_MATCH(RISCV_FeatureStdExtZvks); + } + } else if (*p == 't') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvkt); + } else { + /* Unexpected char at 'zvk', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'l') { + p++; + /* State: 'zvl' expecting [1234568] */ + if (*p == '1') { + p++; + /* State: 'zvl1' expecting [026] */ + if (*p == '0') { + p++; + /* State: 'zvl10' expecting [2] */ + if (*p == '2') { + p++; + /* State: 'zvl102' expecting [4] */ + if (*p == '4') { + p++; + /* State: 'zvl1024' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl1024b); + } else { + /* Unexpected char at 'zvl1024', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl102', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl10', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '2') { + p++; + /* State: 'zvl12' expecting [8] */ + if (*p == '8') { + p++; + /* State: 'zvl128' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl128b); + } else { + /* Unexpected char at 'zvl128', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl12', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '6') { + p++; + /* State: 'zvl16' expecting [3] */ + if (*p == '3') { + p++; + /* State: 'zvl163' expecting [8] */ + if (*p == '8') { + p++; + /* State: 'zvl1638' expecting [4] */ + if (*p == '4') { + p++; + /* State: 'zvl16384' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl16384b); + } else { + /* Unexpected char at 'zvl16384', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl1638', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl163', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl16', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl1', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '2') { + p++; + /* State: 'zvl2' expecting [05] */ + if (*p == '0') { + p++; + /* State: 'zvl20' expecting [4] */ + if (*p == '4') { + p++; + /* State: 'zvl204' expecting [8] */ + if (*p == '8') { + p++; + /* State: 'zvl2048' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl2048b); + } else { + /* Unexpected char at 'zvl2048', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl204', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl20', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '5') { + p++; + /* State: 'zvl25' expecting [6] */ + if (*p == '6') { + p++; + /* State: 'zvl256' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl256b); + } else { + /* Unexpected char at 'zvl256', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl25', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl2', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '3') { + p++; + /* State: 'zvl3' expecting [2] */ + if (*p == '2') { + p++; + /* State: 'zvl32' expecting [7b] */ + if (*p == '7') { + p++; + /* State: 'zvl327' expecting [6] */ + if (*p == '6') { + p++; + /* State: 'zvl3276' expecting [8] */ + if (*p == '8') { + p++; + /* State: 'zvl32768' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl32768b); + } else { + /* Unexpected char at 'zvl32768', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl3276', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl327', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl32b); + } else { + /* Unexpected char at 'zvl32', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl3', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '4') { + p++; + /* State: 'zvl4' expecting [0] */ + if (*p == '0') { + p++; + /* State: 'zvl40' expecting [9] */ + if (*p == '9') { + p++; + /* State: 'zvl409' expecting [6] */ + if (*p == '6') { + p++; + /* State: 'zvl4096' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl4096b); + } else { + /* Unexpected char at 'zvl4096', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl409', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl40', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl4', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '5') { + p++; + /* State: 'zvl5' expecting [1] */ + if (*p == '1') { + p++; + /* State: 'zvl51' expecting [2] */ + if (*p == '2') { + p++; + /* State: 'zvl512' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl512b); + } else { + /* Unexpected char at 'zvl512', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl51', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl5', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '6') { + p++; + /* State: 'zvl6' expecting [45] */ + if (*p == '4') { + p++; + /* State: 'zvl64' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl64b); + } else { + /* Unexpected char at 'zvl64', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '5') { + p++; + /* State: 'zvl65' expecting [5] */ + if (*p == '5') { + p++; + /* State: 'zvl655' expecting [3] */ + if (*p == '3') { + p++; + /* State: 'zvl6553' expecting [6] */ + if (*p == '6') { + p++; + /* State: 'zvl65536' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl65536b); + } else { + /* Unexpected char at 'zvl65536', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl6553', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl655', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl65', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl6', no match */ + STOP_WITHOUT_MATCH(); + } + } else if (*p == '8') { + p++; + /* State: 'zvl8' expecting [1] */ + if (*p == '1') { + p++; + /* State: 'zvl81' expecting [9] */ + if (*p == '9') { + p++; + /* State: 'zvl819' expecting [2] */ + if (*p == '2') { + p++; + /* State: 'zvl8192' expecting [b] */ + if (*p == 'b') { + p++; + STOP_WITH_MATCH(RISCV_FeatureStdExtZvl8192b); + } else { + /* Unexpected char at 'zvl8192', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl819', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl81', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl8', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zvl', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'zv', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at 'z', no match */ + STOP_WITHOUT_MATCH(); + } + } else { + /* Unexpected char at '', no match */ + STOP_WITHOUT_MATCH(); + } + + /* Should not reach here */ + STOP_WITHOUT_MATCH(); +} + +/* Cleanup macros */ +#undef STOP_WITH_MATCH +#undef STOP_WITHOUT_MATCH + +/* Example usage: + * + * ut64 features = 0; + * riscv_extension_parse_result_t result; + * size_t idx = 0; + * const char *arch = "i2p1_m2p0_zicsr"; + * + * // Parse "i" from "i2p1_m2p0_zicsr" + * result = try_consume_riscv_ext_from(arch, &idx, &features); + * // idx is now 1, result is RISCV_EXT_PARSE_STOPPED_AT_NUMBER + * + * // Skip version "2p1_" by setting idx = 5 + * idx = 5; // now at 'm' + * result = try_consume_riscv_ext_from(arch, &idx, &features); + * // idx is now 6, result is RISCV_EXT_PARSE_STOPPED_AT_NUMBER + * + * // Skip version "2p0_" by setting idx = 10 + * idx = 10; // now at 'z' + * result = try_consume_riscv_ext_from(arch, &idx, &features); + * // idx is now 15, result is RISCV_EXT_PARSE_END_OF_STRING + */ diff --git a/librz/arch/p/asm/asm_riscv_cs.c b/librz/arch/p/asm/asm_riscv_cs.c index a3b16f72ef6..8eb9daf2748 100644 --- a/librz/arch/p/asm/asm_riscv_cs.c +++ b/librz/arch/p/asm/asm_riscv_cs.c @@ -3,6 +3,7 @@ #include #include +#include #include "cs_helper.h" CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(riscv_asm); @@ -13,6 +14,7 @@ static int riscv_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { int ret = -1; cs_insn *insn; cs_mode mode = (a->bits == 64) ? CS_MODE_RISCV64 : CS_MODE_RISCV32; + mode |= mode_from_arch_string(a->cpu); op->size = 4; if (ctx->omode != mode) { cs_close(&ctx->handle); @@ -49,11 +51,11 @@ static int riscv_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { } RzAsmPlugin rz_asm_plugin_riscv_cs = { - .name = "riscv.cs", + .name = "riscv", .desc = "RISC-V Capstone-based disassembler", .license = "BSD", .arch = "riscv", - .cpus = "", + .cpus = NULL, .bits = 32 | 64, .endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG, .init = riscv_asm_init, diff --git a/librz/bin/format/elf/elf_info.c b/librz/bin/format/elf/elf_info.c index 72f21ec00b5..f3134fe6b90 100644 --- a/librz/bin/format/elf/elf_info.c +++ b/librz/bin/format/elf/elf_info.c @@ -6,6 +6,13 @@ #include "elf.h" #include "elf/glibc_elf.h" +#include "rz_bin.h" +#include "rz_bp.h" +#include "rz_util/rz_buf.h" +#include "rz_util/rz_log.h" +#include "rz_util/rz_str.h" +#include "rz_util/rz_strbuf.h" +#include #define VERSYM_VERSION 0x7fff @@ -733,7 +740,131 @@ static inline bool is_elf_class32(ELFOBJ *bin) { return bin->ehdr.e_ident[EI_CLASS] == ELFCLASS32; } -static int get_bits_mips(ELFOBJ *bin) { +static RzBuffer *get_riscv_attributes_section(ELFOBJ *bin) { + RzBinElfSection *section = Elf_(rz_bin_elf_get_section_with_name)(bin, ".riscv.attributes"); + if (!section || section->type != SHT_RISCV_ATTRIBUTES /* shouldn't really be possible */) { + return NULL; + } + return rz_buf_new_slice(bin->b, section->offset, section->size); +} + +typedef enum { + RISCV_ATTR_NONE = 0, + RISCV_ATTR_TRUNCATED_NT_STRING = 1, + RISCV_ATTR_NT_STRING = 2, + RISCV_ATTR_ULEB128 = 3, + RISCV_ATTR_TRUNCATED_ULEB128 = 4, +} riscv_attr_type; + +static riscv_attr_type get_riscv_attribute_from_section(RzBuffer *sec, ut64 attr_tag, int result_maxlen, ut8 *result, int *result_len) { + // format: + /* + * */ + /* = + * | + */ + ut64 curr = 0; + + // format byte + ut8 format; + if (!sec || !rz_buf_read8_offset(sec, &curr, &format) || format != 'A') { + RZ_LOG_ERROR("Can't read the format byte of the RISCV attrbiute section or found a different format (expected 'A' at section start)\n"); + return RISCV_ATTR_NONE; + } + + // subsection length + ut32 subsec_len; + if (!rz_buf_read_ble32_offset(sec, &curr, &subsec_len, /* big endian? */ false)) { + RZ_LOG_ERROR("Can't read the subsection length of the RISCV attribute section\n"); + return RISCV_ATTR_NONE; + } + + // skip vendor name + ut8 byte = 1; + while (byte != '\0') { + if (!rz_buf_read8_offset(sec, &curr, &byte)) { + RZ_LOG_ERROR("Can't read vendor name in RISCV attribute section\n"); + return RISCV_ATTR_NONE; + } + } + + // now parse the tag-value array + while (curr < rz_buf_size(sec)) { + ut64 tag; + ut32 num_bytes_read = rz_buf_uleb128_at(sec, curr, &tag); + curr += num_bytes_read; + + if (num_bytes_read > 8) { + RZ_LOG_WARN("Can't interpret tag value between offsets %llu-%llu: " + "tag is too large at %d bytes, parser can only represent 64-bit tags (skipped)\n", + curr - num_bytes_read, curr, num_bytes_read); + continue; + } + if (tag != attr_tag) { + continue; + } + + // RISCV ABI spec says that there are only 2 types of values associated with tags + // 1- Even tags: ULEB128 values (self-delimiting, no header length necessary) + // 2- Odd tags: Null-terminated strings (also self-delimiting) + // Like ARM but even simpler, no special cases for tags below 32 + bool tag_is_odd = tag & 0x1; + + int result_curr = 0; + // value is a null-terminated string + if (tag_is_odd) { + int string_starts_at = curr; + while (curr < rz_buf_size(sec) && result_curr < result_maxlen) { + bool succeeded = rz_buf_read8_offset(sec, &curr, &result[result_curr++]); + if (!succeeded) { + RZ_LOG_ERROR("Can't read the null-terminated string for tag %lld, starting at offset %d\n", tag, string_starts_at); + break; + } + // done + if (result[result_curr - 1] == '\0') { + break; + } + } + + bool result_overflow = false; + // have we filled the buffer ? + if (result_curr == result_maxlen) { + result_overflow = result[result_maxlen - 1] != '\0'; + // must force the last byte to null, in case the original string was too long + result[result_maxlen - 1] = '\0'; + } + *result_len = result_curr; + return result_overflow ? RISCV_ATTR_TRUNCATED_NT_STRING : RISCV_ATTR_NT_STRING; + } else { // value is a self-delimiting ULEB128 integer + int uleb_starts_at = curr; + while (curr < rz_buf_size(sec) && result_curr < result_maxlen) { + bool succeeded = rz_buf_read8_offset(sec, &curr, &result[result_curr++]); + if (!succeeded) { + RZ_LOG_ERROR("Can't read the ULEB128 value for tag %lld, starting at offset %d\n", tag, uleb_starts_at); + break; + } + // last byte in the variable encoding, most-significant bit not set + if (!(result[result_curr - 1] & 0x80)) { + break; + } + } + + bool result_overflow = false; + // have we filled the buffer ? + if (result_curr == result_maxlen) { + result_overflow = result[result_maxlen - 1] & 0x80; + // must force the last byte to a terminal byte, in case the original number was too long + result[result_maxlen - 1] = result[result_maxlen - 1] & 0x7F; + } + *result_len = result_curr; + return result_overflow ? RISCV_ATTR_TRUNCATED_ULEB128 : RISCV_ATTR_ULEB128; + } + } + return RISCV_ATTR_NONE; +} + +static int +get_bits_mips(ELFOBJ *bin) { if (is_elf_class64(bin)) { return 64; } @@ -780,6 +911,10 @@ static bool arch_is_parisc(ELFOBJ *bin) { return bin->ehdr.e_machine == EM_PARISC; } +static bool arch_is_riscv(ELFOBJ *bin) { + return bin->ehdr.e_machine == EM_RISCV; +} + static char *read_elf_intrp(ELFOBJ *bin, ut64 addr, size_t size) { char *str = malloc(size + 1); if (!str) { @@ -1945,7 +2080,7 @@ RZ_OWN char *Elf_(rz_bin_elf_get_arch)(RZ_NONNULL ELFOBJ *bin) { * \param elf type * \return allocated string * - * Only work on mips right now. Use the elf header to deduce the cpu + * Use the elf header to deduce the cpu */ RZ_OWN char *Elf_(rz_bin_elf_get_cpu)(RZ_NONNULL ELFOBJ *bin) { rz_return_val_if_fail(bin, NULL); @@ -1966,6 +2101,15 @@ RZ_OWN char *Elf_(rz_bin_elf_get_cpu)(RZ_NONNULL ELFOBJ *bin) { return get_cpu_arm(bin); } else if (arch_is_h8xx(bin)) { return get_cpu_h8xx(bin); + } else if (arch_is_riscv(bin)) { + ut8 archstr[256]; + int archstr_len; + riscv_attr_type typ = get_riscv_attribute_from_section(get_riscv_attributes_section(bin), T_RISCV_arch, 256, archstr, &archstr_len); + if (typ == RISCV_ATTR_NT_STRING) { + return rz_str_dup((const char *)archstr); + } + // some hardcoded fallback, the mafd + vector + return strdup("rv64i2p0_c2p0_m2p0_a2p0_f2p0_d2p0_v2p0"); } return NULL; } diff --git a/librz/bin/format/elf/elf_relocs_patching.c b/librz/bin/format/elf/elf_relocs_patching.c index bbcb7769925..cf63c410fa2 100644 --- a/librz/bin/format/elf/elf_relocs_patching.c +++ b/librz/bin/format/elf/elf_relocs_patching.c @@ -4,6 +4,11 @@ // SPDX-License-Identifier: LGPL-3.0-only #include "elf.h" +#include "elf/glibc_elf.h" +#include "rz_types.h" +#include "rz_types_base.h" +#include "rz_util/rz_buf.h" +#include "rz_util/rz_log.h" typedef struct reloc_formular_symbols_t { ut64 A; // Appendend @@ -177,6 +182,20 @@ static void patch_val_over_mask_64(RZ_INOUT RzBuffer *buf_patched, bool big_endi rz_buf_write_at(buf_patched, addr, buf, 8); } +/** + * \brief Does the same as patch_val_over_mask_32 but for 16bit values. + */ +static void patch_val_over_mask_16(RZ_INOUT RzBuffer *buf_patched, bool big_endian, const ut64 addr, const ut16 mask, const ut16 val) { + rz_return_if_fail(buf_patched); + ut8 buf[2] = { 0 }; + + rz_buf_read_at(buf_patched, addr, buf, 2); + ut16 opcode = rz_read_ble16(buf, big_endian) | rz_bits_spread(mask, val); + + rz_write_ble16(buf, opcode, big_endian); + rz_buf_write_at(buf_patched, addr, buf, 2); +} + #define UNHANDL(NAME) \ RZ_LOG_WARN("Unhandled " NAME " reloc\n"); \ return @@ -2258,6 +2277,368 @@ static void patch_reloc_avr(RZ_INOUT RzBuffer *buf_patched, const ut64 patch_add break; } } +// U-Type: 32-bit instructions that store a 20-bit immediate in their upper 20 bit +static const ut32 RISCV_U_TYPE_IMM_MASK = ((1ULL << 20) - 1) << 12; +// I-Type: 32-bit instructions that store a 12-bit immediate in their upper 12 bit +static const ut32 RISCV_I_TYPE_IMM_MASK = ((1ULL << 12) - 1) << 20; +// S-Type: 32-bit instructions that store a 12-bit immediate scattered over 2 places but still in relative order +static const ut32 RISCV_S_TYPE_IMM_MASK = ((0x7F << 25) | (0x1F << 7)); +// B-TYPE: 32-bit instructions that store an 11-bit immediate scattered all over and out of order +static const ut32 RISCV_B_TYPE_IMM_MASKS[] = { + 1ULL << 31, // bit 31: imm[12] + 0x3fULL << 25, // bits 30-25: imm[10:5] + 0xfULL << 8, // bits 11-8: imm[4:1] + 1ULL << 7 // bit 7: imm[11] +}; +// J-TYPE: 32-bit instructions (JAL) that store a 20-bit immediate scattered all over and out of order +static const ut32 RISCV_J_TYPE_IMM_MASKS[] = { + 1ULL << 31, // bit 31: imm[20] + 0x3ffULL << 21, // bits 30-21: imm[10:1] + 1ULL << 20, // bit 20: imm[11] + 0xffULL << 12 // bits 19-12: imm[19:12] +}; +// CB-Type: 16-bit instructions that store an 8-bit immediate scattered all over and out of order +// the immediate is effectively 9 bit with bit 0 implied and always zero +static const ut16 RISCV_CB_TYPE_IMM_MASKS[] = { + (1 << 12), // bit 12: imm[8] + (3 << 10), // bits 11-10: imm[4:3] + (3 << 5), // bits 6-5: imm[7:6] + (3 << 3), // bits 4-3: imm[2:1] + (1 << 2) // bit 2: imm[5] +}; +// CJ-Type: 16-bit instructions that store an 11-bit immediate scattered all over and out of order +// the immediate is effectively 12 bit with bit 0 implied and always zero +static const ut16 RISCV_CJ_TYPE_IMM_MASKS[] = { + (1 << 12), // bit 12: imm[11] + (1 << 11), // bit 11: imm[4] + (3 << 9), // bits 10:9: imm[9:8] + (1 << 8), // bit 8: imm[10] + (1 << 7), // bit 7: imm[6] + (1 << 6), // bit 6: imm[7] + (7 << 3), // bits 5:3: imm[3:1] + (1 << 2) // bit 2: imm[5] +}; +// CI-type: 16-bit instructions that store a 6-bit immediate with the 6th bit scattered from the rest but still in relative order +static const ut16 RISCV_CI_TYPE_IMM_MASK = (1 << 12) | (0x1f << 2); + +#define RISCV_HI20(i) ((i) + 0x800) >> 12 +#define RISCV_LO12(i) ((i) & 0xfff) +#define RISCV_CHECK_NARROWING_32(i, w) \ + if (w == 32) { \ + i = ((ut32)i); \ + } +static void patch_reloc_riscv(RZ_INOUT RzBuffer *buf_patched, const ut64 patch_addr, const int rel_type, bool big_endian, const RelocFormularSymbols *fs, const int bits) { + rz_return_if_fail(buf_patched && fs); + + ut64 val = 0; + // narrow address values for 32-bit binaries + ut64 S = (bits == 32) ? ((ut32)fs->S) : fs->S; + ut64 A = (bits == 32) ? ((ut32)fs->A) : fs->A; + ut64 B = (bits == 32) ? ((ut32)fs->B) : fs->B; + ut64 P = (bits == 32) ? ((ut32)fs->P) : fs->P; + + switch (rel_type) { + case R_RISCV_NONE: + return; + + case R_RISCV_32: + val = S + A; + rz_buf_write_ble32_at(buf_patched, patch_addr, val, big_endian); + break; + + case R_RISCV_64: + val = S + A; + rz_buf_write_ble64_at(buf_patched, patch_addr, val, big_endian); + break; + + case R_RISCV_RELATIVE: + val = A + B; + switch (bits) { + case 32: + rz_buf_write_ble32_at(buf_patched, patch_addr, val, big_endian); + break; + case 64: + rz_buf_write_ble64_at(buf_patched, patch_addr, val, big_endian); + break; + default: + RZ_LOG_WARN("Unsupported number of bits for R_RISCV_RELATIVE: %d, only 32 bits and 64 bits are supported", bits); + return; + } + break; + + case R_RISCV_BRANCH: { + val = S + A - P; + ut64 imm12 = ((val >> 12) & 0x1); // inst[31] = imm[12] + ut64 imm10_5 = ((val >> 5) & 0x3f); // inst[30:25] = imm[10:5] + ut64 imm4_1 = ((val >> 1) & 0xf); // inst[11:8] = imm[4:1] + ut64 imm11 = ((val >> 11) & 0x1); // inst[7] = imm[11] + ut64 imms[4] = { imm12, imm10_5, imm4_1, imm11 }; + for (int i = 0; i < sizeof(RISCV_B_TYPE_IMM_MASKS) / sizeof(RISCV_B_TYPE_IMM_MASKS[0]); i++) { + patch_val_over_mask_32(buf_patched, big_endian, patch_addr, RISCV_B_TYPE_IMM_MASKS[i], imms[i]); + } + break; + } + + case R_RISCV_JAL: { + val = S + A - P; + RISCV_CHECK_NARROWING_32(val, bits); + ut64 imm20 = ((val >> 20) & 0x1); // inst[31] = imm[20] + ut64 imm10_1 = ((val >> 1) & 0x3ff); // inst[30:21] = imm[10:1] + ut64 imm11 = ((val >> 11) & 0x1); // inst[20] = imm[11] + ut64 imm19_12 = ((val >> 12) & 0xff); // inst[19:12] = imm[19:12] + ut64 imms[4] = { imm20, imm10_1, imm11, imm19_12 }; + for (int i = 0; i < sizeof(RISCV_J_TYPE_IMM_MASKS) / sizeof(RISCV_J_TYPE_IMM_MASKS[0]); i++) { + patch_val_over_mask_32(buf_patched, big_endian, patch_addr, RISCV_J_TYPE_IMM_MASKS[i], imms[i]); + } + break; + } + + // both handled by the same formula + // TODO: CALL_PLT is more complex if the symbol is outside the same object file + case R_RISCV_CALL: + case R_RISCV_CALL_PLT: { + ut64 result = S + A - P; + + ut32 hi20 = RISCV_HI20(result); + ut32 lo12 = RISCV_LO12(result); + + // the AUIPC part of the call sequence takes the upper 20 bits of the address + patch_val_over_mask_32(buf_patched, big_endian, patch_addr, RISCV_U_TYPE_IMM_MASK, hi20); + // the JALR part of the call sequence takes the lower 12 bits of the address; + patch_val_over_mask_32(buf_patched, big_endian, patch_addr + 4, RISCV_I_TYPE_IMM_MASK, lo12); + break; + } + + case R_RISCV_JUMP_SLOT: + switch (bits) { + case 32: + rz_buf_write_ble32_at(buf_patched, patch_addr, S, big_endian); + break; + case 64: + rz_buf_write_ble64_at(buf_patched, patch_addr, S, big_endian); + break; + default: + RZ_LOG_WARN("Unsupported number of bits for R_RISCV_JUMP_SLOT: %d, only 32 bits and 64 bits are supported", bits); + break; + } + break; + + case R_RISCV_32_PCREL: + val = S + A - P; + rz_buf_write_ble32_at(buf_patched, patch_addr, val, big_endian); + break; + + case R_RISCV_GOT_HI20: { + val = fs->G + fs->GOT + A - P; + ut32 hi20 = RISCV_HI20(val); + patch_val_over_mask_32(buf_patched, big_endian, patch_addr, RISCV_U_TYPE_IMM_MASK, hi20); + break; + } + case R_RISCV_PCREL_HI20: { + val = S + A - P; + ut32 hi20 = RISCV_HI20(val); + patch_val_over_mask_32(buf_patched, big_endian, patch_addr, RISCV_U_TYPE_IMM_MASK, hi20); + break; + } + + case R_RISCV_PCREL_LO12_I: + case R_RISCV_PCREL_LO12_S: { + val = S + A - P; + ut32 lo12 = RISCV_LO12(val); + patch_val_over_mask_32(buf_patched, big_endian, patch_addr, (rel_type == R_RISCV_PCREL_LO12_I) ? RISCV_I_TYPE_IMM_MASK : RISCV_S_TYPE_IMM_MASK, lo12); + break; + } + + case R_RISCV_HI20: { + val = S + A; + patch_val_over_mask_32(buf_patched, big_endian, patch_addr, RISCV_U_TYPE_IMM_MASK, RISCV_HI20(val)); + break; + } + + case R_RISCV_LO12_I: + case R_RISCV_LO12_S: { + val = S + A; + patch_val_over_mask_32(buf_patched, big_endian, patch_addr, (rel_type == R_RISCV_LO12_I) ? RISCV_I_TYPE_IMM_MASK : RISCV_S_TYPE_IMM_MASK, RISCV_LO12(val)); + break; + } + + case R_RISCV_RVC_BRANCH: { + val = S + A - P; + uint16_t imms[] = { + ((val >> 8) & 0x1), // imm[8] + ((val >> 3) & 0x3), // imm[4:3] + ((val >> 6) & 0x3), // imm[7:6] + ((val >> 1) & 0x3), // imm[2:1] + ((val >> 5) & 0x1) // imm[5] + }; + for (int i = 0; i < sizeof(RISCV_CB_TYPE_IMM_MASKS) / sizeof(RISCV_CB_TYPE_IMM_MASKS[0]); i++) { + patch_val_over_mask_16(buf_patched, big_endian, patch_addr, RISCV_CB_TYPE_IMM_MASKS[i], imms[i]); + } + break; + } + + case R_RISCV_RVC_JUMP: { + val = S + A - P; + uint16_t imms[] = { + ((val >> 11) & 0x1), // imm[11] + ((val >> 4) & 0x1), // imm[4] + ((val >> 8) & 0x3), // imm[9:8] + ((val >> 10) & 0x1), // imm[10] + ((val >> 6) & 0x1), // imm[6] + ((val >> 7) & 0x1), // imm[7] + ((val >> 1) & 0x7), // imm[3:1] + ((val >> 5) & 0x1), // imm[5] + }; + for (int i = 0; i < sizeof(RISCV_CJ_TYPE_IMM_MASKS) / sizeof(RISCV_CJ_TYPE_IMM_MASKS[0]); i++) { + patch_val_over_mask_16(buf_patched, big_endian, patch_addr, RISCV_CJ_TYPE_IMM_MASKS[i], imms[i]); + } + break; + } + + case R_RISCV_RVC_LUI: + val = S + A; + patch_val_over_mask_16(buf_patched, big_endian, patch_addr, RISCV_CI_TYPE_IMM_MASK, val >> 12); + break; + + case R_RISCV_ADD8: { + ut8 old_val = 0; + rz_buf_read_ble8_at(buf_patched, patch_addr, &old_val, big_endian); + ut64 result = ((ut64)old_val) + S + A; + unsigned long long addr = patch_addr; + rz_buf_write_ble8_offset(buf_patched, &addr, (ut8)result, big_endian); + break; + } + + case R_RISCV_ADD16: { + ut16 old_val = 0; + rz_buf_read_ble16_at(buf_patched, patch_addr, &old_val, big_endian); + ut64 result = ((ut64)old_val) + S + A; + rz_buf_write_ble16_at(buf_patched, patch_addr, (ut16)result, big_endian); + break; + } + + case R_RISCV_ADD32: { + ut32 old_val = 0; + rz_buf_read_ble32_at(buf_patched, patch_addr, &old_val, big_endian); + ut64 result = ((ut64)old_val) + S + A; + rz_buf_write_ble32_at(buf_patched, patch_addr, (ut32)result, big_endian); + break; + } + + case R_RISCV_ADD64: { + ut64 old_val = 0; + rz_buf_read_ble64_at(buf_patched, patch_addr, &old_val, big_endian); + ut64 result = old_val + S + A; + rz_buf_write_ble64_at(buf_patched, patch_addr, result, big_endian); + break; + } + + case R_RISCV_SUB8: { + ut8 old_val = 0; + rz_buf_read_ble8_at(buf_patched, patch_addr, &old_val, big_endian); + ut64 result = ((ut64)old_val) - S - A; + unsigned long long addr = patch_addr; + rz_buf_write_ble8_offset(buf_patched, &addr, (ut8)result, big_endian); + break; + } + + case R_RISCV_SUB16: { + ut16 old_val = 0; + rz_buf_read_ble16_at(buf_patched, patch_addr, &old_val, big_endian); + ut64 result = ((ut64)old_val) - S - A; + rz_buf_write_ble16_at(buf_patched, patch_addr, (ut16)result, big_endian); + break; + } + + case R_RISCV_SUB32: { + ut32 old_val = 0; + rz_buf_read_ble32_at(buf_patched, patch_addr, &old_val, big_endian); + ut64 result = ((ut64)old_val) - S - A; + rz_buf_write_ble32_at(buf_patched, patch_addr, (ut32)result, big_endian); + break; + } + + case R_RISCV_SUB64: { + ut64 old_val = 0; + rz_buf_read_ble64_at(buf_patched, patch_addr, &old_val, big_endian); + ut64 result = ((ut64)old_val) - S - A; + rz_buf_write_ble64_at(buf_patched, patch_addr, result, big_endian); + break; + } + + case R_RISCV_SET8: { + val = S + A; + unsigned long long addr = patch_addr; + rz_buf_write_ble8_offset(buf_patched, &addr, (ut8)val, big_endian); + break; + } + case R_RISCV_SET16: { + val = S + A; + rz_buf_write_ble16_at(buf_patched, patch_addr, (ut16)val, big_endian); + break; + } + case R_RISCV_SET32: { + val = S + A; + rz_buf_write_ble32_at(buf_patched, patch_addr, (ut32)val, big_endian); + break; + } + + case R_RISCV_SET6: + case R_RISCV_SUB6: { + ut8 old_val = 0; + rz_buf_read_ble8_at(buf_patched, patch_addr, &old_val, big_endian); + val = S + A; + ut8 result = (rel_type == R_RISCV_SET6) ? val : ((old_val & 0x3F) - val); + rz_buf_write_ble8_at(buf_patched, patch_addr, (old_val & 0xC0) | (result & 0x3F), big_endian); + break; + } + + /*************************************************** UNIMPLEMENTED ***************************************************/ + case R_RISCV_TLS_DTPMOD32: + UNHANDL_DEF("RISCV", rel_type); + RZ_LOG_WARN("RISCV Relocations: TLS_DTPMOD32 UNIMPLEMENTED"); + break; + + case R_RISCV_TLS_DTPMOD64: + UNHANDL_DEF("RISCV", rel_type); + RZ_LOG_WARN("RISCV Relocations: TLS_DTPMOD64 UNIMPLEMENTED"); + break; + + case R_RISCV_TLS_TPREL32: + UNHANDL_DEF("RISCV", rel_type); + RZ_LOG_WARN("RISCV Relocations: TLS_TPREL32 UNIMPLEMENTED"); + break; + + case R_RISCV_TLS_TPREL64: + UNHANDL_DEF("RISCV", rel_type); + RZ_LOG_WARN("RISCV Relocations: TLS_TPREL64 UNIMPLEMENTED"); + break; + + case R_RISCV_TLS_GD_HI20: + UNHANDL_DEF("RISCV", rel_type); + RZ_LOG_WARN("RISCV Relocations: TLS_GD_HI20 UNIMPLEMENTED"); + break; + + case R_RISCV_TLS_GOT_HI20: + UNHANDL_DEF("RISCV", rel_type); + RZ_LOG_WARN("RISCV Relocations: TLS_GOT_HI20 UNIMPLEMENTED"); + break; + + case R_RISCV_TLS_DTPREL32: + UNHANDL_DEF("RISCV", rel_type); + RZ_LOG_WARN("RISCV Relocations: TLS_DTPREL32 UNIMPLEMENTED"); + break; + + case R_RISCV_TLS_DTPREL64: + UNHANDL_DEF("RISCV", rel_type); + RZ_LOG_WARN("RISCV Relocations: TLS_DTPREL64 UNIMPLEMENTED"); + break; + + default: + UNHANDL_DEF("RISC-V", rel_type); + return; + } +} #undef UNHANDL #undef UNHANDL_DEF @@ -2334,6 +2715,10 @@ void Elf_(rz_bin_elf_patch_relocation)(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RzBinE case EM_AVR: patch_reloc_avr(bin->buf_patched, patch_addr, rel->type, big_endian, &formular_sym); break; + case EM_RISCV: + patch_reloc_riscv(bin->buf_patched, patch_addr, rel->type, big_endian, &formular_sym, bin->bits); + break; + case EM_M32: ARCH_MISSING("EM_M32"); case EM_68K: ARCH_MISSING("EM_68K"); case EM_88K: ARCH_MISSING("EM_88K"); @@ -2546,5 +2931,4 @@ void Elf_(rz_bin_elf_patch_relocation)(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RzBinE return; } } - #undef ARCH_MISSING diff --git a/librz/bin/format/elf/glibc_elf.h b/librz/bin/format/elf/glibc_elf.h index 876f812683c..c459192ea43 100644 --- a/librz/bin/format/elf/glibc_elf.h +++ b/librz/bin/format/elf/glibc_elf.h @@ -4125,6 +4125,17 @@ ARM32 relocations: #define R_RISCV_NUM 59 +/* RISCV Tags */ +#define T_RISCV_stack_align 4 +#define T_RISCV_arch 5 +#define T_RISCV_unaligned_access 6 +#define T_RISCV_priv_spec 8 +#define T_RISCV_priv_spec_minor 10 +#define T_RISCV_priv_spec_revision 12 + +/* RISCV-specific section types */ +#define SHT_RISCV_ATTRIBUTES 0x70000003 + /* BPF specific declarations. */ #define R_BPF_NONE 0 /* No reloc */ diff --git a/librz/bin/p/bin_elf.inc b/librz/bin/p/bin_elf.inc index 3619d0c7231..6c8fa0fff72 100644 --- a/librz/bin/p/bin_elf.inc +++ b/librz/bin/p/bin_elf.inc @@ -15,6 +15,7 @@ #include "../i/private.h" #include "elf/elf.h" #include "elf/glibc_elf.h" +#include "rz_vector.h" #include #include diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index 638bd875d50..bf5bd77a3f2 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -338,6 +338,9 @@ typedef enum { RZ_ANALYSIS_OP_TYPE_CPL = 45, /* complement */ RZ_ANALYSIS_OP_TYPE_CRYPTO = 46, RZ_ANALYSIS_OP_TYPE_SYNC = 47, + RZ_ANALYSIS_OP_TYPE_BCNT = 48, /* bit-counting operations like pop count */ + RZ_ANALYSIS_OP_TYPE_REV = 49, /* byte-reversal and bit-reversal operations */ + RZ_ANALYSIS_OP_TYPE_REDUCE = 50, /* instructions that reduce a sequence, like string operations or vector sum */ // RZ_ANALYSIS_OP_TYPE_DEBUG = 43, // monitor/trace/breakpoint #if 0 RZ_ANALYSIS_OP_TYPE_PRIV = 40, /* privileged instruction */ diff --git a/meson_options.txt b/meson_options.txt index a3969fd67b7..5698faaa6e0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -21,7 +21,7 @@ option('rizin_bindings', type: 'string', value: '', description: 'Path where riz option('checks_level', type: 'integer', value: 2, description: 'Value between 0 and 3 to enable different level of assert (see RZ_CHECKS_LEVEL)') option('use_sys_capstone', type: 'feature', value: 'disabled') -option('use_capstone_version', type: 'combo', choices: ['v4', 'v5', 'v6', 'next'], value: 'next', description: 'Specify which version of capstone to use') +option('use_capstone_version', type: 'combo', choices: ['v4', 'v5', 'v6', 'next', 'capstone-riscv-updated'], value: 'next', description: 'Specify which version of capstone to use') option('use_sys_magic', type: 'feature', value: 'disabled') option('use_sys_zydis', type: 'feature', value: 'disabled') option('use_sys_libzip', type: 'feature', value: 'disabled') diff --git a/subprojects/capstone-capstone-riscv-updated.wrap b/subprojects/capstone-capstone-riscv-updated.wrap new file mode 100644 index 00000000000..a4f2a1973f4 --- /dev/null +++ b/subprojects/capstone-capstone-riscv-updated.wrap @@ -0,0 +1,6 @@ +[wrap-git] +url = https://github.com/moste00/capstone.git +revision = refactor_riscv_autosync +directory = capstone-riscv-updated +patch_directory = capstone-riscv-updated +depth = 1 diff --git a/subprojects/capstone-next.wrap b/subprojects/capstone-next.wrap index be49428420b..031898b341a 100644 --- a/subprojects/capstone-next.wrap +++ b/subprojects/capstone-next.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://github.com/capstone-engine/capstone.git -revision = 9539045d675a30eed43869325f7f51cfc26de0b7 +revision = b3bd2f55d862e1d759782007ff81274295561e73 directory = capstone-next patch_directory = capstone-next depth = 1 diff --git a/subprojects/packagefiles/capstone-next/meson.build b/subprojects/packagefiles/capstone-next/meson.build index a6f0fddc93c..47ce09660c6 100644 --- a/subprojects/packagefiles/capstone-next/meson.build +++ b/subprojects/packagefiles/capstone-next/meson.build @@ -55,6 +55,12 @@ cs_files = [ 'arch/PowerPC/PPCInstPrinter.c', 'arch/PowerPC/PPCMapping.c', 'arch/PowerPC/PPCModule.c', + 'arch/RISCV/RISCVDisassembler.c', + 'arch/RISCV/RISCVDisassemblerExtension.c', + 'arch/RISCV/RISCVInstPrinter.c', + 'arch/RISCV/RISCVBaseInfo.c', + 'arch/RISCV/RISCVMapping.c', + 'arch/RISCV/RISCVModule.c', 'arch/Sparc/SparcDisassembler.c', 'arch/Sparc/SparcDisassemblerExtension.c', 'arch/Sparc/SparcInstPrinter.c', @@ -123,6 +129,7 @@ libcapstone_c_args = [ '-DCAPSTONE_HAS_X86', '-DCAPSTONE_HAS_XCORE', '-DCAPSTONE_HAS_XTENSA', + '-DCAPSTONE_HAS_RISCV', ] if meson.get_compiler('c').has_argument('-Wmaybe-uninitialized') diff --git a/subprojects/packagefiles/capstone-riscv-updated/meson.build b/subprojects/packagefiles/capstone-riscv-updated/meson.build new file mode 100644 index 00000000000..8f2cf2e02c6 --- /dev/null +++ b/subprojects/packagefiles/capstone-riscv-updated/meson.build @@ -0,0 +1,148 @@ +project('capstone', 'c', + version: 'capstone-riscv-updated', + meson_version: '>=0.55.0', +) + +cc = meson.get_compiler('c') + +if cc.has_argument('--std=gnu99') + add_project_arguments('--std=gnu99', language: ['c']) +elif cc.has_argument('--std=c99') + add_project_arguments('--std=c99', language: ['c']) +endif + +cs_files = [ + 'arch/Alpha/AlphaDisassembler.c', + 'arch/Alpha/AlphaInstPrinter.c', + 'arch/Alpha/AlphaMapping.c', + 'arch/Alpha/AlphaModule.c', + 'arch/ARC/ARCDisassembler.c', + 'arch/ARC/ARCInstPrinter.c', + 'arch/ARC/ARCMapping.c', + 'arch/ARC/ARCModule.c', + 'arch/AArch64/AArch64BaseInfo.c', + 'arch/AArch64/AArch64Disassembler.c', + 'arch/AArch64/AArch64DisassemblerExtension.c', + 'arch/AArch64/AArch64InstPrinter.c', + 'arch/AArch64/AArch64Mapping.c', + 'arch/AArch64/AArch64Module.c', + 'arch/ARM/ARMBaseInfo.c', + 'arch/ARM/ARMDisassembler.c', + 'arch/ARM/ARMDisassemblerExtension.c', + 'arch/ARM/ARMInstPrinter.c', + 'arch/ARM/ARMMapping.c', + 'arch/ARM/ARMModule.c', + 'arch/HPPA/HPPADisassembler.c', + 'arch/HPPA/HPPAInstPrinter.c', + 'arch/HPPA/HPPAMapping.c', + 'arch/HPPA/HPPAModule.c', + 'arch/LoongArch/LoongArchInstPrinter.c', + 'arch/LoongArch/LoongArchDisassembler.c', + 'arch/LoongArch/LoongArchMapping.c', + 'arch/LoongArch/LoongArchDisassemblerExtension.c', + 'arch/LoongArch/LoongArchModule.c', + 'arch/M680X/M680XDisassembler.c', + 'arch/M680X/M680XInstPrinter.c', + 'arch/M680X/M680XModule.c', + 'arch/M68K/M68KDisassembler.c', + 'arch/M68K/M68KInstPrinter.c', + 'arch/M68K/M68KModule.c', + 'arch/Mips/MipsDisassembler.c', + 'arch/Mips/MipsInstPrinter.c', + 'arch/Mips/MipsMapping.c', + 'arch/Mips/MipsModule.c', + 'arch/PowerPC/PPCDisassembler.c', + 'arch/PowerPC/PPCInstPrinter.c', + 'arch/PowerPC/PPCMapping.c', + 'arch/PowerPC/PPCModule.c', + 'arch/Sparc/SparcDisassembler.c', + 'arch/Sparc/SparcDisassemblerExtension.c', + 'arch/Sparc/SparcInstPrinter.c', + 'arch/Sparc/SparcMapping.c', + 'arch/Sparc/SparcModule.c', + 'arch/SystemZ/SystemZDisassemblerExtension.c', + 'arch/SystemZ/SystemZDisassembler.c', + 'arch/SystemZ/SystemZInstPrinter.c', + 'arch/SystemZ/SystemZMapping.c', + 'arch/SystemZ/SystemZMCTargetDesc.c', + 'arch/SystemZ/SystemZModule.c', + 'arch/TMS320C64x/TMS320C64xDisassembler.c', + 'arch/TMS320C64x/TMS320C64xInstPrinter.c', + 'arch/TMS320C64x/TMS320C64xMapping.c', + 'arch/TMS320C64x/TMS320C64xModule.c', + 'arch/X86/X86ATTInstPrinter.c', + 'arch/X86/X86Disassembler.c', + 'arch/X86/X86DisassemblerDecoder.c', + 'arch/X86/X86IntelInstPrinter.c', + 'arch/X86/X86Mapping.c', + 'arch/X86/X86Module.c', + 'arch/X86/X86InstPrinterCommon.c', + 'arch/XCore/XCoreDisassembler.c', + 'arch/XCore/XCoreInstPrinter.c', + 'arch/XCore/XCoreMapping.c', + 'arch/XCore/XCoreModule.c', + 'arch/TriCore/TriCoreDisassembler.c', + 'arch/TriCore/TriCoreInstPrinter.c', + 'arch/TriCore/TriCoreMapping.c', + 'arch/TriCore/TriCoreModule.c', + 'arch/Xtensa/XtensaDisassembler.c', + 'arch/Xtensa/XtensaInstPrinter.c', + 'arch/Xtensa/XtensaMapping.c', + 'arch/Xtensa/XtensaModule.c', + 'arch/RISCV/RISCVBaseInfo.c', + 'arch/RISCV/RISCVDisassembler.c', + 'arch/RISCV/RISCVDisassemblerExtension.c', + 'arch/RISCV/RISCVInstPrinter.c', + 'arch/RISCV/RISCVMapping.c', + 'arch/RISCV/RISCVModule.c', + 'cs.c', + 'Mapping.c', + 'MCInst.c', + 'MCInstrDesc.c', + 'MCInstPrinter.c', + 'MCRegisterInfo.c', + 'SStream.c', + 'utils.c', +] + +capstone_includes = [include_directories('include'), include_directories('include/capstone')] + +libcapstone_c_args = [ + '-DCAPSTONE_X86_ATT_DISABLE_NO', + '-DCAPSTONE_X86_REDUCE_NO', + '-DCAPSTONE_USE_SYS_DYN_MEM', + '-DCAPSTONE_DIET_NO', + '-DCAPSTONE_HAS_AARCH64', + '-DCAPSTONE_HAS_ARC', + '-DCAPSTONE_HAS_ALPHA', + '-DCAPSTONE_HAS_ARM', + '-DCAPSTONE_HAS_HPPA', + '-DCAPSTONE_HAS_LOONGARCH', + '-DCAPSTONE_HAS_M680X', + '-DCAPSTONE_HAS_M68K', + '-DCAPSTONE_HAS_MIPS', + '-DCAPSTONE_HAS_POWERPC', + '-DCAPSTONE_HAS_SPARC', + '-DCAPSTONE_HAS_SYSTEMZ', + '-DCAPSTONE_HAS_TMS320C64X', + '-DCAPSTONE_HAS_TRICORE', + '-DCAPSTONE_HAS_X86', + '-DCAPSTONE_HAS_XCORE', + '-DCAPSTONE_HAS_XTENSA', + '-DCAPSTONE_HAS_RISCV' +] + +if meson.get_compiler('c').has_argument('-Wmaybe-uninitialized') + libcapstone_c_args += '-Wno-maybe-uninitialized' +endif + +libcapstone = library('capstone', cs_files, + c_args: libcapstone_c_args, + include_directories: capstone_includes, + implicit_include_directories: false +) + +capstone_dep = declare_dependency( + link_with: libcapstone, + include_directories: capstone_includes +) \ No newline at end of file diff --git a/sys/riscv_extension_parser_generator.py b/sys/riscv_extension_parser_generator.py new file mode 100644 index 00000000000..121d303bb8f --- /dev/null +++ b/sys/riscv_extension_parser_generator.py @@ -0,0 +1,335 @@ +#!/usr/bin/env python3 +""" +RISC-V Extension Trie-Based Parser Generator + +Given a list of RISCV_FeatureStdExt* enums, generates C code that: +1. Parses extension names using a trie data structure +2. ORs the corresponding enum value with a running accumulator +3. Includes an ASCII art tree visualization of the trie +4. Annotates branches with parse state +5. Uses macros to reduce boilerplate +""" + +from typing import Dict, List, Optional, Tuple +from dataclasses import dataclass + +@dataclass +class TrieNode: + children: Dict[str, 'TrieNode'] + enum_name: Optional[str] = None + + def __init__(self): + self.children = {} + self.enum_name = None + +class Trie: + def __init__(self): + self.root = TrieNode() + + def insert(self, ext_name: str, enum_name: str): + """Insert an extension name into the trie""" + node = self.root + for char in ext_name: + if char not in node.children: + node.children[char] = TrieNode() + node = node.children[char] + node.enum_name = enum_name + + def generate_ascii_tree(self, node: Optional[TrieNode] = None, + prefix: str = "", is_last: bool = True, + char: str = "ROOT") -> List[str]: + """Generate ASCII tree representation""" + if node is None: + node = self.root + + lines = [] + + # Current node + connector = "└── " if is_last else "├── " + if char == "ROOT": + line = "ROOT" + else: + line = prefix + connector + char + if node.enum_name: + line += f" [{node.enum_name}]" + lines.append(line) + + # Children + if node.children: + sorted_children = sorted(node.children.items()) + for i, (ch, child) in enumerate(sorted_children): + is_last_child = (i == len(sorted_children) - 1) + + if char == "ROOT": + child_prefix = "" + else: + extension = " " if is_last else "│ " + child_prefix = prefix + extension + + lines.extend(self.generate_ascii_tree( + child, child_prefix, is_last_child, ch + )) + + return lines + +def parse_enum_definitions(enum_text: str) -> List[Tuple[str, str]]: + """Parse enum definitions and extract extension names""" + results = [] + + for line in enum_text.strip().split('\n'): + line = line.strip() + if not line or not line.startswith('RISCV_FeatureStdExt'): + continue + + # Remove trailing comma and split + enum_name = line.rstrip(',').split('=')[0].strip() + + # Extract extension name (part after FeatureStdExt) + if 'FeatureStdExt' in enum_name: + ext_name = enum_name.split('FeatureStdExt')[1].lower() + if ext_name: # Skip empty names + results.append((ext_name, enum_name)) + + return results + +def generate_c_code(trie: Trie, extensions: List[Tuple[str, str]]) -> str: + """Generate the complete C parsing function""" + + # Generate ASCII tree + tree_lines = trie.generate_ascii_tree() + tree_comment = "\n".join(f" * {line}" for line in tree_lines) + + # Generate function body + code_lines = [] + + def generate_node_code(node: TrieNode, depth: int, path: str) -> List[str]: + """Recursively generate parsing code for trie nodes""" + lines = [] + indent = " " * depth + + if not node.children: + # Leaf node + if node.enum_name: + lines.append(f"{indent}STOP_WITH_MATCH({node.enum_name});") + else: + lines.append(f"{indent}STOP_WITHOUT_MATCH();") + return lines + + # Non-leaf node - check if this is also a valid end point + if node.enum_name: + lines.append(f"{indent}STOP_WITH_MATCH({node.enum_name});") + lines.append("") + + # Process children - add state comment only before branching + sorted_children = sorted(node.children.items()) + expected_chars = [c for c, _ in sorted_children] + expected_str = ''.join(expected_chars) + + lines.append(f"{indent}/* State: '{path}' expecting [{expected_str}] */") + + for i, (char, child) in enumerate(sorted_children): + if i == 0: + lines.append(f"{indent}if (*p == '{char}') {{") + else: + lines.append(f"{indent}}} else if (*p == '{char}') {{") + + lines.append(f"{indent} p++;") + lines.extend(generate_node_code(child, depth + 1, path + char)) + + lines.append(f"{indent}}} else {{") + + # In the else branch, we have an unexpected character + if node.enum_name: + # There was a valid match at the previous state + lines.append(f"{indent} /* Unexpected char, but '{path}' was valid */") + lines.append(f"{indent} STOP_WITH_MATCH({node.enum_name});") + else: + # No valid match at this point + lines.append(f"{indent} /* Unexpected char at '{path}', no match */") + lines.append(f"{indent} STOP_WITHOUT_MATCH();") + + lines.append(f"{indent}}}") + + return lines + + # Start with root's children + if trie.root.children: + code_lines.extend(generate_node_code(trie.root, 1, "")) + code_lines.append("") + code_lines.append(" /* Should not reach here */") + code_lines.append(" STOP_WITHOUT_MATCH();") + + # Build the complete function + full_code = "/*\n" + full_code += " * \n \n *********************************************** AUTO-GENERATED CODE, DO NOT EDIT BY HAND! " + full_code += " * *********************************************** \n \n" + full_code += " * RISC-V Extension Parser Using a Trie trick\n" + full_code += " * Generated from arch/RISCV/RISCVGenSubtargetInfo.inc in Capstone sources \n" + full_code += " * \n" + full_code += " * This function parses a single RISC-V extension name and ORs the corresponding\n" + full_code += " * feature flags with an accumulator 'mode'.\n" + full_code += " * \n" + full_code += " * Trie Diagram:\n" + full_code += tree_comment + "\n" + full_code += " */\n\n" + + flags_defs = "\n".join([f"#define {member} {i} \n" for i, (_, member) in enumerate(extensions)]) + full_code += flags_defs + + full_code += "/* Parse result enum - indicates why parsing stopped */\n" + full_code += "typedef enum {\n" + full_code += " RISCV_EXT_PARSE_END_OF_STRING, /* Stopped at '\\0' - valid extension found */\n" + full_code += " RISCV_EXT_PARSE_STOPPED_AT_NUMBER, /* Stopped at a digit - valid extension found */\n" + full_code += " RISCV_EXT_PARSE_STOPPED_AT_UNDERSCORE, /* Stopped at '_' - valid extension found */\n" + full_code += " RISCV_EXT_PARSE_STOPPED_AT_UNEXPECTED, /* Stopped at unexpected char - valid extension found */\n" + full_code += " RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING, /* Reached '\\0' - no valid extension */\n" + full_code += " RISCV_EXT_PARSE_NO_MATCH_NUMBER, /* Hit number - no valid extension at this point */\n" + full_code += " RISCV_EXT_PARSE_NO_MATCH_UNDERSCORE, /* Hit underscore - no valid extension at this point */\n" + full_code += " RISCV_EXT_PARSE_NO_MATCH_UNEXPECTED, /* Hit unexpected char - no valid extension */\n" + full_code += "} riscv_extension_parse_result_t;\n\n" + + full_code += "/* Macro: Stop parsing with a matched extension */\n" + full_code += "#ifndef MATCH_CALLBACK\n" + full_code += "#define MATCH_CALLBACK(feature_enum)\n" + full_code += "#endif\n\n" + full_code += "#ifndef FINI_EXT_CALLBACKS\n" + full_code += "#define FINI_EXT_CALLBACKS()\n" + full_code += "#endif\n\n" + full_code += "#define STOP_WITH_MATCH(feature_enum) \\\n" + full_code += " do { \\\n" + full_code += " MATCH_CALLBACK(feature_enum); \\\n" + full_code += " *idx = (size_t)(p - ext_name); \\\n" + full_code += " *mode = feature_enum; \\\n" + full_code += " FINI_EXT_CALLBACKS(); \\\n" + full_code += " if (*p == '\\0') { \\\n" + full_code += " return RISCV_EXT_PARSE_END_OF_STRING; \\\n" + full_code += " } else if (*p >= '0' && *p <= '9') { \\\n" + full_code += " return RISCV_EXT_PARSE_STOPPED_AT_NUMBER; \\\n" + full_code += " } else if (*p == '_') { \\\n" + full_code += " return RISCV_EXT_PARSE_STOPPED_AT_UNDERSCORE; \\\n" + full_code += " } else { \\\n" + full_code += " return RISCV_EXT_PARSE_STOPPED_AT_UNEXPECTED; \\\n" + full_code += " } \\\n" + full_code += " } while (0)\n\n" + + full_code += "/* Macro: Stop parsing without a match */\n" + full_code += "#define STOP_WITHOUT_MATCH() \\\n" + full_code += " do { \\\n" + full_code += " *idx = (size_t)(p - ext_name); \\\n" + full_code += " if (*p == '\\0') { \\\n" + full_code += " return RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING; \\\n" + full_code += " } else if (*p >= '0' && *p <= '9') { \\\n" + full_code += " return RISCV_EXT_PARSE_NO_MATCH_NUMBER; \\\n" + full_code += " } else if (*p == '_') { \\\n" + full_code += " return RISCV_EXT_PARSE_NO_MATCH_UNDERSCORE; \\\n" + full_code += " } else { \\\n" + full_code += " return RISCV_EXT_PARSE_NO_MATCH_UNEXPECTED; \\\n" + full_code += " } \\\n" + full_code += " } while (0)\n\n" + + full_code += "/**\n" + full_code += " * Main parse routine: Try to consume a RISC-V extension name from the architecture string at a given position.\n" + full_code += " * \n" + full_code += " * @param arch_str: The full architecture string\n" + full_code += " * @param idx: Pointer to current index (will be updated to show consumed length)\n" + full_code += " * @param mode: Pointer to the feature accumulator (will be ORed with the feature flag if extension found)\n" + full_code += " * @return: Parse result indicating why parsing stopped and whether a match was found\n" + full_code += " * \n" + full_code += " * Stopping conditions:\n" + full_code += " * - '\\0' (end of string)\n" + full_code += " * - '0'-'9' (version number)\n" + full_code += " * - '_' (extension separator)\n" + full_code += " * - Any unexpected character\n" + full_code += " * \n" + full_code += " * The function uses a trie-based approach for efficient parsing.\n" + full_code += " * State comments show the current position in the trie:\n" + full_code += " * 'abc...' means we've matched 'abc' and are looking for more\n" + full_code += " * 'abc(!x)' means we've matched 'abc' but encountered unexpected char instead of 'x'\n" + full_code += " */\n" + full_code += "#ifndef INIT_EXT_CALLBACKS\n" + full_code += "#define INIT_EXT_CALLBACKS()\n" + full_code += "#endif\n\n" + full_code += "static inline riscv_extension_parse_result_t\n" + full_code += "try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode)\n" + full_code += "{\n" + full_code += " if (!ext_name || !idx || !mode) {\n" + full_code += " return RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING;\n" + full_code += " }\n" + full_code += " \n" + full_code += " INIT_EXT_CALLBACKS();\n" + full_code += " const char *p = ext_name + *idx;\n" + full_code += " \n" + full_code += " if (*p == '\\0') {\n" + full_code += " return RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING;\n" + full_code += " }\n\n" + + full_code += "\n".join(code_lines) + full_code += "\n}\n\n" + + full_code += "/* Cleanup macros */\n" + full_code += "#undef STOP_WITH_MATCH\n" + full_code += "#undef STOP_WITHOUT_MATCH\n\n" + + # Add example usage + full_code += "/* Example usage:\n" + full_code += " *\n" + full_code += " * ut64 features = 0;\n" + full_code += " * riscv_extension_parse_result_t result;\n" + full_code += " * size_t idx = 0;\n" + full_code += " * const char *arch = \"i2p1_m2p0_zicsr\";\n" + full_code += " * \n" + full_code += " * // Parse \"i\" from \"i2p1_m2p0_zicsr\"\n" + full_code += " * result = try_consume_riscv_ext_from(arch, &idx, &features);\n" + full_code += " * // idx is now 1, result is RISCV_EXT_PARSE_STOPPED_AT_NUMBER\n" + full_code += " * \n" + full_code += " * // Skip version \"2p1_\" by setting idx = 5\n" + full_code += " * idx = 5; // now at 'm'\n" + full_code += " * result = try_consume_riscv_ext_from(arch, &idx, &features);\n" + full_code += " * // idx is now 6, result is RISCV_EXT_PARSE_STOPPED_AT_NUMBER\n" + full_code += " * \n" + full_code += " * // Skip version \"2p0_\" by setting idx = 10\n" + full_code += " * idx = 10; // now at 'z'\n" + full_code += " * result = try_consume_riscv_ext_from(arch, &idx, &features);\n" + full_code += " * // idx is now 15, result is RISCV_EXT_PARSE_END_OF_STRING\n" + full_code += " */\n" + + return full_code + +def main(): + import sys + import os + + if len(sys.argv) < 3: + print(f"Usage: {sys.argv[0]} ") + sys.exit(1) + + input_header = sys.argv[1] + output_file = sys.argv[2] + + if not os.path.exists(input_header): + print(f"Error: Input file {input_header} not found") + sys.exit(1) + + with open(input_header, 'r') as f: + enum_text = "\n".join([line for line in f if line.strip().startswith('RISCV_FeatureStdExt')]) + + # Parse enum definitions + extensions = parse_enum_definitions(enum_text) + + if not extensions: + print(f"Warning: No extensions found in {input_header}") + + # Build trie + trie = Trie() + for ext_name, enum_name in extensions: + trie.insert(ext_name, enum_name) + + # Generate C code + c_code = generate_c_code(trie, extensions) + + # Output to file + with open(output_file, 'w') as f: + f.write(c_code) + +if __name__ == "__main__": + main() diff --git a/test/db/analysis/riscv b/test/db/analysis/riscv index a9f3127f49d..3bed7d86532 100644 --- a/test/db/analysis/riscv +++ b/test/db/analysis/riscv @@ -19,7 +19,7 @@ wx 21a001009d06aa858146 pd 5 EOF EXPECT=< 0x00000002 8280 ret :`-> 0x00000004 9d06 addi a3, a3, 7 - `==< 0x00000006 f5fe bnez a3, 0x2 - 0x00000008 0000 illegal -EOF -RUN - -NAME=asm pseudo for riscv -FILE=bins/elf/analysis/guess-number-riscv64 -CMDS=< 0x00010170 b7170200 lui a5, 0x21 -| :: 0x00010174 1385874f addi a0, a5, 1272 -| :: 0x00010178 ef00c01f jal ra, sym.printf -| :: 0x0001017c 930784fe addi a5, s0, -24 +| :: 0x00010174 1385874f addi a0, a5, 0x4f8 +| :: 0x00010178 ef00c01f jal sym.printf +| :: 0x0001017c 930784fe addi a5, s0, -0x18 | :: 0x00010180 93850700 mv a1, a5 | :: 0x00010184 b7170200 lui a5, 0x21 -| :: 0x00010188 13850751 addi a0, a5, 1296 -| :: 0x0001018c ef00402f jal ra, sym.scanf -| :: 0x00010190 032784fe lw a4, -24(s0) -| :: 0x00010194 8327c4fe lw a5, -20(s0) +| :: 0x00010188 13850751 addi a0, a5, 0x510 +| :: 0x0001018c ef00402f jal sym.scanf +| :: 0x00010190 032784fe lw a4, -0x18(s0) +| :: 0x00010194 8327c4fe lw a5, -0x14(s0) | ,===< 0x00010198 631cf700 bne a4, a5, 0x101b0 | |:: 0x0001019c b7170200 lui a5, 0x21 -| |:: 0x000101a0 13858751 addi a0, a5, 1304 -| |:: 0x000101a4 ef00002d jal ra, sym.puts +| |:: 0x000101a0 13858751 addi a0, a5, 0x518 +| |:: 0x000101a4 ef00002d jal sym.puts | |:: 0x000101a8 93070000 li a5, 0 | ,====< 0x000101ac 6f000003 j 0x101dc -| |`---> 0x000101b0 032784fe lw a4, -24(s0) -| | :: 0x000101b4 8327c4fe lw a5, -20(s0) -| |,===< 0x000101b8 635af700 ble a5, a4, 0x101cc +| |`---> 0x000101b0 032784fe lw a4, -0x18(s0) +| | :: 0x000101b4 8327c4fe lw a5, -0x14(s0) +| |,===< 0x000101b8 635af700 bge a4, a5, 0x101cc | ||:: 0x000101bc b7170200 lui a5, 0x21 -| ||:: 0x000101c0 13858752 addi a0, a5, 1320 -| ||:: 0x000101c4 ef00002b jal ra, sym.puts +| ||:: 0x000101c0 13858752 addi a0, a5, 0x528 +| ||:: 0x000101c4 ef00002b jal sym.puts | ||`==< 0x000101c8 6ff09ffa j 0x10170 | |`---> 0x000101cc b7170200 lui a5, 0x21 -| | : 0x000101d0 13858753 addi a0, a5, 1336 -| | : 0x000101d4 ef00002a jal ra, sym.puts +| | : 0x000101d0 13858753 addi a0, a5, 0x538 +| | : 0x000101d4 ef00002a jal sym.puts | | `=< 0x000101d8 6ff09ff9 j 0x10170 | | ; CODE XREF from main @ 0x101ac | `----> 0x000101dc 13850700 mv a0, a5 -| 0x000101e0 83308101 ld ra, 24(sp) -| 0x000101e4 03340101 ld s0, 16(sp) -| 0x000101e8 13010102 addi sp, sp, 32 +| 0x000101e0 83308101 ld ra, 0x18(sp) +| 0x000101e4 03340101 ld s0, 0x10(sp) +| 0x000101e8 13010102 addi sp, sp, 0x20 \ 0x000101ec 67800000 ret EOF RUN @@ -520,47 +520,47 @@ EXPECT=< 0x00010170 b7170200 lui a5, 0x21 -| :: 0x00010174 1385874f addi a0, a5, 1272 ; const char *fmt -| :: 0x00010178 ef00c01f jal ra, dbg.printf -| :: 0x0001017c 930784fe addi a5, s0, -24 +| :: 0x00010174 1385874f addi a0, a5, 0x4f8 +| :: 0x00010178 ef00c01f jal dbg.printf +| :: 0x0001017c 930784fe addi a5, s0, -0x18 | :: 0x00010180 93850700 mv a1, a5 | :: 0x00010184 b7170200 lui a5, 0x21 -| :: 0x00010188 13850751 addi a0, a5, 1296 ; const char *fmt -| :: 0x0001018c ef00402f jal ra, dbg.scanf -| :: 0x00010190 032784fe lw a4, -24(s0) -| :: 0x00010194 8327c4fe lw a5, -20(s0) +| :: 0x00010188 13850751 addi a0, a5, 0x510 +| :: 0x0001018c ef00402f jal dbg.scanf +| :: 0x00010190 032784fe lw a4, -0x18(s0) +| :: 0x00010194 8327c4fe lw a5, -0x14(s0) | ,===< 0x00010198 631cf700 bne a4, a5, 0x101b0 | |:: 0x0001019c b7170200 lui a5, 0x21 -| |:: 0x000101a0 13858751 addi a0, a5, 1304 ; const char *s -| |:: 0x000101a4 ef00002d jal ra, dbg.puts +| |:: 0x000101a0 13858751 addi a0, a5, 0x518 +| |:: 0x000101a4 ef00002d jal dbg.puts | |:: 0x000101a8 93070000 li a5, 0 | ,====< 0x000101ac 6f000003 j 0x101dc -| |`---> 0x000101b0 032784fe lw a4, -24(s0) -| | :: 0x000101b4 8327c4fe lw a5, -20(s0) -| |,===< 0x000101b8 635af700 ble a5, a4, 0x101cc +| |`---> 0x000101b0 032784fe lw a4, -0x18(s0) +| | :: 0x000101b4 8327c4fe lw a5, -0x14(s0) +| |,===< 0x000101b8 635af700 bge a4, a5, 0x101cc | ||:: 0x000101bc b7170200 lui a5, 0x21 -| ||:: 0x000101c0 13858752 addi a0, a5, 1320 ; const char *s -| ||:: 0x000101c4 ef00002b jal ra, dbg.puts +| ||:: 0x000101c0 13858752 addi a0, a5, 0x528 +| ||:: 0x000101c4 ef00002b jal dbg.puts | ||`==< 0x000101c8 6ff09ffa j 0x10170 | |`---> 0x000101cc b7170200 lui a5, 0x21 -| | : 0x000101d0 13858753 addi a0, a5, 1336 ; const char *s -| | : 0x000101d4 ef00002a jal ra, dbg.puts +| | : 0x000101d0 13858753 addi a0, a5, 0x538 +| | : 0x000101d4 ef00002a jal dbg.puts | | `=< 0x000101d8 6ff09ff9 j 0x10170 | | ; CODE XREF from main @ 0x101ac | `----> 0x000101dc 13850700 mv a0, a5 -| 0x000101e0 83308101 ld ra, 24(sp) -| 0x000101e4 03340101 ld s0, 16(sp) -| 0x000101e8 13010102 addi sp, sp, 32 +| 0x000101e0 83308101 ld ra, 0x18(sp) +| 0x000101e4 03340101 ld s0, 0x10(sp) +| 0x000101e8 13010102 addi sp, sp, 0x20 \ 0x000101ec 67800000 ret EOF RUN diff --git a/test/db/formats/elf/riscv-relocs b/test/db/formats/elf/riscv-relocs new file mode 100644 index 00000000000..e199816c7ef --- /dev/null +++ b/test/db/formats/elf/riscv-relocs @@ -0,0 +1,929 @@ +NAME=ADD8/16/32/64 and SUB8/16/32/64 relocs +FILE=bins/elf/riscv_relocs_add +CMDS=< 0x08000038 jal loc._x.0 ; RELOC 0 bar @ 0x08000034 +nth paddr vaddr bind type size lib name +-------------------------------------------------------- + 1 0x00000038 0x08000038 LOCAL NOTYPE 0 foo + 2 0x00000034 0x08000034 LOCAL NOTYPE 0 $x.0 + 3 0x00000034 0x08000034 LOCAL NOTYPE 0 bar + 4 0x00000034 0x08000034 GLOBAL NOTYPE 0 _start + vaddr paddr target type name +-------------------------------------------------- +0x08000034 0x00000034 0x08000038 R_RISCV_JAL foo +0x08000038 0x00000038 0x08000034 R_RISCV_JAL bar +EOF +RUN + +NAME=JAL relocs (64 bits near) +FILE=bins/elf/riscv_relocs_jal_near_64 +CMDS=< 0x08000044 jal loc._x.0 ; RELOC 0 bar @ 0x08000040 +nth paddr vaddr bind type size lib name +-------------------------------------------------------- + 1 0x00000044 0x08000044 LOCAL NOTYPE 0 foo + 2 0x00000040 0x08000040 LOCAL NOTYPE 0 $x.0 + 3 0x00000040 0x08000040 LOCAL NOTYPE 0 bar + 4 0x00000040 0x08000040 GLOBAL NOTYPE 0 _start + vaddr paddr target type name +-------------------------------------------------- +0x08000040 0x00000040 0x08000044 R_RISCV_JAL foo +0x08000044 0x00000044 0x08000040 R_RISCV_JAL bar +EOF +RUN + +NAME=JAL relocs (32 bits far) +FILE=bins/elf/riscv_relocs_jal_far_32 +CMDS=< 0x0800003e addi a0, a0, 1 ; RELOC TARGET 0 .LBB0_2 @ 0x0800003e + 0x08000040 ret +nth paddr vaddr bind type size lib name +---------------------------------------------------------------- + 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch.c + 2 0x00000034 0x08000034 LOCAL NOTYPE 0 $x.0 + 3 0x0000003e 0x0800003e LOCAL NOTYPE 0 .LBB0_2 + 4 0x00000042 0x08000042 LOCAL NOTYPE 0 $d.1 + 5 0x0000006a 0x0800006a LOCAL NOTYPE 0 $d.2 + 6 0x00000034 0x08000034 GLOBAL FUNC 14 test + vaddr paddr target type name +-------------------------------------------------------- +0x08000036 0x00000036 0x0800003e R_RISCV_BRANCH .LBB0_2 +EOF +RUN + +NAME=BRANCH relocs (64 bits near) +FILE=bins/elf/riscv_relocs_branch_near_64 +CMDS=< 0x0800004a addiw a0, a0, 1 ; RELOC TARGET 0 .LBB0_2 @ 0x0800004a + 0x0800004c ret +nth paddr vaddr bind type size lib name +---------------------------------------------------------------- + 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch.c + 2 0x00000040 0x08000040 LOCAL NOTYPE 0 $x.0 + 3 0x0000004a 0x0800004a LOCAL NOTYPE 0 .LBB0_2 + 4 0x0000004e 0x0800004e LOCAL NOTYPE 0 $d.1 + 5 0x00000076 0x08000076 LOCAL NOTYPE 0 $d.2 + 6 0x00000040 0x08000040 GLOBAL FUNC 14 test + vaddr paddr target type name +-------------------------------------------------------- +0x08000042 0x00000042 0x0800004a R_RISCV_BRANCH .LBB0_2 +EOF +RUN + + +NAME=BRANCH relocs (32 bits far forward) +FILE=bins/elf/riscv_relocs_branch_far_32 +CMDS=< 0x08001032 li a0, 1 ; RELOC TARGET 0 .LBB0_2 @ 0x08001032 +| 0x08001034 ret +nth paddr vaddr bind type size lib name +-------------------------------------------------------------------- + 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch_far.c + 2 0x00000034 0x08000034 LOCAL NOTYPE 0 $x.0 + 3 0x00001032 0x08001032 LOCAL NOTYPE 0 .LBB0_2 + 4 0x00002038 0x08002038 LOCAL NOTYPE 0 .LBB1_2 + 5 0x0000203c 0x0800203c LOCAL NOTYPE 0 .LBB2_1 + 6 0x00003044 0x08003044 LOCAL NOTYPE 0 .LBB3_1 + 7 0x00004050 0x08004050 LOCAL NOTYPE 0 $d.1 + 8 0x00004078 0x08004078 LOCAL NOTYPE 0 $d.2 + 9 0x00000034 0x08000034 GLOBAL FUNC 4098 test_forward_max + 10 0x00001036 0x08001036 GLOBAL FUNC 4102 test_forward_over + 11 0x0000203c 0x0800203c GLOBAL FUNC 4104 test_backward_max + 12 0x00003044 0x08003044 GLOBAL FUNC 4108 test_backward_over + vaddr paddr target type name +-------------------------------------------------------- +0x08000034 0x00000034 0x08001032 R_RISCV_BRANCH .LBB0_2 +0x08001038 0x00001038 0x08002038 R_RISCV_JAL .LBB1_2 +0x0800303c 0x0000303c 0x0800203c R_RISCV_BRANCH .LBB2_1 +0x08004048 0x00004048 0x08003044 R_RISCV_JAL .LBB3_1 +EOF +RUN + +NAME=BRANCH relocs (64 bits far forward) +FILE=bins/elf/riscv_relocs_branch_far_64 +CMDS=< 0x0800103e li a0, 1 ; RELOC TARGET 0 .LBB0_2 @ 0x0800103e +| 0x08001040 ret +nth paddr vaddr bind type size lib name +-------------------------------------------------------------------- + 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch_far.c + 2 0x00000040 0x08000040 LOCAL NOTYPE 0 $x.0 + 3 0x0000103e 0x0800103e LOCAL NOTYPE 0 .LBB0_2 + 4 0x00002044 0x08002044 LOCAL NOTYPE 0 .LBB1_2 + 5 0x00002048 0x08002048 LOCAL NOTYPE 0 .LBB2_1 + 6 0x00003050 0x08003050 LOCAL NOTYPE 0 .LBB3_1 + 7 0x0000405c 0x0800405c LOCAL NOTYPE 0 $d.1 + 8 0x00004084 0x08004084 LOCAL NOTYPE 0 $d.2 + 9 0x00000040 0x08000040 GLOBAL FUNC 4098 test_forward_max + 10 0x00001042 0x08001042 GLOBAL FUNC 4102 test_forward_over + 11 0x00002048 0x08002048 GLOBAL FUNC 4104 test_backward_max + 12 0x00003050 0x08003050 GLOBAL FUNC 4108 test_backward_over + vaddr paddr target type name +-------------------------------------------------------- +0x08000040 0x00000040 0x0800103e R_RISCV_BRANCH .LBB0_2 +0x08001044 0x00001044 0x08002044 R_RISCV_JAL .LBB1_2 +0x08003048 0x00003048 0x08002048 R_RISCV_BRANCH .LBB2_1 +0x08004054 0x00004054 0x08003050 R_RISCV_JAL .LBB3_1 +EOF +RUN + +NAME=BRANCH relocs (32 bits far backward) +FILE=bins/elf/riscv_relocs_branch_far_32 +CMDS=< 0x0800004e addi a0, a0, 0xf ; RELOC TARGET 0 .LBB0_2 @ 0x0800004e +| | ; CODE XREF from loc._x.0 @ 0x800004c +| | ;-- .LBB0_3: +| `--> 0x08000050 lw ra, 0xc(sp) ; RELOC TARGET 0 .LBB0_3 @ 0x08000050 +| 0x08000052 lw s0, 8(sp) +| 0x08000054 addi sp, sp, 0x10 +\ 0x08000056 ret +nth paddr vaddr bind type size lib name +-------------------------------------------------------------------------------- + 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch_compressed_near.c + 2 0x00000034 0x08000034 LOCAL NOTYPE 0 $x.0 + 3 0x0000004e 0x0800004e LOCAL NOTYPE 0 .LBB0_2 + 4 0x00000050 0x08000050 LOCAL NOTYPE 0 .LBB0_3 + 5 0x00000058 0x08000058 LOCAL NOTYPE 0 $d.1 + 6 0x00000080 0x08000080 LOCAL NOTYPE 0 $d.2 + 7 0x00000034 0x08000034 GLOBAL FUNC 36 test + 8 ---------- ---------- GLOBAL NOTYPE 0 imp.__mulsi3 + vaddr paddr target type name +------------------------------------------------------------- +0x08000040 0x00000040 0x00000000 R_RISCV_RELAX +0x08000040 0x00000040 0x08000210 R_RISCV_CALL_PLT __mulsi3 +0x08000048 0x00000048 0x0800004e R_RISCV_RVC_BRANCH .LBB0_2 +0x0800004c 0x0000004c 0x08000050 R_RISCV_RVC_JUMP .LBB0_3 +EOF +RUN + +NAME=RVC BRANCH (near 64-bits) +FILE=bins/elf/riscv_relocs_rvc_branch_near_64 +CMDS=< 0x0800005a addiw a0, a0, 0xf ; RELOC TARGET 0 .LBB0_2 @ 0x0800005a ; arg1 +| | ; CODE XREF from loc._x.0 @ 0x8000058 +| | ;-- .LBB0_3: +| `--> 0x0800005c ld ra, 8(sp) ; RELOC TARGET 0 .LBB0_3 @ 0x0800005c +| 0x0800005e ld s0, 0(sp) +| 0x08000060 addi sp, sp, 0x10 +\ 0x08000062 ret +nth paddr vaddr bind type size lib name +-------------------------------------------------------------------------------- + 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch_compressed_near.c + 2 0x00000040 0x08000040 LOCAL NOTYPE 0 $x.0 + 3 0x0000005a 0x0800005a LOCAL NOTYPE 0 .LBB0_2 + 4 0x0000005c 0x0800005c LOCAL NOTYPE 0 .LBB0_3 + 5 0x00000064 0x08000064 LOCAL NOTYPE 0 $d.1 + 6 0x0000008c 0x0800008c LOCAL NOTYPE 0 $d.2 + 7 0x00000040 0x08000040 GLOBAL FUNC 36 test + 8 ---------- ---------- GLOBAL NOTYPE 0 imp.__muldi3 + vaddr paddr target type name +------------------------------------------------------------- +0x0800004c 0x0000004c 0x00000000 R_RISCV_RELAX +0x0800004c 0x0000004c 0x08000298 R_RISCV_CALL_PLT __muldi3 +0x08000054 0x00000054 0x0800005a R_RISCV_RVC_BRANCH .LBB0_2 +0x08000058 0x00000058 0x0800005c R_RISCV_RVC_JUMP .LBB0_3 +EOF +RUN + +NAME=RVC BRANCH (far forward 32-bits) +FILE=bins/elf/riscv_relocs_rvc_branch_far_32 +CMDS=< 0x08000132 li a0, 1 ; RELOC TARGET 0 .LBB0_2 @ 0x08000132 +| 0x08000134 ret +nth paddr vaddr bind type size lib name +------------------------------------------------------------------------------- + 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch_compressed_far.c + 2 0x00000034 0x08000034 LOCAL NOTYPE 0 $x.0 + 3 0x00000132 0x08000132 LOCAL NOTYPE 0 .LBB0_2 + 4 0x00000238 0x08000238 LOCAL NOTYPE 0 .LBB1_2 + 5 0x0000023c 0x0800023c LOCAL NOTYPE 0 .LBB2_1 + 6 0x00000342 0x08000342 LOCAL NOTYPE 0 .LBB3_1 + 7 0x0000044c 0x0800044c LOCAL NOTYPE 0 $d.1 + 8 0x00000474 0x08000474 LOCAL NOTYPE 0 $d.2 + 9 0x00000034 0x08000034 GLOBAL FUNC 258 test_forward_max + 10 0x00000136 0x08000136 GLOBAL FUNC 262 test_forward_over + 11 0x0000023c 0x0800023c GLOBAL FUNC 262 test_backward_max + 12 0x00000342 0x08000342 GLOBAL FUNC 266 test_backward_over + vaddr paddr target type name +------------------------------------------------------------ +0x08000034 0x00000034 0x08000132 R_RISCV_RVC_BRANCH .LBB0_2 +0x08000136 0x00000136 0x08000238 R_RISCV_BRANCH .LBB1_2 +0x0800033c 0x0000033c 0x0800023c R_RISCV_RVC_BRANCH .LBB2_1 +0x08000444 0x00000444 0x08000342 R_RISCV_BRANCH .LBB3_1 +EOF +RUN + +NAME=RVC BRANCH (far backward 32-bits) +FILE=bins/elf/riscv_relocs_rvc_branch_far_32 +CMDS=< 0x0800013e li a0, 1 ; RELOC TARGET 0 .LBB0_2 @ 0x0800013e +| 0x08000140 ret +nth paddr vaddr bind type size lib name +------------------------------------------------------------------------------- + 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch_compressed_far.c + 2 0x00000040 0x08000040 LOCAL NOTYPE 0 $x.0 + 3 0x0000013e 0x0800013e LOCAL NOTYPE 0 .LBB0_2 + 4 0x00000244 0x08000244 LOCAL NOTYPE 0 .LBB1_2 + 5 0x00000248 0x08000248 LOCAL NOTYPE 0 .LBB2_1 + 6 0x0000034e 0x0800034e LOCAL NOTYPE 0 .LBB3_1 + 7 0x00000458 0x08000458 LOCAL NOTYPE 0 $d.1 + 8 0x00000480 0x08000480 LOCAL NOTYPE 0 $d.2 + 9 0x00000040 0x08000040 GLOBAL FUNC 258 test_forward_max + 10 0x00000142 0x08000142 GLOBAL FUNC 262 test_forward_over + 11 0x00000248 0x08000248 GLOBAL FUNC 262 test_backward_max + 12 0x0000034e 0x0800034e GLOBAL FUNC 266 test_backward_over + vaddr paddr target type name +------------------------------------------------------------ +0x08000040 0x00000040 0x0800013e R_RISCV_RVC_BRANCH .LBB0_2 +0x08000142 0x00000142 0x08000244 R_RISCV_BRANCH .LBB1_2 +0x08000348 0x00000348 0x08000248 R_RISCV_RVC_BRANCH .LBB2_1 +0x08000450 0x00000450 0x0800034e R_RISCV_BRANCH .LBB3_1 +EOF +RUN + +NAME=RVC BRANCH (far backward 64-bits) +FILE=bins/elf/riscv_relocs_rvc_branch_far_64 +CMDS=<regdelta->name, "r3", "Source reg base should be r3"); rz_analysis_op_fini(&op); -#if WITH_GPL SWITCH_TO_ARCH_BITS("riscv", 32); // lw s10, 64(sp) rz_analysis_op_init(&op); @@ -94,13 +93,12 @@ bool test_rz_analysis_op_val() { rz_analysis_op_init(&op); len = rz_analysis_op(analysis, &op, 0, (const ut8 *)"\x22\xc5", 2, RZ_ANALYSIS_OP_MASK_VAL); mu_assert_eq(len, 2, "Op is of size 2"); - mu_assert_eq(op.dst->type, RZ_ANALYSIS_VAL_MEM, "Destination should be reg"); + mu_assert_eq(op.dst->type, RZ_ANALYSIS_VAL_MEM, "Destination should be mem"); mu_assert_streq(op.dst->reg->name, "sp", "Dst reg should be s10"); mu_assert_eq(op.dst->delta, 136, "Source delta should be 64"); mu_assert_eq(op.src[0]->type, RZ_ANALYSIS_VAL_REG, "Source should be reg"); mu_assert_streq(op.src[0]->reg->name, "s0", "Source reg base should be s0"); rz_analysis_op_fini(&op); -#endif rz_analysis_free(analysis); mu_end; From 85b3930fbd4e70be3246c8c5e653722f2f60558d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D9=85=D8=B5=D8=B7=D9=81=D9=8A=20=D9=85=D8=AD=D9=85=D9=88?= =?UTF-8?q?=D8=AF=20=D9=83=D9=85=D8=A7=D9=84=20=D8=A7=D9=84=D8=AF=D9=8A?= =?UTF-8?q?=D9=86?= <48567303+moste00@users.noreply.github.com> Date: Sun, 8 Feb 2026 01:52:21 +0200 Subject: [PATCH 3/3] fix CI --- librz/arch/p/analysis/analysis_riscv_cs.c | 10 +- librz/arch/p/analysis/analysis_riscv_utils.h | 3 + librz/arch/p/arch_riscv_cs.c | 7 +- librz/arch/p/arch_riscv_extension_parser.inc | 3 + librz/arch/p/asm/asm_riscv_cs.c | 3 +- librz/bin/format/elf/elf_info.c | 27 +- librz/bin/format/elf/elf_relocs_patching.c | 1 + meson_options.txt | 2 +- .../capstone-capstone-riscv-updated.wrap | 6 - subprojects/capstone-next.wrap | 2 +- subprojects/capstone-v6.wrap | 10 +- .../capstone-6.0.0-alpha6/meson.build | 141 ------- .../meson.build | 18 +- sys/riscv_extension_parser_generator.py | 207 ++++++---- test/db/analysis/alpha | 2 +- test/db/analysis/riscv | 367 +++++++++--------- test/db/cmd/cmd_aL | 3 +- test/db/cmd/cmd_list | 18 +- test/db/formats/elf/riscv-relocs | 15 +- test/db/formats/zimg | 1 + test/unit/meson.build | 5 +- test/unit/test_analysis_op.c | 1 + 22 files changed, 397 insertions(+), 455 deletions(-) delete mode 100644 subprojects/capstone-capstone-riscv-updated.wrap delete mode 100644 subprojects/packagefiles/capstone-6.0.0-alpha6/meson.build rename subprojects/packagefiles/{capstone-riscv-updated => capstone-6.0.0-alpha7}/meson.build (97%) diff --git a/librz/arch/p/analysis/analysis_riscv_cs.c b/librz/arch/p/analysis/analysis_riscv_cs.c index 62a1141d745..1c7cb74435d 100644 --- a/librz/arch/p/analysis/analysis_riscv_cs.c +++ b/librz/arch/p/analysis/analysis_riscv_cs.c @@ -1,5 +1,6 @@ +// SPDX-FileCopyrightText: 2024-2026 moste00 // SPDX-FileCopyrightText: 2013-2020 pancake -// SPDX-License-Identifier: LGPL-3.0-only +// SPDX-License-Identifier: BSD-3-Clause #include #include "rz_reg.h" @@ -462,10 +463,8 @@ static void set_op_val(RzAnalysisOp *op, cs_insn *insn) { switch (insn->id) { case RISCV_INS_LUI: case RISCV_INS_C_LUI: - op->val = imm << 12; - break; case RISCV_INS_AUIPC: - op->val = op->addr + (imm << 12); + op->val = imm << 12; break; default: op->val = imm; @@ -842,8 +841,7 @@ int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf } case RISCV_INS_JALR: - // special case (TODO: move to capstone and depend only on the groups API) - if (insn->detail->riscv.op_count == 0) { + if (group_exists_in(insn->detail->groups, insn->detail->groups_count, RISCV_GRP_RET)) { op->type = RZ_ANALYSIS_OP_TYPE_RET; break; } diff --git a/librz/arch/p/analysis/analysis_riscv_utils.h b/librz/arch/p/analysis/analysis_riscv_utils.h index 105f301ddfa..6687ad774dc 100644 --- a/librz/arch/p/analysis/analysis_riscv_utils.h +++ b/librz/arch/p/analysis/analysis_riscv_utils.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: 2024-2026 moste00 +// SPDX-License-Identifier: BSD-3-Clause + #include #include "cs_operand.h" diff --git a/librz/arch/p/arch_riscv_cs.c b/librz/arch/p/arch_riscv_cs.c index 6022513638d..b73fb9311ca 100644 --- a/librz/arch/p/arch_riscv_cs.c +++ b/librz/arch/p/arch_riscv_cs.c @@ -1,6 +1,6 @@ -// SPDX-FileCopyrightText: 2024 RizinOrg +// SPDX-FileCopyrightText: 2024-2026 moste00 // SPDX-FileCopyrightText: 2024 deroad -// SPDX-License-Identifier: LGPL-3.0-only +// SPDX-License-Identifier: BSD-3-Clause #include #include @@ -116,7 +116,8 @@ size_t skip_extension_version(const char *arch_str, size_t curr) { size_t curr1 = expect_char(arch_str, 'p', curr); if (curr1 == curr) { // error, expected p - RZ_LOG_ERROR("Invalid architecture string: expected the version separator 'p' at index %zu in archiecture string %s, found %c instead\n", + RZ_LOG_ERROR("Invalid architecture string: expected the version separator 'p' at index %zu" + "in archiecture string %s, found %c instead\n", curr, arch_str, arch_str[curr]); return curr; } diff --git a/librz/arch/p/arch_riscv_extension_parser.inc b/librz/arch/p/arch_riscv_extension_parser.inc index 6044552620a..867d408bef0 100644 --- a/librz/arch/p/arch_riscv_extension_parser.inc +++ b/librz/arch/p/arch_riscv_extension_parser.inc @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: 2024-2026 moste00 +// SPDX-License-Identifier: BSD-3-Clause + /* * diff --git a/librz/arch/p/asm/asm_riscv_cs.c b/librz/arch/p/asm/asm_riscv_cs.c index 8eb9daf2748..21354fd4ef3 100644 --- a/librz/arch/p/asm/asm_riscv_cs.c +++ b/librz/arch/p/asm/asm_riscv_cs.c @@ -1,5 +1,6 @@ +// SPDX-FileCopyrightText: 2024-2026 moste00 // SPDX-FileCopyrightText: 2019 pancake -// SPDX-License-Identifier: LGPL-3.0-only +// SPDX-License-Identifier: BSD-3-Clause #include #include diff --git a/librz/bin/format/elf/elf_info.c b/librz/bin/format/elf/elf_info.c index f3134fe6b90..55cb9f41026 100644 --- a/librz/bin/format/elf/elf_info.c +++ b/librz/bin/format/elf/elf_info.c @@ -12,7 +12,6 @@ #include "rz_util/rz_log.h" #include "rz_util/rz_str.h" #include "rz_util/rz_strbuf.h" -#include #define VERSYM_VERSION 0x7fff @@ -748,14 +747,27 @@ static RzBuffer *get_riscv_attributes_section(ELFOBJ *bin) { return rz_buf_new_slice(bin->b, section->offset, section->size); } +/// All possible results of getting a riscv attribute of a given tag typedef enum { - RISCV_ATTR_NONE = 0, - RISCV_ATTR_TRUNCATED_NT_STRING = 1, - RISCV_ATTR_NT_STRING = 2, - RISCV_ATTR_ULEB128 = 3, - RISCV_ATTR_TRUNCATED_ULEB128 = 4, + RISCV_ATTR_NONE = 0, //< no attribute was found with the given tag or parsing error of the section format + RISCV_ATTR_TRUNCATED_NT_STRING = 1, //< attribute of type null-terminated string, too long to fit into result buffer + RISCV_ATTR_NT_STRING = 2, //< attribute of type null-terminated string + RISCV_ATTR_ULEB128 = 3, //< attribute of type uleb128 integer + RISCV_ATTR_TRUNCATED_ULEB128 = 4, //< attribute of type uleb128 integer, too big to fit into result buffer } riscv_attr_type; +/** + * \brief Get a riscv attribute of a given tag from the .riscv.attributes section + * This section is defined in the RISC-V ELF psABI as a sequence of uleb128 encoded tags + * paired with either null-terminated string or uleb128 values. + * + * \param sec The .riscv.attributes section + * \param attr_tag The tag of the attribute to get + * \param result_maxlen The maximum capacity of the result buffer + * \param [out] result The result buffer + * \param [out] result_len The length of usable data in the result buffer, always <= result_maxlen + * \return riscv_attr_type The type of the found attribute, indicating whether it's a string or uleb128 integer and whether it was truncated + */ static riscv_attr_type get_riscv_attribute_from_section(RzBuffer *sec, ut64 attr_tag, int result_maxlen, ut8 *result, int *result_len) { // format: /* @@ -863,8 +875,7 @@ static riscv_attr_type get_riscv_attribute_from_section(RzBuffer *sec, ut64 attr return RISCV_ATTR_NONE; } -static int -get_bits_mips(ELFOBJ *bin) { +static int get_bits_mips(ELFOBJ *bin) { if (is_elf_class64(bin)) { return 64; } diff --git a/librz/bin/format/elf/elf_relocs_patching.c b/librz/bin/format/elf/elf_relocs_patching.c index cf63c410fa2..d2d2dea0883 100644 --- a/librz/bin/format/elf/elf_relocs_patching.c +++ b/librz/bin/format/elf/elf_relocs_patching.c @@ -2327,6 +2327,7 @@ static const ut16 RISCV_CI_TYPE_IMM_MASK = (1 << 12) | (0x1f << 2); if (w == 32) { \ i = ((ut32)i); \ } + static void patch_reloc_riscv(RZ_INOUT RzBuffer *buf_patched, const ut64 patch_addr, const int rel_type, bool big_endian, const RelocFormularSymbols *fs, const int bits) { rz_return_if_fail(buf_patched && fs); diff --git a/meson_options.txt b/meson_options.txt index 5698faaa6e0..a3969fd67b7 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -21,7 +21,7 @@ option('rizin_bindings', type: 'string', value: '', description: 'Path where riz option('checks_level', type: 'integer', value: 2, description: 'Value between 0 and 3 to enable different level of assert (see RZ_CHECKS_LEVEL)') option('use_sys_capstone', type: 'feature', value: 'disabled') -option('use_capstone_version', type: 'combo', choices: ['v4', 'v5', 'v6', 'next', 'capstone-riscv-updated'], value: 'next', description: 'Specify which version of capstone to use') +option('use_capstone_version', type: 'combo', choices: ['v4', 'v5', 'v6', 'next'], value: 'next', description: 'Specify which version of capstone to use') option('use_sys_magic', type: 'feature', value: 'disabled') option('use_sys_zydis', type: 'feature', value: 'disabled') option('use_sys_libzip', type: 'feature', value: 'disabled') diff --git a/subprojects/capstone-capstone-riscv-updated.wrap b/subprojects/capstone-capstone-riscv-updated.wrap deleted file mode 100644 index a4f2a1973f4..00000000000 --- a/subprojects/capstone-capstone-riscv-updated.wrap +++ /dev/null @@ -1,6 +0,0 @@ -[wrap-git] -url = https://github.com/moste00/capstone.git -revision = refactor_riscv_autosync -directory = capstone-riscv-updated -patch_directory = capstone-riscv-updated -depth = 1 diff --git a/subprojects/capstone-next.wrap b/subprojects/capstone-next.wrap index 031898b341a..6fc9a8649e4 100644 --- a/subprojects/capstone-next.wrap +++ b/subprojects/capstone-next.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://github.com/capstone-engine/capstone.git -revision = b3bd2f55d862e1d759782007ff81274295561e73 +revision = 3533a9c8d0713eac0d39532d91f6c7acfa23b3d6 directory = capstone-next patch_directory = capstone-next depth = 1 diff --git a/subprojects/capstone-v6.wrap b/subprojects/capstone-v6.wrap index 9b4a1673752..7fe0caa1f3f 100644 --- a/subprojects/capstone-v6.wrap +++ b/subprojects/capstone-v6.wrap @@ -1,6 +1,6 @@ [wrap-file] -source_url = https://github.com/capstone-engine/capstone/releases/download/6.0.0-Alpha6/capstone-6.0.0-Alpha6.tar.xz -source_filename = capstone-6.0.0-Alpha6.tar.xz -source_hash = 8ad244c35508b28d6c0751e3610a25380f34ddd892c968212794ed6a90d8e3cb -directory = capstone-6.0.0-Alpha6 -patch_directory = capstone-6.0.0-alpha6 +source_url = https://github.com/capstone-engine/capstone/releases/download/6.0.0-Alpha7/capstone-6.0.0-Alpha7.tar.xz +source_filename = capstone-6.0.0-Alpha7.tar.xz +source_hash = 6864bf6cff06f2698fd30854cc2097b6d41cd10b5454be67e8b56ad0cfc686ec +directory = capstone-6.0.0-Alpha7 +patch_directory = capstone-6.0.0-alpha7 diff --git a/subprojects/packagefiles/capstone-6.0.0-alpha6/meson.build b/subprojects/packagefiles/capstone-6.0.0-alpha6/meson.build deleted file mode 100644 index a6f0fddc93c..00000000000 --- a/subprojects/packagefiles/capstone-6.0.0-alpha6/meson.build +++ /dev/null @@ -1,141 +0,0 @@ -project('capstone', 'c', - version: 'next', - meson_version: '>=0.55.0', -) - -cc = meson.get_compiler('c') - -if cc.has_argument('--std=gnu99') - add_project_arguments('--std=gnu99', language: ['c']) -elif cc.has_argument('--std=c99') - add_project_arguments('--std=c99', language: ['c']) -endif - -cs_files = [ - 'arch/Alpha/AlphaDisassembler.c', - 'arch/Alpha/AlphaInstPrinter.c', - 'arch/Alpha/AlphaMapping.c', - 'arch/Alpha/AlphaModule.c', - 'arch/ARC/ARCDisassembler.c', - 'arch/ARC/ARCInstPrinter.c', - 'arch/ARC/ARCMapping.c', - 'arch/ARC/ARCModule.c', - 'arch/AArch64/AArch64BaseInfo.c', - 'arch/AArch64/AArch64Disassembler.c', - 'arch/AArch64/AArch64DisassemblerExtension.c', - 'arch/AArch64/AArch64InstPrinter.c', - 'arch/AArch64/AArch64Mapping.c', - 'arch/AArch64/AArch64Module.c', - 'arch/ARM/ARMBaseInfo.c', - 'arch/ARM/ARMDisassembler.c', - 'arch/ARM/ARMDisassemblerExtension.c', - 'arch/ARM/ARMInstPrinter.c', - 'arch/ARM/ARMMapping.c', - 'arch/ARM/ARMModule.c', - 'arch/HPPA/HPPADisassembler.c', - 'arch/HPPA/HPPAInstPrinter.c', - 'arch/HPPA/HPPAMapping.c', - 'arch/HPPA/HPPAModule.c', - 'arch/LoongArch/LoongArchInstPrinter.c', - 'arch/LoongArch/LoongArchDisassembler.c', - 'arch/LoongArch/LoongArchMapping.c', - 'arch/LoongArch/LoongArchDisassemblerExtension.c', - 'arch/LoongArch/LoongArchModule.c', - 'arch/M680X/M680XDisassembler.c', - 'arch/M680X/M680XInstPrinter.c', - 'arch/M680X/M680XModule.c', - 'arch/M68K/M68KDisassembler.c', - 'arch/M68K/M68KInstPrinter.c', - 'arch/M68K/M68KModule.c', - 'arch/Mips/MipsDisassembler.c', - 'arch/Mips/MipsInstPrinter.c', - 'arch/Mips/MipsMapping.c', - 'arch/Mips/MipsModule.c', - 'arch/PowerPC/PPCDisassembler.c', - 'arch/PowerPC/PPCInstPrinter.c', - 'arch/PowerPC/PPCMapping.c', - 'arch/PowerPC/PPCModule.c', - 'arch/Sparc/SparcDisassembler.c', - 'arch/Sparc/SparcDisassemblerExtension.c', - 'arch/Sparc/SparcInstPrinter.c', - 'arch/Sparc/SparcMapping.c', - 'arch/Sparc/SparcModule.c', - 'arch/SystemZ/SystemZDisassemblerExtension.c', - 'arch/SystemZ/SystemZDisassembler.c', - 'arch/SystemZ/SystemZInstPrinter.c', - 'arch/SystemZ/SystemZMapping.c', - 'arch/SystemZ/SystemZMCTargetDesc.c', - 'arch/SystemZ/SystemZModule.c', - 'arch/TMS320C64x/TMS320C64xDisassembler.c', - 'arch/TMS320C64x/TMS320C64xInstPrinter.c', - 'arch/TMS320C64x/TMS320C64xMapping.c', - 'arch/TMS320C64x/TMS320C64xModule.c', - 'arch/X86/X86ATTInstPrinter.c', - 'arch/X86/X86Disassembler.c', - 'arch/X86/X86DisassemblerDecoder.c', - 'arch/X86/X86IntelInstPrinter.c', - 'arch/X86/X86Mapping.c', - 'arch/X86/X86Module.c', - 'arch/X86/X86InstPrinterCommon.c', - 'arch/XCore/XCoreDisassembler.c', - 'arch/XCore/XCoreInstPrinter.c', - 'arch/XCore/XCoreMapping.c', - 'arch/XCore/XCoreModule.c', - 'arch/TriCore/TriCoreDisassembler.c', - 'arch/TriCore/TriCoreInstPrinter.c', - 'arch/TriCore/TriCoreMapping.c', - 'arch/TriCore/TriCoreModule.c', - 'arch/Xtensa/XtensaDisassembler.c', - 'arch/Xtensa/XtensaInstPrinter.c', - 'arch/Xtensa/XtensaMapping.c', - 'arch/Xtensa/XtensaModule.c', - 'cs.c', - 'Mapping.c', - 'MCInst.c', - 'MCInstrDesc.c', - 'MCInstPrinter.c', - 'MCRegisterInfo.c', - 'SStream.c', - 'utils.c', -] - -capstone_includes = [include_directories('include'), include_directories('include/capstone')] - -libcapstone_c_args = [ - '-DCAPSTONE_X86_ATT_DISABLE_NO', - '-DCAPSTONE_X86_REDUCE_NO', - '-DCAPSTONE_USE_SYS_DYN_MEM', - '-DCAPSTONE_DIET_NO', - '-DCAPSTONE_HAS_AARCH64', - '-DCAPSTONE_HAS_ARC', - '-DCAPSTONE_HAS_ALPHA', - '-DCAPSTONE_HAS_ARM', - '-DCAPSTONE_HAS_HPPA', - '-DCAPSTONE_HAS_LOONGARCH', - '-DCAPSTONE_HAS_M680X', - '-DCAPSTONE_HAS_M68K', - '-DCAPSTONE_HAS_MIPS', - '-DCAPSTONE_HAS_POWERPC', - '-DCAPSTONE_HAS_SPARC', - '-DCAPSTONE_HAS_SYSTEMZ', - '-DCAPSTONE_HAS_TMS320C64X', - '-DCAPSTONE_HAS_TRICORE', - '-DCAPSTONE_HAS_X86', - '-DCAPSTONE_HAS_XCORE', - '-DCAPSTONE_HAS_XTENSA', -] - -if meson.get_compiler('c').has_argument('-Wmaybe-uninitialized') - libcapstone_c_args += '-Wno-maybe-uninitialized' -endif - -libcapstone = library('capstone', cs_files, - c_args: libcapstone_c_args, - include_directories: capstone_includes, - implicit_include_directories: false -) - -capstone_dep = declare_dependency( - link_with: libcapstone, - include_directories: capstone_includes -) diff --git a/subprojects/packagefiles/capstone-riscv-updated/meson.build b/subprojects/packagefiles/capstone-6.0.0-alpha7/meson.build similarity index 97% rename from subprojects/packagefiles/capstone-riscv-updated/meson.build rename to subprojects/packagefiles/capstone-6.0.0-alpha7/meson.build index 8f2cf2e02c6..47ce09660c6 100644 --- a/subprojects/packagefiles/capstone-riscv-updated/meson.build +++ b/subprojects/packagefiles/capstone-6.0.0-alpha7/meson.build @@ -1,5 +1,5 @@ project('capstone', 'c', - version: 'capstone-riscv-updated', + version: 'next', meson_version: '>=0.55.0', ) @@ -55,6 +55,12 @@ cs_files = [ 'arch/PowerPC/PPCInstPrinter.c', 'arch/PowerPC/PPCMapping.c', 'arch/PowerPC/PPCModule.c', + 'arch/RISCV/RISCVDisassembler.c', + 'arch/RISCV/RISCVDisassemblerExtension.c', + 'arch/RISCV/RISCVInstPrinter.c', + 'arch/RISCV/RISCVBaseInfo.c', + 'arch/RISCV/RISCVMapping.c', + 'arch/RISCV/RISCVModule.c', 'arch/Sparc/SparcDisassembler.c', 'arch/Sparc/SparcDisassemblerExtension.c', 'arch/Sparc/SparcInstPrinter.c', @@ -89,12 +95,6 @@ cs_files = [ 'arch/Xtensa/XtensaInstPrinter.c', 'arch/Xtensa/XtensaMapping.c', 'arch/Xtensa/XtensaModule.c', - 'arch/RISCV/RISCVBaseInfo.c', - 'arch/RISCV/RISCVDisassembler.c', - 'arch/RISCV/RISCVDisassemblerExtension.c', - 'arch/RISCV/RISCVInstPrinter.c', - 'arch/RISCV/RISCVMapping.c', - 'arch/RISCV/RISCVModule.c', 'cs.c', 'Mapping.c', 'MCInst.c', @@ -129,7 +129,7 @@ libcapstone_c_args = [ '-DCAPSTONE_HAS_X86', '-DCAPSTONE_HAS_XCORE', '-DCAPSTONE_HAS_XTENSA', - '-DCAPSTONE_HAS_RISCV' + '-DCAPSTONE_HAS_RISCV', ] if meson.get_compiler('c').has_argument('-Wmaybe-uninitialized') @@ -145,4 +145,4 @@ libcapstone = library('capstone', cs_files, capstone_dep = declare_dependency( link_with: libcapstone, include_directories: capstone_includes -) \ No newline at end of file +) diff --git a/sys/riscv_extension_parser_generator.py b/sys/riscv_extension_parser_generator.py index 121d303bb8f..97154b5464f 100644 --- a/sys/riscv_extension_parser_generator.py +++ b/sys/riscv_extension_parser_generator.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2024-2026 moste00 +# SPDX-License-Identifier: BSD-3-Clause + """ RISC-V Extension Trie-Based Parser Generator @@ -10,22 +13,26 @@ 5. Uses macros to reduce boilerplate """ +import sys +import os from typing import Dict, List, Optional, Tuple from dataclasses import dataclass + @dataclass class TrieNode: - children: Dict[str, 'TrieNode'] + children: Dict[str, "TrieNode"] enum_name: Optional[str] = None - + def __init__(self): self.children = {} self.enum_name = None + class Trie: def __init__(self): self.root = TrieNode() - + def insert(self, ext_name: str, enum_name: str): """Insert an extension name into the trie""" node = self.root @@ -34,16 +41,20 @@ def insert(self, ext_name: str, enum_name: str): node.children[char] = TrieNode() node = node.children[char] node.enum_name = enum_name - - def generate_ascii_tree(self, node: Optional[TrieNode] = None, - prefix: str = "", is_last: bool = True, - char: str = "ROOT") -> List[str]: + + def generate_ascii_tree( + self, + node: Optional[TrieNode] = None, + prefix: str = "", + is_last: bool = True, + char: str = "ROOT", + ) -> List[str]: """Generate ASCII tree representation""" if node is None: node = self.root - + lines = [] - + # Current node connector = "└── " if is_last else "├── " if char == "ROOT": @@ -53,60 +64,63 @@ def generate_ascii_tree(self, node: Optional[TrieNode] = None, if node.enum_name: line += f" [{node.enum_name}]" lines.append(line) - + # Children if node.children: sorted_children = sorted(node.children.items()) for i, (ch, child) in enumerate(sorted_children): - is_last_child = (i == len(sorted_children) - 1) - + is_last_child = i == len(sorted_children) - 1 + if char == "ROOT": child_prefix = "" else: extension = " " if is_last else "│ " child_prefix = prefix + extension - - lines.extend(self.generate_ascii_tree( - child, child_prefix, is_last_child, ch - )) - + + lines.extend( + self.generate_ascii_tree(child, child_prefix, is_last_child, ch) + ) + return lines + def parse_enum_definitions(enum_text: str) -> List[Tuple[str, str]]: """Parse enum definitions and extract extension names""" results = [] - - for line in enum_text.strip().split('\n'): + + for line in enum_text.strip().split("\n"): line = line.strip() - if not line or not line.startswith('RISCV_FeatureStdExt'): + if not line or not line.startswith("RISCV_FeatureStdExt"): continue - + # Remove trailing comma and split - enum_name = line.rstrip(',').split('=')[0].strip() - + enum_name = line.rstrip(",").split("=")[0].strip() + # Extract extension name (part after FeatureStdExt) - if 'FeatureStdExt' in enum_name: - ext_name = enum_name.split('FeatureStdExt')[1].lower() + if "FeatureStdExt" in enum_name: + ext_name = enum_name.split("FeatureStdExt")[1].lower() if ext_name: # Skip empty names results.append((ext_name, enum_name)) - + return results + +# pylint: disable=too-many-statements def generate_c_code(trie: Trie, extensions: List[Tuple[str, str]]) -> str: """Generate the complete C parsing function""" - + # Generate ASCII tree tree_lines = trie.generate_ascii_tree() tree_comment = "\n".join(f" * {line}" for line in tree_lines) - + # Generate function body code_lines = [] - + def generate_node_code(node: TrieNode, depth: int, path: str) -> List[str]: """Recursively generate parsing code for trie nodes""" lines = [] indent = " " * depth - + if not node.children: # Leaf node if node.enum_name: @@ -114,30 +128,30 @@ def generate_node_code(node: TrieNode, depth: int, path: str) -> List[str]: else: lines.append(f"{indent}STOP_WITHOUT_MATCH();") return lines - + # Non-leaf node - check if this is also a valid end point if node.enum_name: lines.append(f"{indent}STOP_WITH_MATCH({node.enum_name});") lines.append("") - + # Process children - add state comment only before branching sorted_children = sorted(node.children.items()) expected_chars = [c for c, _ in sorted_children] - expected_str = ''.join(expected_chars) - + expected_str = "".join(expected_chars) + lines.append(f"{indent}/* State: '{path}' expecting [{expected_str}] */") - + for i, (char, child) in enumerate(sorted_children): if i == 0: lines.append(f"{indent}if (*p == '{char}') {{") else: lines.append(f"{indent}}} else if (*p == '{char}') {{") - + lines.append(f"{indent} p++;") lines.extend(generate_node_code(child, depth + 1, path + char)) - + lines.append(f"{indent}}} else {{") - + # In the else branch, we have an unexpected character if node.enum_name: # There was a valid match at the previous state @@ -147,24 +161,28 @@ def generate_node_code(node: TrieNode, depth: int, path: str) -> List[str]: # No valid match at this point lines.append(f"{indent} /* Unexpected char at '{path}', no match */") lines.append(f"{indent} STOP_WITHOUT_MATCH();") - + lines.append(f"{indent}}}") - + return lines - + # Start with root's children if trie.root.children: code_lines.extend(generate_node_code(trie.root, 1, "")) code_lines.append("") code_lines.append(" /* Should not reach here */") code_lines.append(" STOP_WITHOUT_MATCH();") - + # Build the complete function - full_code = "/*\n" + full_code = "// SPDX-FileCopyrightText: 2024-2026 moste00 \n" + full_code += "// " + "SPDX" + "-License-Identifier: BSD-3-Clause" + full_code += "\n\n/*\n" full_code += " * \n \n *********************************************** AUTO-GENERATED CODE, DO NOT EDIT BY HAND! " full_code += " * *********************************************** \n \n" full_code += " * RISC-V Extension Parser Using a Trie trick\n" - full_code += " * Generated from arch/RISCV/RISCVGenSubtargetInfo.inc in Capstone sources \n" + full_code += ( + " * Generated from arch/RISCV/RISCVGenSubtargetInfo.inc in Capstone sources \n" + ) full_code += " * \n" full_code += " * This function parses a single RISC-V extension name and ORs the corresponding\n" full_code += " * feature flags with an accumulator 'mode'.\n" @@ -172,22 +190,48 @@ def generate_node_code(node: TrieNode, depth: int, path: str) -> List[str]: full_code += " * Trie Diagram:\n" full_code += tree_comment + "\n" full_code += " */\n\n" - - flags_defs = "\n".join([f"#define {member} {i} \n" for i, (_, member) in enumerate(extensions)]) + + flags_defs = "\n".join( + [f"#define {member} {i} \n" for i, (_, member) in enumerate(extensions)] + ) full_code += flags_defs full_code += "/* Parse result enum - indicates why parsing stopped */\n" full_code += "typedef enum {\n" - full_code += " RISCV_EXT_PARSE_END_OF_STRING, /* Stopped at '\\0' - valid extension found */\n" - full_code += " RISCV_EXT_PARSE_STOPPED_AT_NUMBER, /* Stopped at a digit - valid extension found */\n" - full_code += " RISCV_EXT_PARSE_STOPPED_AT_UNDERSCORE, /* Stopped at '_' - valid extension found */\n" - full_code += " RISCV_EXT_PARSE_STOPPED_AT_UNEXPECTED, /* Stopped at unexpected char - valid extension found */\n" - full_code += " RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING, /* Reached '\\0' - no valid extension */\n" - full_code += " RISCV_EXT_PARSE_NO_MATCH_NUMBER, /* Hit number - no valid extension at this point */\n" - full_code += " RISCV_EXT_PARSE_NO_MATCH_UNDERSCORE, /* Hit underscore - no valid extension at this point */\n" - full_code += " RISCV_EXT_PARSE_NO_MATCH_UNEXPECTED, /* Hit unexpected char - no valid extension */\n" + full_code += ( + " RISCV_EXT_PARSE_END_OF_STRING, " + "/* Stopped at '\\0' - valid extension found */\n" + ) + full_code += ( + " RISCV_EXT_PARSE_STOPPED_AT_NUMBER, " + "/* Stopped at a digit - valid extension found */\n" + ) + full_code += ( + " RISCV_EXT_PARSE_STOPPED_AT_UNDERSCORE, " + "/* Stopped at '_' - valid extension found */\n" + ) + full_code += ( + " RISCV_EXT_PARSE_STOPPED_AT_UNEXPECTED, " + "/* Stopped at unexpected char - valid extension found */\n" + ) + full_code += ( + " RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING, " + "/* Reached '\\0' - no valid extension */\n" + ) + full_code += ( + " RISCV_EXT_PARSE_NO_MATCH_NUMBER, " + "/* Hit number - no valid extension at this point */\n" + ) + full_code += ( + " RISCV_EXT_PARSE_NO_MATCH_UNDERSCORE, " + "/* Hit underscore - no valid extension at this point */\n" + ) + full_code += ( + " RISCV_EXT_PARSE_NO_MATCH_UNEXPECTED, " + "/* Hit unexpected char - no valid extension */\n" + ) full_code += "} riscv_extension_parse_result_t;\n\n" - + full_code += "/* Macro: Stop parsing with a matched extension */\n" full_code += "#ifndef MATCH_CALLBACK\n" full_code += "#define MATCH_CALLBACK(feature_enum)\n" @@ -211,7 +255,7 @@ def generate_node_code(node: TrieNode, depth: int, path: str) -> List[str]: full_code += " return RISCV_EXT_PARSE_STOPPED_AT_UNEXPECTED; \\\n" full_code += " } \\\n" full_code += " } while (0)\n\n" - + full_code += "/* Macro: Stop parsing without a match */\n" full_code += "#define STOP_WITHOUT_MATCH() \\\n" full_code += " do { \\\n" @@ -226,13 +270,22 @@ def generate_node_code(node: TrieNode, depth: int, path: str) -> List[str]: full_code += " return RISCV_EXT_PARSE_NO_MATCH_UNEXPECTED; \\\n" full_code += " } \\\n" full_code += " } while (0)\n\n" - + full_code += "/**\n" - full_code += " * Main parse routine: Try to consume a RISC-V extension name from the architecture string at a given position.\n" + full_code += ( + " * Main parse routine: Try to consume a RISC-V extension name " + "from the architecture string at a given position.\n" + ) full_code += " * \n" full_code += " * @param arch_str: The full architecture string\n" - full_code += " * @param idx: Pointer to current index (will be updated to show consumed length)\n" - full_code += " * @param mode: Pointer to the feature accumulator (will be ORed with the feature flag if extension found)\n" + full_code += ( + " * @param idx: Pointer to current index " + "(will be updated to show consumed length)\n" + ) + full_code += ( + " * @param mode: Pointer to the feature accumulator " + "(will be ORed with the feature flag if extension found)\n" + ) full_code += " * @return: Parse result indicating why parsing stopped and whether a match was found\n" full_code += " * \n" full_code += " * Stopping conditions:\n" @@ -250,7 +303,9 @@ def generate_node_code(node: TrieNode, depth: int, path: str) -> List[str]: full_code += "#define INIT_EXT_CALLBACKS()\n" full_code += "#endif\n\n" full_code += "static inline riscv_extension_parse_result_t\n" - full_code += "try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode)\n" + full_code += ( + "try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode)\n" + ) full_code += "{\n" full_code += " if (!ext_name || !idx || !mode) {\n" full_code += " return RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING;\n" @@ -262,42 +317,41 @@ def generate_node_code(node: TrieNode, depth: int, path: str) -> List[str]: full_code += " if (*p == '\\0') {\n" full_code += " return RISCV_EXT_PARSE_NO_MATCH_END_OF_STRING;\n" full_code += " }\n\n" - + full_code += "\n".join(code_lines) full_code += "\n}\n\n" - + full_code += "/* Cleanup macros */\n" full_code += "#undef STOP_WITH_MATCH\n" full_code += "#undef STOP_WITHOUT_MATCH\n\n" - + # Add example usage full_code += "/* Example usage:\n" full_code += " *\n" full_code += " * ut64 features = 0;\n" full_code += " * riscv_extension_parse_result_t result;\n" full_code += " * size_t idx = 0;\n" - full_code += " * const char *arch = \"i2p1_m2p0_zicsr\";\n" + full_code += ' * const char *arch = "i2p1_m2p0_zicsr";\n' full_code += " * \n" - full_code += " * // Parse \"i\" from \"i2p1_m2p0_zicsr\"\n" + full_code += ' * // Parse "i" from "i2p1_m2p0_zicsr"\n' full_code += " * result = try_consume_riscv_ext_from(arch, &idx, &features);\n" full_code += " * // idx is now 1, result is RISCV_EXT_PARSE_STOPPED_AT_NUMBER\n" full_code += " * \n" - full_code += " * // Skip version \"2p1_\" by setting idx = 5\n" + full_code += ' * // Skip version "2p1_" by setting idx = 5\n' full_code += " * idx = 5; // now at 'm'\n" full_code += " * result = try_consume_riscv_ext_from(arch, &idx, &features);\n" full_code += " * // idx is now 6, result is RISCV_EXT_PARSE_STOPPED_AT_NUMBER\n" full_code += " * \n" - full_code += " * // Skip version \"2p0_\" by setting idx = 10\n" + full_code += ' * // Skip version "2p0_" by setting idx = 10\n' full_code += " * idx = 10; // now at 'z'\n" full_code += " * result = try_consume_riscv_ext_from(arch, &idx, &features);\n" full_code += " * // idx is now 15, result is RISCV_EXT_PARSE_END_OF_STRING\n" full_code += " */\n" - + return full_code + def main(): - import sys - import os if len(sys.argv) < 3: print(f"Usage: {sys.argv[0]} ") @@ -310,8 +364,10 @@ def main(): print(f"Error: Input file {input_header} not found") sys.exit(1) - with open(input_header, 'r') as f: - enum_text = "\n".join([line for line in f if line.strip().startswith('RISCV_FeatureStdExt')]) + with open(input_header, "r", encoding="utf-8") as f: + enum_text = "\n".join( + [line for line in f if line.strip().startswith("RISCV_FeatureStdExt")] + ) # Parse enum definitions extensions = parse_enum_definitions(enum_text) @@ -326,10 +382,11 @@ def main(): # Generate C code c_code = generate_c_code(trie, extensions) - + # Output to file - with open(output_file, 'w') as f: + with open(output_file, "w", encoding="utf-8") as f: f.write(c_code) + if __name__ == "__main__": main() diff --git a/test/db/analysis/alpha b/test/db/analysis/alpha index b8f1141e445..ee3c3c0468e 100644 --- a/test/db/analysis/alpha +++ b/test/db/analysis/alpha @@ -51,7 +51,7 @@ opex: - type: "reg" value: "$2" - type: "imm" - value: 536982352 + value: 4831949648 jump: 0x12001b350 fail: 0x12001b340 cond: al diff --git a/test/db/analysis/riscv b/test/db/analysis/riscv index 3bed7d86532..05fe7cb83c6 100644 --- a/test/db/analysis/riscv +++ b/test/db/analysis/riscv @@ -278,7 +278,9 @@ nth paddr vaddr bind type size lib name 5 0x000004b0 0x000104b0 GLOBAL FUNC 0 imp.__libc_start_main ; CALL XREF from sym.test_aes64_instructions @ 0x10812 ;-- aes64ds: -/ loc._xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zknd1p0_zkne1p0_zknh1p0(); +/ loc._xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zknd1p0_zkne1p0_zknh1p0(int64_t arg1, int64_t arg2); +| ; arg int64_t arg1 @ a0 +| ; arg int64_t arg2 @ a1 | ; var int64_t var_30h @ stack - 0x30 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 @@ -288,8 +290,8 @@ nth paddr vaddr bind type size lib name | 0x00010584 06f4 sd ra, 0x28(sp) | 0x00010586 22f0 sd s0, 0x20(sp) | 0x00010588 0018 addi s0, sp, 0x30 -| 0x0001058a 233ca4fc sd a0, -0x28(s0) -| 0x0001058e 2338b4fc sd a1, -0x30(s0) +| 0x0001058a 233ca4fc sd a0, -0x28(s0) ; arg1 +| 0x0001058e 2338b4fc sd a1, -0x30(s0) ; arg2 | 0x00010592 833784fd ld a5, -0x28(s0) | 0x00010596 033704fd ld a4, -0x30(s0) | 0x0001059a b387e73a aes64ds a5, a5, a4 @@ -299,9 +301,11 @@ nth paddr vaddr bind type size lib name | 0x000105a8 a270 ld ra, 0x28(sp) | 0x000105aa 0274 ld s0, 0x20(sp) | 0x000105ac 4561 addi sp, sp, 0x30 -| 0x000105ae 8280 ret +\ 0x000105ae 8280 ret ; CALL XREF from sym.test_aes64_instructions @ 0x10822 -/ sym.aes64dsm(); +/ sym.aes64dsm(int64_t arg1, int64_t arg2); +| ; arg int64_t arg1 @ a0 +| ; arg int64_t arg2 @ a1 | ; var int64_t var_30h @ stack - 0x30 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 @@ -311,8 +315,8 @@ nth paddr vaddr bind type size lib name | 0x000105b2 06f4 sd ra, 0x28(sp) | 0x000105b4 22f0 sd s0, 0x20(sp) | 0x000105b6 0018 addi s0, sp, 0x30 -| 0x000105b8 233ca4fc sd a0, -0x28(s0) -| 0x000105bc 2338b4fc sd a1, -0x30(s0) +| 0x000105b8 233ca4fc sd a0, -0x28(s0) ; arg1 +| 0x000105bc 2338b4fc sd a1, -0x30(s0) ; arg2 | 0x000105c0 833784fd ld a5, -0x28(s0) | 0x000105c4 033704fd ld a4, -0x30(s0) | 0x000105c8 b387e73e aes64dsm a5, a5, a4 @@ -322,9 +326,11 @@ nth paddr vaddr bind type size lib name | 0x000105d6 a270 ld ra, 0x28(sp) | 0x000105d8 0274 ld s0, 0x20(sp) | 0x000105da 4561 addi sp, sp, 0x30 -| 0x000105dc 8280 ret +\ 0x000105dc 8280 ret ; CALL XREF from sym.test_aes64_instructions @ 0x10832 -/ sym.aes64es(); +/ sym.aes64es(int64_t arg1, int64_t arg2); +| ; arg int64_t arg1 @ a0 +| ; arg int64_t arg2 @ a1 | ; var int64_t var_30h @ stack - 0x30 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 @@ -334,8 +340,8 @@ nth paddr vaddr bind type size lib name | 0x000105e0 06f4 sd ra, 0x28(sp) | 0x000105e2 22f0 sd s0, 0x20(sp) | 0x000105e4 0018 addi s0, sp, 0x30 -| 0x000105e6 233ca4fc sd a0, -0x28(s0) -| 0x000105ea 2338b4fc sd a1, -0x30(s0) +| 0x000105e6 233ca4fc sd a0, -0x28(s0) ; arg1 +| 0x000105ea 2338b4fc sd a1, -0x30(s0) ; arg2 | 0x000105ee 833784fd ld a5, -0x28(s0) | 0x000105f2 033704fd ld a4, -0x30(s0) | 0x000105f6 b387e732 aes64es a5, a5, a4 @@ -345,9 +351,11 @@ nth paddr vaddr bind type size lib name | 0x00010604 a270 ld ra, 0x28(sp) | 0x00010606 0274 ld s0, 0x20(sp) | 0x00010608 4561 addi sp, sp, 0x30 -| 0x0001060a 8280 ret +\ 0x0001060a 8280 ret ; CALL XREF from sym.test_aes64_instructions @ 0x10842 -/ sym.aes64esm(); +/ sym.aes64esm(int64_t arg1, int64_t arg2); +| ; arg int64_t arg1 @ a0 +| ; arg int64_t arg2 @ a1 | ; var int64_t var_30h @ stack - 0x30 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 @@ -357,8 +365,8 @@ nth paddr vaddr bind type size lib name | 0x0001060e 06f4 sd ra, 0x28(sp) | 0x00010610 22f0 sd s0, 0x20(sp) | 0x00010612 0018 addi s0, sp, 0x30 -| 0x00010614 233ca4fc sd a0, -0x28(s0) -| 0x00010618 2338b4fc sd a1, -0x30(s0) +| 0x00010614 233ca4fc sd a0, -0x28(s0) ; arg1 +| 0x00010618 2338b4fc sd a1, -0x30(s0) ; arg2 | 0x0001061c 833784fd ld a5, -0x28(s0) | 0x00010620 033704fd ld a4, -0x30(s0) | 0x00010624 b387e736 aes64esm a5, a5, a4 @@ -368,9 +376,10 @@ nth paddr vaddr bind type size lib name | 0x00010632 a270 ld ra, 0x28(sp) | 0x00010634 0274 ld s0, 0x20(sp) | 0x00010636 4561 addi sp, sp, 0x30 -| 0x00010638 8280 ret +\ 0x00010638 8280 ret ; CALL XREF from sym.test_aes64_instructions @ 0x1084e -/ sym.aes64im(); +/ sym.aes64im(int64_t arg1); +| ; arg int64_t arg1 @ a0 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 | ; var int64_t var_10h @ stack - 0x10 @@ -379,7 +388,7 @@ nth paddr vaddr bind type size lib name | 0x0001063c 06f4 sd ra, 0x28(sp) | 0x0001063e 22f0 sd s0, 0x20(sp) | 0x00010640 0018 addi s0, sp, 0x30 -| 0x00010642 233ca4fc sd a0, -0x28(s0) +| 0x00010642 233ca4fc sd a0, -0x28(s0) ; arg1 | 0x00010646 833784fd ld a5, -0x28(s0) | 0x0001064a 93970730 aes64im a5, a5 | 0x0001064e 2334f4fe sd a5, -0x18(s0) @@ -388,9 +397,11 @@ nth paddr vaddr bind type size lib name | 0x00010658 a270 ld ra, 0x28(sp) | 0x0001065a 0274 ld s0, 0x20(sp) | 0x0001065c 4561 addi sp, sp, 0x30 -| 0x0001065e 8280 ret +\ 0x0001065e 8280 ret ; CALL XREF from sym.test_aes64_instructions @ 0x1087a -/ sym.aes64ks2(); +/ sym.aes64ks2(int64_t arg1, int64_t arg2); +| ; arg int64_t arg1 @ a0 +| ; arg int64_t arg2 @ a1 | ; var int64_t var_30h @ stack - 0x30 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 @@ -400,8 +411,8 @@ nth paddr vaddr bind type size lib name | 0x00010662 06f4 sd ra, 0x28(sp) | 0x00010664 22f0 sd s0, 0x20(sp) | 0x00010666 0018 addi s0, sp, 0x30 -| 0x00010668 233ca4fc sd a0, -0x28(s0) -| 0x0001066c 2338b4fc sd a1, -0x30(s0) +| 0x00010668 233ca4fc sd a0, -0x28(s0) ; arg1 +| 0x0001066c 2338b4fc sd a1, -0x30(s0) ; arg2 | 0x00010670 833784fd ld a5, -0x28(s0) | 0x00010674 033704fd ld a4, -0x30(s0) | 0x00010678 b387e77e aes64ks2 a5, a5, a4 @@ -411,9 +422,10 @@ nth paddr vaddr bind type size lib name | 0x00010686 a270 ld ra, 0x28(sp) | 0x00010688 0274 ld s0, 0x20(sp) | 0x0001068a 4561 addi sp, sp, 0x30 -| 0x0001068c 8280 ret +\ 0x0001068c 8280 ret ; CALL XREF from sym.test_sha256_instructions @ 0x108bc -/ sym.sha256sig0(); +/ sym.sha256sig0(int64_t arg1); +| ; arg int64_t arg1 @ a0 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 | ; var int64_t var_10h @ stack - 0x10 @@ -422,7 +434,7 @@ nth paddr vaddr bind type size lib name | 0x00010690 06f4 sd ra, 0x28(sp) | 0x00010692 22f0 sd s0, 0x20(sp) | 0x00010694 0018 addi s0, sp, 0x30 -| 0x00010696 233ca4fc sd a0, -0x28(s0) +| 0x00010696 233ca4fc sd a0, -0x28(s0) ; arg1 | 0x0001069a 833784fd ld a5, -0x28(s0) | 0x0001069e 93972710 sha256sig0 a5, a5 | 0x000106a2 2334f4fe sd a5, -0x18(s0) @@ -431,9 +443,10 @@ nth paddr vaddr bind type size lib name | 0x000106ac a270 ld ra, 0x28(sp) | 0x000106ae 0274 ld s0, 0x20(sp) | 0x000106b0 4561 addi sp, sp, 0x30 -| 0x000106b2 8280 ret +\ 0x000106b2 8280 ret ; CALL XREF from sym.test_sha256_instructions @ 0x108d6 -/ sym.sha256sig1(); +/ sym.sha256sig1(int64_t arg1); +| ; arg int64_t arg1 @ a0 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 | ; var int64_t var_10h @ stack - 0x10 @@ -442,7 +455,7 @@ nth paddr vaddr bind type size lib name | 0x000106b6 06f4 sd ra, 0x28(sp) | 0x000106b8 22f0 sd s0, 0x20(sp) | 0x000106ba 0018 addi s0, sp, 0x30 -| 0x000106bc 233ca4fc sd a0, -0x28(s0) +| 0x000106bc 233ca4fc sd a0, -0x28(s0) ; arg1 | 0x000106c0 833784fd ld a5, -0x28(s0) | 0x000106c4 93973710 sha256sig1 a5, a5 | 0x000106c8 2334f4fe sd a5, -0x18(s0) @@ -451,9 +464,10 @@ nth paddr vaddr bind type size lib name | 0x000106d2 a270 ld ra, 0x28(sp) | 0x000106d4 0274 ld s0, 0x20(sp) | 0x000106d6 4561 addi sp, sp, 0x30 -| 0x000106d8 8280 ret +\ 0x000106d8 8280 ret ; CALL XREF from sym.test_sha256_instructions @ 0x108f0 -/ sym.sha256sum0(); +/ sym.sha256sum0(int64_t arg1); +| ; arg int64_t arg1 @ a0 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 | ; var int64_t var_10h @ stack - 0x10 @@ -462,7 +476,7 @@ nth paddr vaddr bind type size lib name | 0x000106dc 06f4 sd ra, 0x28(sp) | 0x000106de 22f0 sd s0, 0x20(sp) | 0x000106e0 0018 addi s0, sp, 0x30 -| 0x000106e2 233ca4fc sd a0, -0x28(s0) +| 0x000106e2 233ca4fc sd a0, -0x28(s0) ; arg1 | 0x000106e6 833784fd ld a5, -0x28(s0) | 0x000106ea 93970710 sha256sum0 a5, a5 | 0x000106ee 2334f4fe sd a5, -0x18(s0) @@ -471,9 +485,10 @@ nth paddr vaddr bind type size lib name | 0x000106f8 a270 ld ra, 0x28(sp) | 0x000106fa 0274 ld s0, 0x20(sp) | 0x000106fc 4561 addi sp, sp, 0x30 -| 0x000106fe 8280 ret +\ 0x000106fe 8280 ret ; CALL XREF from sym.test_sha256_instructions @ 0x1090a -/ sym.sha256sum1(); +/ sym.sha256sum1(int64_t arg1); +| ; arg int64_t arg1 @ a0 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 | ; var int64_t var_10h @ stack - 0x10 @@ -482,7 +497,7 @@ nth paddr vaddr bind type size lib name | 0x00010702 06f4 sd ra, 0x28(sp) | 0x00010704 22f0 sd s0, 0x20(sp) | 0x00010706 0018 addi s0, sp, 0x30 -| 0x00010708 233ca4fc sd a0, -0x28(s0) +| 0x00010708 233ca4fc sd a0, -0x28(s0) ; arg1 | 0x0001070c 833784fd ld a5, -0x28(s0) | 0x00010710 93971710 sha256sum1 a5, a5 | 0x00010714 2334f4fe sd a5, -0x18(s0) @@ -491,9 +506,10 @@ nth paddr vaddr bind type size lib name | 0x0001071e a270 ld ra, 0x28(sp) | 0x00010720 0274 ld s0, 0x20(sp) | 0x00010722 4561 addi sp, sp, 0x30 -| 0x00010724 8280 ret +\ 0x00010724 8280 ret ; CALL XREF from sym.test_sha512_instructions @ 0x1094a -/ sym.sha512sig0(); +/ sym.sha512sig0(int64_t arg1); +| ; arg int64_t arg1 @ a0 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 | ; var int64_t var_10h @ stack - 0x10 @@ -502,7 +518,7 @@ nth paddr vaddr bind type size lib name | 0x00010728 06f4 sd ra, 0x28(sp) | 0x0001072a 22f0 sd s0, 0x20(sp) | 0x0001072c 0018 addi s0, sp, 0x30 -| 0x0001072e 233ca4fc sd a0, -0x28(s0) +| 0x0001072e 233ca4fc sd a0, -0x28(s0) ; arg1 | 0x00010732 833784fd ld a5, -0x28(s0) | 0x00010736 93976710 sha512sig0 a5, a5 | 0x0001073a 2334f4fe sd a5, -0x18(s0) @@ -511,9 +527,10 @@ nth paddr vaddr bind type size lib name | 0x00010744 a270 ld ra, 0x28(sp) | 0x00010746 0274 ld s0, 0x20(sp) | 0x00010748 4561 addi sp, sp, 0x30 -| 0x0001074a 8280 ret +\ 0x0001074a 8280 ret ; CALL XREF from sym.test_sha512_instructions @ 0x10964 -/ sym.sha512sig1(); +/ sym.sha512sig1(int64_t arg1); +| ; arg int64_t arg1 @ a0 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 | ; var int64_t var_10h @ stack - 0x10 @@ -522,7 +539,7 @@ nth paddr vaddr bind type size lib name | 0x0001074e 06f4 sd ra, 0x28(sp) | 0x00010750 22f0 sd s0, 0x20(sp) | 0x00010752 0018 addi s0, sp, 0x30 -| 0x00010754 233ca4fc sd a0, -0x28(s0) +| 0x00010754 233ca4fc sd a0, -0x28(s0) ; arg1 | 0x00010758 833784fd ld a5, -0x28(s0) | 0x0001075c 93977710 sha512sig1 a5, a5 | 0x00010760 2334f4fe sd a5, -0x18(s0) @@ -531,9 +548,10 @@ nth paddr vaddr bind type size lib name | 0x0001076a a270 ld ra, 0x28(sp) | 0x0001076c 0274 ld s0, 0x20(sp) | 0x0001076e 4561 addi sp, sp, 0x30 -| 0x00010770 8280 ret +\ 0x00010770 8280 ret ; CALL XREF from sym.test_sha512_instructions @ 0x1097e -/ sym.sha512sum0(); +/ sym.sha512sum0(int64_t arg1); +| ; arg int64_t arg1 @ a0 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 | ; var int64_t var_10h @ stack - 0x10 @@ -542,7 +560,7 @@ nth paddr vaddr bind type size lib name | 0x00010774 06f4 sd ra, 0x28(sp) | 0x00010776 22f0 sd s0, 0x20(sp) | 0x00010778 0018 addi s0, sp, 0x30 -| 0x0001077a 233ca4fc sd a0, -0x28(s0) +| 0x0001077a 233ca4fc sd a0, -0x28(s0) ; arg1 | 0x0001077e 833784fd ld a5, -0x28(s0) | 0x00010782 93974710 sha512sum0 a5, a5 | 0x00010786 2334f4fe sd a5, -0x18(s0) @@ -551,9 +569,10 @@ nth paddr vaddr bind type size lib name | 0x00010790 a270 ld ra, 0x28(sp) | 0x00010792 0274 ld s0, 0x20(sp) | 0x00010794 4561 addi sp, sp, 0x30 -| 0x00010796 8280 ret +\ 0x00010796 8280 ret ; CALL XREF from sym.test_sha512_instructions @ 0x10998 -/ sym.sha512sum1(); +/ sym.sha512sum1(int64_t arg1); +| ; arg int64_t arg1 @ a0 | ; var int64_t var_28h @ stack - 0x28 | ; var int64_t var_18h @ stack - 0x18 | ; var int64_t var_10h @ stack - 0x10 @@ -562,7 +581,7 @@ nth paddr vaddr bind type size lib name | 0x0001079a 06f4 sd ra, 0x28(sp) | 0x0001079c 22f0 sd s0, 0x20(sp) | 0x0001079e 0018 addi s0, sp, 0x30 -| 0x000107a0 233ca4fc sd a0, -0x28(s0) +| 0x000107a0 233ca4fc sd a0, -0x28(s0) ; arg1 | 0x000107a4 833784fd ld a5, -0x28(s0) | 0x000107a8 93975710 sha512sum1 a5, a5 | 0x000107ac 2334f4fe sd a5, -0x18(s0) @@ -571,7 +590,7 @@ nth paddr vaddr bind type size lib name | 0x000107b6 a270 ld ra, 0x28(sp) | 0x000107b8 0274 ld s0, 0x20(sp) | 0x000107ba 4561 addi sp, sp, 0x30 -| 0x000107bc 8280 ret +\ 0x000107bc 8280 ret ; CALL XREF from main @ 0x109e8 / sym.test_aes64_instructions(int64_t arg6); | ; arg int64_t arg6 @ a5 @@ -588,13 +607,13 @@ nth paddr vaddr bind type size lib name | 0x000107e0 8000 addi s0, sp, 0x40 | 0x000107e2 c567 lui a5, 0x11 | 0x000107e4 83b707c3 ld a5, -0x3d0(a5) ; arg6 -| 0x000107e8 2334f4fe sd a5, -0x18(s0) +| 0x000107e8 2334f4fe sd a5, -0x18(s0) ; arg6 | 0x000107ec c567 lui a5, 0x11 | 0x000107ee 83b787c3 ld a5, -0x3c8(a5) ; arg6 -| 0x000107f2 2330f4fe sd a5, -0x20(s0) +| 0x000107f2 2330f4fe sd a5, -0x20(s0) ; arg6 | 0x000107f6 c567 lui a5, 0x11 | 0x000107f8 83b707c4 ld a5, -0x3c0(a5) ; arg6 -| 0x000107fc 233cf4fc sd a5, -0x28(s0) +| 0x000107fc 233cf4fc sd a5, -0x28(s0) ; arg6 | 0x00010800 c567 lui a5, 0x11 | 0x00010802 138587a5 addi a0, a5, -0x5a8 ; arg6 | 0x00010806 eff0bfcc jal sym.imp.puts ; int puts(const char *s) @@ -636,7 +655,7 @@ nth paddr vaddr bind type size lib name | 0x00010892 e270 ld ra, 0x38(sp) | 0x00010894 4274 ld s0, 0x30(sp) | 0x00010896 2161 addi sp, sp, 0x40 -| 0x00010898 8280 ret +\ 0x00010898 8280 ret EOF RUN @@ -1152,7 +1171,7 @@ EXPECT=< 0x000116f0 6383d704 beq a5, a3, 0x11736 -| | ||| 0x000116f4 3b880601 addw a6, a3, a6 -| | ||| 0x000116f8 bb8ede40 subw t4, t4, a3 -| | `---> 0x000116fc 9b86feff addiw a3, t4, -1 -| | || 0x00011700 1387f57f addi a4, a1, 0x7ff ; arg2 -| | || 0x00011704 0a08 slli a6, a6, 2 -| | || 0x00011706 1307977f addi a4, a4, 0x7f9 -| | || 0x0001170a 13960602 slli a2, a3, 0x20 -| | || 0x0001170e 9387f57f addi a5, a1, 0x7ff ; arg2 -| | || 0x00011712 9356e601 srli a3, a2, 0x1e -| | || 0x00011716 33070741 sub a4, a4, a6 -| | || 0x0001171a 9387d77f addi a5, a5, 0x7fd -| | || 0x0001171e 4295 add a0, a0, a6 ; arg1 -| | || 0x00011720 158f sub a4, a4, a3 -| | || 0x00011722 b3870741 sub a5, a5, a6 -| | .---> 0x00011726 87270500 flw fa5, 0(a0) ; arg1 -| | :|| 0x0001172a f117 addi a5, a5, -4 -| | :|| 0x0001172c 1105 addi a0, a0, 4 ; arg1 -| | :|| 0x0001172e 27a2f700 fsw fa5, 4(a5) -| | `===< 0x00011732 e31af7fe bne a4, a5, 0x11726 -| `--`--> 0x00011736 8280 ret -| `-> 0x00011738 8147 li a5, 0 -| 0x0001173a 930e0040 li t4, 0x400 -| 0x0001173e 0148 li a6, 0 -| 0x00011740 3db7 j 0x1166e +| .---> 0x0001166e 732320c2 csrr t1, vlenb +| :|| 0x00011672 93563300 srli a3, t1, 3 +| :|| 0x00011676 9388f6ff addi a7, a3, -1 +| :|| 0x0001167a 1307f03f li a4, 0x3ff +| :|| 0x0001167e 1b860800 sext.w a2, a7 +| :|| 0x00011682 1d9f subw a4, a4, a5 +| ,====< 0x00011684 636cc706 bltu a4, a2, 0x116fc +| |:|| 0x00011688 13970702 slli a4, a5, 0x20 +| |:|| 0x0001168c 135ee701 srli t3, a4, 0x1e +| |:|| 0x00011690 5776700d vsetvli a2, zero, e0x20, mf2, ta, ma +| |:|| 0x00011694 330fc501 add t5, a0, t3 ; arg1 +| |:|| 0x00011698 87610f02 vle32.v v3, (t5) +| |:|| 0x0001169c d7a00852 vid.v v1 +| |:|| 0x000116a0 935f1300 srli t6, t1, 1 +| |:|| 0x000116a4 d7c0180e vrsub.vx v1, v1, a7 +| |:|| 0x000116a8 0567 lui a4, 1 +| |:|| 0x000116aa 3307f741 sub a4, a4, t6 +| |:|| 0x000116ae 57813032 vrgather.vv v2, v3, v1 +| |:|| 0x000116b2 3307c741 sub a4, a4, t3 +| |:|| 0x000116b6 2e97 add a4, a4, a1 ; arg2 +| |:|| 0x000116b8 27610702 vse32.v v2, (a4) +| |:|| 0x000116bc b308d040 neg a7, a3 +| |:|| 0x000116c0 93880840 addi a7, a7, 0x400 +| |:|| 0x000116c4 bb88f840 subw a7, a7, a5 +| |:|| 0x000116c8 130e0040 li t3, 0x400 +| |:|| 0x000116cc 8126 sext.w a3, a3 +| |:|| 0x000116ce bb07fe40 subw a5, t3, a5 +| ,=====< 0x000116d2 63efd800 bltu a7, a3, 0x116f0 +| ||:|| 0x000116d6 7e9f add t5, t5, t6 +| ||:|| 0x000116d8 87610f02 vle32.v v3, (t5) +| ||:|| 0x000116dc 3307f741 sub a4, a4, t6 +| ||:|| 0x000116e0 13532300 srli t1, t1, 2 +| ||:|| 0x000116e4 9b060300 sext.w a3, t1 +| ||:|| 0x000116e8 57813032 vrgather.vv v2, v3, v1 +| ||:|| 0x000116ec 27610702 vse32.v v2, (a4) +| ,`-----> 0x000116f0 6383d704 beq a5, a3, 0x11736 +| | |:|| 0x000116f4 3b880601 addw a6, a3, a6 +| | |:|| 0x000116f8 bb8ede40 subw t4, t4, a3 +| | `----> 0x000116fc 9b86feff addiw a3, t4, -1 +| | :|| 0x00011700 1387f57f addi a4, a1, 0x7ff ; arg2 +| | :|| 0x00011704 0a08 slli a6, a6, 2 +| | :|| 0x00011706 1307977f addi a4, a4, 0x7f9 +| | :|| 0x0001170a 13960602 slli a2, a3, 0x20 +| | :|| 0x0001170e 9387f57f addi a5, a1, 0x7ff ; arg2 +| | :|| 0x00011712 9356e601 srli a3, a2, 0x1e +| | :|| 0x00011716 33070741 sub a4, a4, a6 +| | :|| 0x0001171a 9387d77f addi a5, a5, 0x7fd +| | :|| 0x0001171e 4295 add a0, a0, a6 ; arg1 +| | :|| 0x00011720 158f sub a4, a4, a3 +| | :|| 0x00011722 b3870741 sub a5, a5, a6 +| | .----> 0x00011726 87270500 flw fa5, 0(a0) ; arg1 +| | ::|| 0x0001172a f117 addi a5, a5, -4 +| | ::|| 0x0001172c 1105 addi a0, a0, 4 ; arg1 +| | ::|| 0x0001172e 27a2f700 fsw fa5, 4(a5) +| | `====< 0x00011732 e31af7fe bne a4, a5, 0x11726 +| `---`--> 0x00011736 8280 ret +| : `-> 0x00011738 8147 li a5, 0 +| : 0x0001173a 930e0040 li t4, 0x400 +| : 0x0001173e 0148 li a6, 0 +\ `===< 0x00011740 3db7 j 0x1166e EOF RUN @@ -2154,7 +2173,7 @@ EXPECT=< 0x08001032 li a0, 1 ; RELOC TARGET 0 .LBB0_2 @ 0x08001032 -| 0x08001034 ret +\ 0x08001034 ret nth paddr vaddr bind type size lib name -------------------------------------------------------------------- 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch_far.c @@ -392,7 +392,7 @@ EXPECT=< 0x0800103e li a0, 1 ; RELOC TARGET 0 .LBB0_2 @ 0x0800103e -| 0x08001040 ret +\ 0x08001040 ret nth paddr vaddr bind type size lib name -------------------------------------------------------------------- 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch_far.c @@ -536,7 +536,7 @@ EXPECT=< 0x08000132 li a0, 1 ; RELOC TARGET 0 .LBB0_2 @ 0x08000132 -| 0x08000134 ret +\ 0x08000134 ret nth paddr vaddr bind type size lib name ------------------------------------------------------------------------------- 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch_compressed_far.c @@ -862,7 +861,7 @@ EXPECT=< 0x0800013e li a0, 1 ; RELOC TARGET 0 .LBB0_2 @ 0x0800013e -| 0x08000140 ret +\ 0x08000140 ret nth paddr vaddr bind type size lib name ------------------------------------------------------------------------------- 1 ---------- 0x00000000 LOCAL FILE 0 riscv_branch_compressed_far.c diff --git a/test/db/formats/zimg b/test/db/formats/zimg index bbefe6a829c..b57e263e447 100644 --- a/test/db/formats/zimg +++ b/test/db/formats/zimg @@ -276,4 +276,5 @@ zImage: 0x00000028 0x0000000000000000 0x0000005643534952 ........RISCV... 0x00000038 0x0000000005435352 0x1440107310401073 RSC.....s.@.s.@. EOF +BROKEN=1 RUN diff --git a/test/unit/meson.build b/test/unit/meson.build index d0e940d9efe..1ce25c66d8a 100644 --- a/test/unit/meson.build +++ b/test/unit/meson.build @@ -19,7 +19,6 @@ if get_option('enable_tests') 'analysis_function', 'analysis_hints', 'analysis_meta', - 'analysis_op', 'analysis_var', 'analysis_xrefs', 'annotated_code', @@ -138,6 +137,10 @@ if get_option('enable_tests') 'yank', ] + if capstone_dep.type_name() == 'internal' + tests += 'analysis_op' + endif + unit_test_env = environment() if test_env_common_path != [] unit_test_env.prepend('PATH', test_env_common_path) diff --git a/test/unit/test_analysis_op.c b/test/unit/test_analysis_op.c index 6ddd920d1ab..beb236ad101 100644 --- a/test/unit/test_analysis_op.c +++ b/test/unit/test_analysis_op.c @@ -79,6 +79,7 @@ bool test_rz_analysis_op_val() { rz_analysis_op_fini(&op); SWITCH_TO_ARCH_BITS("riscv", 32); + rz_analysis_set_cpu(analysis, "rv32i2p0_c2p0"); // lw s10, 64(sp) rz_analysis_op_init(&op); len = rz_analysis_op(analysis, &op, 0, (const ut8 *)"\x06\x4d", 2, RZ_ANALYSIS_OP_MASK_VAL);