@@ -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+
507511typedef 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
28032812static 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
28122825static 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