Skip to content
This repository was archived by the owner on Apr 13, 2019. It is now read-only.

Commit 0ffb846

Browse files
author
Michael Clark
committed
RISC-V - Disassemble reserved compressed encodings as illegal
- Due to the design of the disassembler, the immediate is not known during decoding of the opcode; so to handle compressed encodings with reserved immediate values (non-zero), we need to add an additional check during decompression to match reserved encodings with zero immediates and translate them into the illegal instruction. The following compressed opcodes have reserved encodings with zero immediates: c.addi4spn, c.addi, c.lui, c.addi16sp, c.srli, c.srai, c.andi and c.slli Signed-off-by: Michael Clark <[email protected]>
1 parent d621573 commit 0ffb846

File tree

1 file changed

+34
-17
lines changed

1 file changed

+34
-17
lines changed

disas/riscv.c

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -504,14 +504,19 @@ typedef struct {
504504
const rvc_constraint *constraints;
505505
} rv_comp_data;
506506

507+
enum {
508+
rvcd_imm_nz = 0x1
509+
};
510+
507511
typedef struct {
508512
const char * const name;
509513
const rv_codec codec;
510514
const char * const format;
511515
const rv_comp_data *pseudo;
512-
const int decomp_rv32;
513-
const int decomp_rv64;
514-
const int decomp_rv128;
516+
const short decomp_rv32;
517+
const short decomp_rv64;
518+
const short decomp_rv128;
519+
const short decomp_data;
515520
} rv_opcode_data;
516521

517522
/* register names */
@@ -1011,22 +1016,22 @@ const rv_opcode_data opcode_data[] = {
10111016
{ "fcvt.q.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
10121017
{ "fmv.x.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
10131018
{ "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
1014-
{ "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1019+
{ "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi, rvcd_imm_nz },
10151020
{ "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, 0 },
10161021
{ "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
10171022
{ "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
10181023
{ "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, 0 },
10191024
{ "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
10201025
{ "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
10211026
{ "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1022-
{ "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1027+
{ "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi, rvcd_imm_nz },
10231028
{ "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal, 0, 0 },
10241029
{ "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1025-
{ "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
1026-
{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, rv_op_lui },
1027-
{ "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli, rv_op_srli, rv_op_srli },
1028-
{ "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai, rv_op_srai, rv_op_srai },
1029-
{ "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, rv_op_andi, rv_op_andi },
1030+
{ "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi, rvcd_imm_nz },
1031+
{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, rv_op_lui, rvcd_imm_nz },
1032+
{ "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli, rv_op_srli, rv_op_srli, rvcd_imm_nz },
1033+
{ "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai, rv_op_srai, rv_op_srai, rvcd_imm_nz },
1034+
{ "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, rv_op_andi, rv_op_andi, rvcd_imm_nz },
10301035
{ "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, rv_op_sub },
10311036
{ "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, rv_op_xor },
10321037
{ "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, rv_op_or },
@@ -1036,7 +1041,7 @@ const rv_opcode_data opcode_data[] = {
10361041
{ "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, rv_op_jal },
10371042
{ "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq, rv_op_beq },
10381043
{ "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne, rv_op_bne },
1039-
{ "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, rv_op_slli, rv_op_slli },
1044+
{ "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, rv_op_slli, rv_op_slli, rvcd_imm_nz },
10401045
{ "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, rv_op_fld },
10411046
{ "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
10421047
{ "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
@@ -2795,26 +2800,38 @@ static void decode_inst_decompress_rv32(rv_decode *dec)
27952800
{
27962801
int decomp_op = opcode_data[dec->op].decomp_rv32;
27972802
if (decomp_op != rv_op_illegal) {
2798-
dec->op = decomp_op;
2799-
dec->codec = opcode_data[decomp_op].codec;
2803+
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz) && dec->imm == 0) {
2804+
dec->op = rv_op_illegal;
2805+
} else {
2806+
dec->op = decomp_op;
2807+
dec->codec = opcode_data[decomp_op].codec;
2808+
}
28002809
}
28012810
}
28022811

28032812
static void decode_inst_decompress_rv64(rv_decode *dec)
28042813
{
28052814
int decomp_op = opcode_data[dec->op].decomp_rv64;
28062815
if (decomp_op != rv_op_illegal) {
2807-
dec->op = decomp_op;
2808-
dec->codec = opcode_data[decomp_op].codec;
2816+
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz) && dec->imm == 0) {
2817+
dec->op = rv_op_illegal;
2818+
} else {
2819+
dec->op = decomp_op;
2820+
dec->codec = opcode_data[decomp_op].codec;
2821+
}
28092822
}
28102823
}
28112824

28122825
static void decode_inst_decompress_rv128(rv_decode *dec)
28132826
{
28142827
int decomp_op = opcode_data[dec->op].decomp_rv128;
28152828
if (decomp_op != rv_op_illegal) {
2816-
dec->op = decomp_op;
2817-
dec->codec = opcode_data[decomp_op].codec;
2829+
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz) && dec->imm == 0) {
2830+
dec->op = rv_op_illegal;
2831+
} else {
2832+
dec->op = decomp_op;
2833+
dec->codec = opcode_data[decomp_op].codec;
2834+
}
28182835
}
28192836
}
28202837

0 commit comments

Comments
 (0)