From 62f6a46a9149484308b574302e345352ba05648a Mon Sep 17 00:00:00 2001 From: wangyang Date: Tue, 11 Aug 2026 10:50:34 +0800 Subject: [PATCH 1/5] [#958] riscv: canonicalize malformed half operands for fclass.h --- arch/riscv/translate.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/riscv/translate.c b/arch/riscv/translate.c index b494feb9a..95fe57ef8 100644 --- a/arch/riscv/translate.c +++ b/arch/riscv/translate.c @@ -3662,7 +3662,10 @@ static void gen_fp_arith(DisasContext *dc, uint32_t opc, int rd, int rs1, int rs if(rm == 0x0) { /* FMV */ gen_helper_fmv_x_h(write_int_rd, cpu_env, cpu_fpr[rs1], rm_reg); } else if(rm == 0x1) { - gen_helper_fclass_h(write_int_rd, cpu_env, cpu_fpr[rs1]); + TCGv_i64 rs1_boxed = tcg_temp_local_new_i64(); + gen_unbox_float(RISCV_HALF_PRECISION, env, rs1_boxed, cpu_fpr[rs1]); + gen_helper_fclass_h(write_int_rd, cpu_env, rs1_boxed); + tcg_temp_free_i64(rs1_boxed); } else { kill_unknown(dc, RISCV_EXCP_ILLEGAL_INST); } From 5cf8ffb8043071b3801b720c4cc1a0a8fc23631b Mon Sep 17 00:00:00 2001 From: wangyang Date: Tue, 11 Aug 2026 10:50:35 +0800 Subject: [PATCH 2/5] [#959] riscv: accept dual-owner bitmanip instructions with either extension --- arch/riscv/translate.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/arch/riscv/translate.c b/arch/riscv/translate.c index 95fe57ef8..0abd622fa 100644 --- a/arch/riscv/translate.c +++ b/arch/riscv/translate.c @@ -215,6 +215,19 @@ static int ensure_additional_extension(DisasContext *dc, enum riscv_additional_f return 0; } +/* Dual-owner extension gate (e.g. Zbb / Zbkb both own ANDN, ROL, REV8, ...): + * succeed if either extension is enabled. ensure_additional_extension() + * raises the illegal-instruction exception on failure, so it must not be + * called for the first alternative before checking the second one. + */ +static int ensure_any_additional_extension(DisasContext *dc, enum riscv_additional_feature ext1, enum riscv_additional_feature ext2) +{ + if(riscv_has_additional_ext(cpu, ext1) || riscv_has_additional_ext(cpu, ext2)) { + return 1; + } + ensure_additional_extension(dc, ext1); + return 0; +} static int ensure_fp_extension(DisasContext *dc, int precision_bit) { switch((enum riscv_floating_point_precision)extract64(dc->opcode, precision_bit, 2)) { @@ -1117,21 +1130,21 @@ static void gen_arith(DisasContext *dc, uint32_t opc, int rd, int rs1, int rs2) tcg_gen_add_tl(source1, source1, source2); break; case OPC_RISC_ANDN: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } tcg_gen_not_tl(source2, source2); tcg_gen_and_tl(source1, source1, source2); break; case OPC_RISC_ORN: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } tcg_gen_not_tl(source2, source2); tcg_gen_or_tl(source1, source1, source2); break; case OPC_RISC_XNOR: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } tcg_gen_xor_tl(source1, source1, source2); @@ -1242,7 +1255,7 @@ static void gen_arith(DisasContext *dc, uint32_t opc, int rd, int rs1, int rs2) break; #endif case OPC_RISC_ROL: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } cond1 = tcg_temp_new(); @@ -1251,7 +1264,7 @@ static void gen_arith(DisasContext *dc, uint32_t opc, int rd, int rs1, int rs2) tcg_temp_free(cond1); break; case OPC_RISC_ROLW: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } cond1 = tcg_temp_new_i64(); @@ -1265,13 +1278,13 @@ static void gen_arith(DisasContext *dc, uint32_t opc, int rd, int rs1, int rs2) break; case OPC_RISC_ROR: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } tcg_gen_rotr_tl(source1, source1, source2); break; case OPC_RISC_RORW: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } cond1 = tcg_temp_new_i64(); @@ -1467,13 +1480,13 @@ static void gen_arith_bitmanip(DisasContext *dc, int rd, int rs1, target_long im tcg_gen_ext32s_i64(source1, source1); break; case OPC_RISC_RORI: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } tcg_gen_rotri_tl(source1, source1, (imm & BITMANIP_SHAMT_MASK)); break; case OPC_RISC_RORIW: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } t0 = tcg_temp_new_i64(); @@ -1491,13 +1504,13 @@ static void gen_arith_bitmanip(DisasContext *dc, int rd, int rs1, target_long im tcg_gen_shli_i64(source1, source1, (imm & BITMANIP_SHAMT_MASK)); break; case OPC_RISC_REV8_32: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } tcg_gen_bswap32_i32(source1, source1); break; case OPC_RISC_REV8_64: - if(!ensure_additional_extension(dc, RISCV_FEATURE_ZBB) && !ensure_additional_extension(dc, RISCV_FEATURE_ZBKB)) { + if(!ensure_any_additional_extension(dc, RISCV_FEATURE_ZBB, RISCV_FEATURE_ZBKB)) { return; } tcg_gen_bswap64_i64(source1, source1); From 93771ad095f75bfd293d17edd996556da3e7f789 Mon Sep 17 00:00:00 2001 From: wangyang Date: Tue, 11 Aug 2026 10:50:39 +0800 Subject: [PATCH 3/5] [#960] riscv: gate Zcb instructions on their required extensions --- arch/riscv/translate.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/riscv/translate.c b/arch/riscv/translate.c index 0abd622fa..5b87c0b59 100644 --- a/arch/riscv/translate.c +++ b/arch/riscv/translate.c @@ -6406,6 +6406,10 @@ static void decode_RV32_64C1(CPUState *env, DisasContext *dc) if(!ensure_additional_extension(dc, RISCV_FEATURE_ZCB)) { break; } + /* C.MUL additionally requires M or Zmmul. */ + if(!ensure_extension(dc, RISCV_FEATURE_RVM)) { + break; + } /* C.MUL -> mul rd', rd', rs2' */ gen_arith(dc, OPC_RISC_MUL, rs1s, rs1s, rs2s); break; @@ -6415,6 +6419,10 @@ static void decode_RV32_64C1(CPUState *env, DisasContext *dc) } /* C.ZEXT.B, C.SEXT.B, C.ZEXT.H, C.SEXT.H, C.ZEXT.W, C.NOT */ uint8_t c_op = extract32(dc->opcode, 2, 3); + if((c_op == 1 || c_op == 2 || c_op == 3) && + !ensure_additional_extension(dc, RISCV_FEATURE_ZBB)) { + break; + } switch(c_op) { case 0: From 8771636189aad64612b993aa2c1c1c2849b6a668 Mon Sep 17 00:00:00 2001 From: wangyang Date: Tue, 11 Aug 2026 10:50:42 +0800 Subject: [PATCH 4/5] [#961] riscv: reject scalar M instructions without the M extension --- arch/riscv/translate.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/riscv/translate.c b/arch/riscv/translate.c index 5b87c0b59..f4b1261a0 100644 --- a/arch/riscv/translate.c +++ b/arch/riscv/translate.c @@ -883,6 +883,29 @@ static void gen_arith(DisasContext *dc, uint32_t opc, int rd, int rs1, int rs2) { TCGv source1, source2, cond1, cond2, zeroreg, resultopt1; target_ulong mask; + switch(opc) { + case OPC_RISC_MUL: + case OPC_RISC_MULH: + case OPC_RISC_MULHSU: + case OPC_RISC_MULHU: + case OPC_RISC_DIV: + case OPC_RISC_DIVU: + case OPC_RISC_REM: + case OPC_RISC_REMU: +#if defined(TARGET_RISCV64) + case OPC_RISC_MULW: + case OPC_RISC_DIVW: + case OPC_RISC_DIVUW: + case OPC_RISC_REMW: + case OPC_RISC_REMUW: +#endif + if(!ensure_extension(dc, RISCV_FEATURE_RVM)) { + return; + } + break; + default: + break; + } source1 = tcg_temp_local_new(); source2 = tcg_temp_local_new(); gen_get_gpr(source1, rs1); From 9a85f18d9ab5b3b3262755b58dabf39db9f4054f Mon Sep 17 00:00:00 2001 From: wangyang Date: Tue, 11 Aug 2026 10:50:51 +0800 Subject: [PATCH 5/5] [#962] riscv: remove obsolete SFENCE.VM branch from gen_system --- arch/riscv/translate.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/riscv/translate.c b/arch/riscv/translate.c index f4b1261a0..4f8dc0e00 100644 --- a/arch/riscv/translate.c +++ b/arch/riscv/translate.c @@ -3757,9 +3757,6 @@ static void gen_system(DisasContext *dc, uint32_t opc, int rd, int rs1, int rs2, gen_exit_tb_no_chaining(dc->base.tb); dc->base.is_jmp = DISAS_BRANCH; break; - case 0x4: /* SFENCE.VM */ - gen_helper_tlb_flush(cpu_env); - break; case 0x5: /* WFI */ tcg_gen_movi_tl(cpu_pc, dc->npc); gen_helper_wfi(cpu_env);