@samitouri / QOSamiQemu / commits / 67aba8e3ec

target/riscv: Fix size of vector CSRs

According to version 20250508 of the unprivileged specification: - vtype: bits 0..7 used, bit XLEN-1 illegal, rest reserved => fix to 64-bits. - vxsat: bit 0 used, vxrm which would occupy bits 1..2 is stored separately, and bits 3..31 are set to 0 => fix to 8-bits. - vxrm: 2 lowest bits are used for rounding mode, rest set to 0 => fix to 8-bits. - vstart: maximum value of VLMAX-1, where VLMAX is at most 2^16 => fix to 32-bits as vstart is mapped to a TCG global. - vl: maximum value of VLEN which is at most 2^16 => fix to 32-bits as vl is mapped to a TCG global. Fields are shuffled for reduced padding. Note, the cpu/vector VMSTATE version is bumped, breaking migration from older versions. Signed-off-by: Anton Johansson <anjo@rev.ng> Acked-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20260520125406.28693-3-anjo@rev.ng> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Anton Johansson committed May 20, 2026 at 14:53 UTC 67aba8e3ecf4b9d5958976079a6c28f80ac34cae
5 files changed +103 -82
target/riscv/cpu.h
+6 -6
@@ -193,7 +193,7 @@ FIELD(VTYPE, VSEW, 3, 3)
193 FIELD(VTYPE, VTA, 6, 1)
194 FIELD(VTYPE, VMA, 7, 1)
195 FIELD(VTYPE, ALTFMT, 8, 1)
196 -FIELD(VTYPE, RESERVED, 9, sizeof(target_ulong) * 8 - 10)
196 +FIELD(VTYPE, RESERVED, 9, sizeof(uint64_t) * 8 - 10)
197
198 typedef struct PMUCTRState {
199 /* Current value of a counter */
@@ -219,11 +219,11 @@ struct CPUArchState {
219
220 /* vector coprocessor state. */
221 uint64_t vreg[32 * RV_VLEN_MAX / 64] QEMU_ALIGNED(16);
222 - target_ulong vxrm;
223 - target_ulong vxsat;
224 - target_ulong vl;
225 - target_ulong vstart;
226 - target_ulong vtype;
222 + uint64_t vtype;
223 + uint32_t vl;
224 + uint32_t vstart;
225 + uint8_t vxrm;
226 + uint8_t vxsat;
227 bool vill;
228
229 target_ulong pc;
target/riscv/insn_trans/trans_rvv.c.inc
+11 -11
@@ -203,7 +203,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
203
204 if (rd == 0 && rs1 == 0) {
205 s1 = tcg_temp_new();
206 - tcg_gen_mov_tl(s1, cpu_vl);
206 + tcg_gen_ext_i32_tl(s1, cpu_vl);
207 } else if (rs1 == 0) {
208 /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
209 s1 = tcg_constant_tl(RV_VLEN_MAX);
@@ -1213,9 +1213,9 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
1213 tcg_gen_qemu_st_i64(t8, addr, s->mem_idx, MO_LEUQ | atomicity);
1214 }
1215 if (i == size - 8) {
1216 - tcg_gen_movi_tl(cpu_vstart, 0);
1216 + tcg_gen_movi_i32(cpu_vstart, 0);
1217 } else {
1218 - tcg_gen_addi_tl(cpu_vstart, cpu_vstart, 8 >> log2_esz);
1218 + tcg_gen_addi_i32(cpu_vstart, cpu_vstart, 8 >> log2_esz);
1219 }
1220 }
1221 } else {
@@ -2426,7 +2426,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
2426 s->cfg_ptr->vlenb, data, \
2427 (s->altfmt ? gen_helper_##BFA_HELPER : \
2428 fns[s->sew - 1])); \
2429 - tcg_gen_movi_tl(cpu_vstart, 0); \
2429 + tcg_gen_movi_i32(cpu_vstart, 0); \
2430 finalize_rvv_inst(s); \
2431 \
2432 return true; \
@@ -3641,7 +3641,7 @@ static bool trans_vmv_x_s(DisasContext *s, arg_vmv_x_s *a)
3641 vec_element_loadi(s, t1, a->rs2, 0, true);
3642 tcg_gen_trunc_i64_tl(dest, t1);
3643 gen_set_gpr(s, a->rd, dest);
3644 - tcg_gen_movi_tl(cpu_vstart, 0);
3644 + tcg_gen_movi_i32(cpu_vstart, 0);
3645 finalize_rvv_inst(s);
3646 return true;
3647 }
@@ -3658,7 +3658,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
3658 TCGv s1;
3659 TCGLabel *over = gen_new_label();
3660
3661 - tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
3661 + tcg_gen_brcond_i32(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
3662
3663 t1 = tcg_temp_new_i64();
3664
@@ -3670,7 +3670,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
3670 tcg_gen_ext_tl_i64(t1, s1);
3671 vec_element_storei_tail(s, a->rd, t1);
3672 gen_set_label(over);
3673 - tcg_gen_movi_tl(cpu_vstart, 0);
3673 + tcg_gen_movi_i32(cpu_vstart, 0);
3674 finalize_rvv_inst(s);
3675 return true;
3676 }
@@ -3698,7 +3698,7 @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
3698 }
3699
3700 mark_fs_dirty(s);
3701 - tcg_gen_movi_tl(cpu_vstart, 0);
3701 + tcg_gen_movi_i32(cpu_vstart, 0);
3702 finalize_rvv_inst(s);
3703 return true;
3704 }
@@ -3719,7 +3719,7 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
3719 TCGLabel *over = gen_new_label();
3720
3721 /* if vstart >= vl, skip vector register write back */
3722 - tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
3722 + tcg_gen_brcond_i32(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
3723
3724 /* NaN-box f[rs1] */
3725 t1 = tcg_temp_new_i64();
@@ -3728,7 +3728,7 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
3728 vec_element_storei_tail(s, a->rd, t1);
3729
3730 gen_set_label(over);
3731 - tcg_gen_movi_tl(cpu_vstart, 0);
3731 + tcg_gen_movi_i32(cpu_vstart, 0);
3732 finalize_rvv_inst(s);
3733 return true;
3734 }
@@ -3793,7 +3793,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
3793 \
3794 fns[s->sew](dest, mask, src1, src2, tcg_env, desc); \
3795 \
3796 - tcg_gen_movi_tl(cpu_vstart, 0); \
3796 + tcg_gen_movi_i32(cpu_vstart, 0); \
3797 finalize_rvv_inst(s); \
3798 \
3799 return true; \
target/riscv/machine.c
+7 -7
@@ -138,16 +138,16 @@ static bool vector_needed(void *opaque)
138
139 static const VMStateDescription vmstate_vector = {
140 .name = "cpu/vector",
141 - .version_id = 2,
142 - .minimum_version_id = 2,
141 + .version_id = 3,
142 + .minimum_version_id = 3,
143 .needed = vector_needed,
144 .fields = (const VMStateField[]) {
145 VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
146 - VMSTATE_UINTTL(env.vxrm, RISCVCPU),
147 - VMSTATE_UINTTL(env.vxsat, RISCVCPU),
148 - VMSTATE_UINTTL(env.vl, RISCVCPU),
149 - VMSTATE_UINTTL(env.vstart, RISCVCPU),
150 - VMSTATE_UINTTL(env.vtype, RISCVCPU),
146 + VMSTATE_UINT64(env.vtype, RISCVCPU),
147 + VMSTATE_UINT32(env.vl, RISCVCPU),
148 + VMSTATE_UINT32(env.vstart, RISCVCPU),
149 + VMSTATE_UINT8(env.vxrm, RISCVCPU),
150 + VMSTATE_UINT8(env.vxsat, RISCVCPU),
151 VMSTATE_BOOL(env.vill, RISCVCPU),
152 VMSTATE_END_OF_LIST()
153 }
target/riscv/translate.c
+8 -4
@@ -38,8 +38,9 @@
38 #include "tcg/tcg-cpu.h"
39
40 /* global register indices */
41 -static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
41 +static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc;
42 static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
43 +static TCGv_i32 cpu_vl, cpu_vstart;
44 static TCGv load_res;
45 static TCGv load_val;
46
@@ -1480,6 +1481,10 @@ void riscv_translate_init(void)
1481 size_t field_offset = 0;
1482 #endif
1483
1484 + /* 32 bits in size, no offset needed */
1485 + size_t vl_offset = offsetof(CPURISCVState, vl);
1486 + size_t vstart_offset = offsetof(CPURISCVState, vstart);
1487 +
1488 for (i = 1; i < 32; i++) {
1489 cpu_gpr[i] = tcg_global_mem_new(tcg_env,
1490 offsetof(CPURISCVState, gpr[i]) + field_offset,
@@ -1495,9 +1500,8 @@ void riscv_translate_init(void)
1500 }
1501
1502 cpu_pc = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, pc), "pc");
1498 - cpu_vl = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, vl), "vl");
1499 - cpu_vstart = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, vstart),
1500 - "vstart");
1503 + cpu_vl = tcg_global_mem_new_i32(tcg_env, vl_offset, "vl");
1504 + cpu_vstart = tcg_global_mem_new_i32(tcg_env, vstart_offset, "vstart");
1505 load_res = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, load_res),
1506 "load_res");
1507 load_val = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, load_val),
target/riscv/vector_helper.c
+71 -54
@@ -285,7 +285,7 @@ vext_continuous_ldst_host(CPURISCVState *env, vext_ldst_elem_fn_host *ldst_host,
285 }
286 }
287
288 -static void vext_set_tail_elems_1s(target_ulong vl, void *vd,
288 +static void vext_set_tail_elems_1s(uint32_t vl, void *vd,
289 uint32_t desc, uint32_t nf,
290 uint32_t esz, uint32_t max_elems)
291 {
@@ -388,6 +388,12 @@ vext_page_ldst_us(CPURISCVState *env, void *vd, target_ulong addr,
388 uint32_t evl = env->vstart + elems;
389 MMUAccessType access_type = is_load ? MMU_DATA_LOAD : MMU_DATA_STORE;
390
391 + /*
392 + * Maximum vector length is VLMAX == 2^16 == LMUL * VL / SEW, and
393 + * occurs for LMUL == 8, SEW == 8, VL == 2^16.
394 + */
395 + g_assert(env->vstart < UINT16_MAX && UINT16_MAX - env->vstart >= elems);
396 +
397 /* Check page permission/pmp/watchpoint/etc. */
398 probe_pages(env, addr, size, ra, access_type, mmu_index, &host, &flags,
399 true);
@@ -2224,12 +2230,12 @@ GEN_VEXT_VMERGE_VX(vmerge_vxm_d, int64_t, H8)
2230 * define common macros for fixed point here.
2231 */
2232 typedef void opivv2_rm_fn(void *vd, void *vs1, void *vs2, int i,
2227 - CPURISCVState *env, int vxrm);
2233 + CPURISCVState *env, uint8_t vxrm);
2234
2235 #define OPIVV2_RM(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \
2236 static inline void \
2237 do_##NAME(void *vd, void *vs1, void *vs2, int i, \
2232 - CPURISCVState *env, int vxrm) \
2238 + CPURISCVState *env, uint8_t vxrm) \
2239 { \
2240 TX1 s1 = *((T1 *)vs1 + HS1(i)); \
2241 TX2 s2 = *((T2 *)vs2 + HS2(i)); \
@@ -2239,7 +2245,7 @@ do_##NAME(void *vd, void *vs1, void *vs2, int i, \
2245 static inline void
2246 vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2,
2247 CPURISCVState *env,
2242 - uint32_t vl, uint32_t vm, int vxrm,
2248 + uint32_t vl, uint32_t vm, uint8_t vxrm,
2249 opivv2_rm_fn *fn, uint32_t vma, uint32_t esz)
2250 {
2251 for (uint32_t i = env->vstart; i < vl; i++) {
@@ -2298,7 +2304,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
2304 do_##NAME, ESZ); \
2305 }
2306
2301 -static inline uint8_t saddu8(CPURISCVState *env, int vxrm, uint8_t a,
2307 +static inline uint8_t saddu8(CPURISCVState *env, uint8_t vxrm, uint8_t a,
2308 uint8_t b)
2309 {
2310 uint8_t res = a + b;
@@ -2309,7 +2315,7 @@ static inline uint8_t saddu8(CPURISCVState *env, int vxrm, uint8_t a,
2315 return res;
2316 }
2317
2312 -static inline uint16_t saddu16(CPURISCVState *env, int vxrm, uint16_t a,
2318 +static inline uint16_t saddu16(CPURISCVState *env, uint8_t vxrm, uint16_t a,
2319 uint16_t b)
2320 {
2321 uint16_t res = a + b;
@@ -2320,7 +2326,7 @@ static inline uint16_t saddu16(CPURISCVState *env, int vxrm, uint16_t a,
2326 return res;
2327 }
2328
2323 -static inline uint32_t saddu32(CPURISCVState *env, int vxrm, uint32_t a,
2329 +static inline uint32_t saddu32(CPURISCVState *env, uint8_t vxrm, uint32_t a,
2330 uint32_t b)
2331 {
2332 uint32_t res = a + b;
@@ -2331,7 +2337,7 @@ static inline uint32_t saddu32(CPURISCVState *env, int vxrm, uint32_t a,
2337 return res;
2338 }
2339
2334 -static inline uint64_t saddu64(CPURISCVState *env, int vxrm, uint64_t a,
2340 +static inline uint64_t saddu64(CPURISCVState *env, uint8_t vxrm, uint64_t a,
2341 uint64_t b)
2342 {
2343 uint64_t res = a + b;
@@ -2352,12 +2358,12 @@ GEN_VEXT_VV_RM(vsaddu_vv_w, 4)
2358 GEN_VEXT_VV_RM(vsaddu_vv_d, 8)
2359
2360 typedef void opivx2_rm_fn(void *vd, target_long s1, void *vs2, int i,
2355 - CPURISCVState *env, int vxrm);
2361 + CPURISCVState *env, uint8_t vxrm);
2362
2363 #define OPIVX2_RM(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
2364 static inline void \
2365 do_##NAME(void *vd, target_long s1, void *vs2, int i, \
2360 - CPURISCVState *env, int vxrm) \
2366 + CPURISCVState *env, uint8_t vxrm) \
2367 { \
2368 TX2 s2 = *((T2 *)vs2 + HS2(i)); \
2369 *((TD *)vd + HD(i)) = OP(env, vxrm, s2, (TX1)(T1)s1); \
@@ -2366,7 +2372,7 @@ do_##NAME(void *vd, target_long s1, void *vs2, int i, \
2372 static inline void
2373 vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2,
2374 CPURISCVState *env,
2369 - uint32_t vl, uint32_t vm, int vxrm,
2375 + uint32_t vl, uint32_t vm, uint8_t vxrm,
2376 opivx2_rm_fn *fn, uint32_t vma, uint32_t esz)
2377 {
2378 for (uint32_t i = env->vstart; i < vl; i++) {
@@ -2435,7 +2441,8 @@ GEN_VEXT_VX_RM(vsaddu_vx_h, 2)
2441 GEN_VEXT_VX_RM(vsaddu_vx_w, 4)
2442 GEN_VEXT_VX_RM(vsaddu_vx_d, 8)
2443
2438 -static inline int8_t sadd8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2444 +static inline int8_t sadd8(CPURISCVState *env, uint8_t vxrm, int8_t a,
2445 + int8_t b)
2446 {
2447 int8_t res = a + b;
2448 if ((res ^ a) & (res ^ b) & INT8_MIN) {
@@ -2445,7 +2452,7 @@ static inline int8_t sadd8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2452 return res;
2453 }
2454
2448 -static inline int16_t sadd16(CPURISCVState *env, int vxrm, int16_t a,
2455 +static inline int16_t sadd16(CPURISCVState *env, uint8_t vxrm, int16_t a,
2456 int16_t b)
2457 {
2458 int16_t res = a + b;
@@ -2456,7 +2463,7 @@ static inline int16_t sadd16(CPURISCVState *env, int vxrm, int16_t a,
2463 return res;
2464 }
2465
2459 -static inline int32_t sadd32(CPURISCVState *env, int vxrm, int32_t a,
2466 +static inline int32_t sadd32(CPURISCVState *env, uint8_t vxrm, int32_t a,
2467 int32_t b)
2468 {
2469 int32_t res = a + b;
@@ -2467,7 +2474,7 @@ static inline int32_t sadd32(CPURISCVState *env, int vxrm, int32_t a,
2474 return res;
2475 }
2476
2470 -static inline int64_t sadd64(CPURISCVState *env, int vxrm, int64_t a,
2477 +static inline int64_t sadd64(CPURISCVState *env, uint8_t vxrm, int64_t a,
2478 int64_t b)
2479 {
2480 int64_t res = a + b;
@@ -2496,7 +2503,7 @@ GEN_VEXT_VX_RM(vsadd_vx_h, 2)
2503 GEN_VEXT_VX_RM(vsadd_vx_w, 4)
2504 GEN_VEXT_VX_RM(vsadd_vx_d, 8)
2505
2499 -static inline uint8_t ssubu8(CPURISCVState *env, int vxrm, uint8_t a,
2506 +static inline uint8_t ssubu8(CPURISCVState *env, uint8_t vxrm, uint8_t a,
2507 uint8_t b)
2508 {
2509 uint8_t res = a - b;
@@ -2507,7 +2514,7 @@ static inline uint8_t ssubu8(CPURISCVState *env, int vxrm, uint8_t a,
2514 return res;
2515 }
2516
2510 -static inline uint16_t ssubu16(CPURISCVState *env, int vxrm, uint16_t a,
2517 +static inline uint16_t ssubu16(CPURISCVState *env, uint8_t vxrm, uint16_t a,
2518 uint16_t b)
2519 {
2520 uint16_t res = a - b;
@@ -2518,7 +2525,7 @@ static inline uint16_t ssubu16(CPURISCVState *env, int vxrm, uint16_t a,
2525 return res;
2526 }
2527
2521 -static inline uint32_t ssubu32(CPURISCVState *env, int vxrm, uint32_t a,
2528 +static inline uint32_t ssubu32(CPURISCVState *env, uint8_t vxrm, uint32_t a,
2529 uint32_t b)
2530 {
2531 uint32_t res = a - b;
@@ -2529,7 +2536,7 @@ static inline uint32_t ssubu32(CPURISCVState *env, int vxrm, uint32_t a,
2536 return res;
2537 }
2538
2532 -static inline uint64_t ssubu64(CPURISCVState *env, int vxrm, uint64_t a,
2539 +static inline uint64_t ssubu64(CPURISCVState *env, uint8_t vxrm, uint64_t a,
2540 uint64_t b)
2541 {
2542 uint64_t res = a - b;
@@ -2558,7 +2565,8 @@ GEN_VEXT_VX_RM(vssubu_vx_h, 2)
2565 GEN_VEXT_VX_RM(vssubu_vx_w, 4)
2566 GEN_VEXT_VX_RM(vssubu_vx_d, 8)
2567
2561 -static inline int8_t ssub8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2568 +static inline int8_t ssub8(CPURISCVState *env, uint8_t vxrm, int8_t a,
2569 + int8_t b)
2570 {
2571 int8_t res = a - b;
2572 if ((res ^ a) & (a ^ b) & INT8_MIN) {
@@ -2568,7 +2576,7 @@ static inline int8_t ssub8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2576 return res;
2577 }
2578
2571 -static inline int16_t ssub16(CPURISCVState *env, int vxrm, int16_t a,
2579 +static inline int16_t ssub16(CPURISCVState *env, uint8_t vxrm, int16_t a,
2580 int16_t b)
2581 {
2582 int16_t res = a - b;
@@ -2579,7 +2587,7 @@ static inline int16_t ssub16(CPURISCVState *env, int vxrm, int16_t a,
2587 return res;
2588 }
2589
2582 -static inline int32_t ssub32(CPURISCVState *env, int vxrm, int32_t a,
2590 +static inline int32_t ssub32(CPURISCVState *env, uint8_t vxrm, int32_t a,
2591 int32_t b)
2592 {
2593 int32_t res = a - b;
@@ -2590,7 +2598,7 @@ static inline int32_t ssub32(CPURISCVState *env, int vxrm, int32_t a,
2598 return res;
2599 }
2600
2593 -static inline int64_t ssub64(CPURISCVState *env, int vxrm, int64_t a,
2601 +static inline int64_t ssub64(CPURISCVState *env, uint8_t vxrm, int64_t a,
2602 int64_t b)
2603 {
2604 int64_t res = a - b;
@@ -2620,7 +2628,7 @@ GEN_VEXT_VX_RM(vssub_vx_w, 4)
2628 GEN_VEXT_VX_RM(vssub_vx_d, 8)
2629
2630 /* Vector Single-Width Averaging Add and Subtract */
2623 -static inline uint8_t get_round(int vxrm, uint64_t v, uint8_t shift)
2631 +static inline uint8_t get_round(uint8_t vxrm, uint64_t v, uint8_t shift)
2632 {
2633 uint8_t d = extract64(v, shift, 1);
2634 uint8_t d1;
@@ -2632,22 +2640,30 @@ static inline uint8_t get_round(int vxrm, uint64_t v, uint8_t shift)
2640
2641 d1 = extract64(v, shift - 1, 1);
2642 D1 = extract64(v, 0, shift);
2635 - if (vxrm == 0) { /* round-to-nearest-up (add +0.5 LSB) */
2643 + switch (vxrm) {
2644 + case 0:
2645 + /* round-to-nearest-up (add +0.5 LSB) */
2646 return d1;
2637 - } else if (vxrm == 1) { /* round-to-nearest-even */
2647 + case 1:
2648 + /* round-to-nearest-even */
2649 if (shift > 1) {
2650 D2 = extract64(v, 0, shift - 1);
2651 return d1 & ((D2 != 0) | d);
2652 } else {
2653 return d1 & d;
2654 }
2644 - } else if (vxrm == 3) { /* round-to-odd (OR bits into LSB, aka "jam") */
2655 + case 2:
2656 + /* round-down (truncate) */
2657 + return 0;
2658 + case 3:
2659 + /* round-to-odd (OR bits into LSB, aka "jam") */
2660 return !d & (D1 != 0);
2661 + default:
2662 + g_assert_not_reached();
2663 }
2647 - return 0; /* round-down (truncate) */
2664 }
2665
2650 -static inline int32_t aadd32(CPURISCVState *env, int vxrm, int32_t a,
2666 +static inline int32_t aadd32(CPURISCVState *env, uint8_t vxrm, int32_t a,
2667 int32_t b)
2668 {
2669 int64_t res = (int64_t)a + b;
@@ -2656,7 +2672,7 @@ static inline int32_t aadd32(CPURISCVState *env, int vxrm, int32_t a,
2672 return (res >> 1) + round;
2673 }
2674
2659 -static inline int64_t aadd64(CPURISCVState *env, int vxrm, int64_t a,
2675 +static inline int64_t aadd64(CPURISCVState *env, uint8_t vxrm, int64_t a,
2676 int64_t b)
2677 {
2678 int64_t res = a + b;
@@ -2685,7 +2701,7 @@ GEN_VEXT_VX_RM(vaadd_vx_h, 2)
2701 GEN_VEXT_VX_RM(vaadd_vx_w, 4)
2702 GEN_VEXT_VX_RM(vaadd_vx_d, 8)
2703
2688 -static inline uint32_t aaddu32(CPURISCVState *env, int vxrm,
2704 +static inline uint32_t aaddu32(CPURISCVState *env, uint8_t vxrm,
2705 uint32_t a, uint32_t b)
2706 {
2707 uint64_t res = (uint64_t)a + b;
@@ -2694,7 +2710,7 @@ static inline uint32_t aaddu32(CPURISCVState *env, int vxrm,
2710 return (res >> 1) + round;
2711 }
2712
2697 -static inline uint64_t aaddu64(CPURISCVState *env, int vxrm,
2713 +static inline uint64_t aaddu64(CPURISCVState *env, uint8_t vxrm,
2714 uint64_t a, uint64_t b)
2715 {
2716 uint64_t res = a + b;
@@ -2722,7 +2738,7 @@ GEN_VEXT_VX_RM(vaaddu_vx_h, 2)
2738 GEN_VEXT_VX_RM(vaaddu_vx_w, 4)
2739 GEN_VEXT_VX_RM(vaaddu_vx_d, 8)
2740
2725 -static inline int32_t asub32(CPURISCVState *env, int vxrm, int32_t a,
2741 +static inline int32_t asub32(CPURISCVState *env, uint8_t vxrm, int32_t a,
2742 int32_t b)
2743 {
2744 int64_t res = (int64_t)a - b;
@@ -2731,7 +2747,7 @@ static inline int32_t asub32(CPURISCVState *env, int vxrm, int32_t a,
2747 return (res >> 1) + round;
2748 }
2749
2734 -static inline int64_t asub64(CPURISCVState *env, int vxrm, int64_t a,
2750 +static inline int64_t asub64(CPURISCVState *env, uint8_t vxrm, int64_t a,
2751 int64_t b)
2752 {
2753 int64_t res = (int64_t)a - b;
@@ -2760,7 +2776,7 @@ GEN_VEXT_VX_RM(vasub_vx_h, 2)
2776 GEN_VEXT_VX_RM(vasub_vx_w, 4)
2777 GEN_VEXT_VX_RM(vasub_vx_d, 8)
2778
2763 -static inline uint32_t asubu32(CPURISCVState *env, int vxrm,
2779 +static inline uint32_t asubu32(CPURISCVState *env, uint8_t vxrm,
2780 uint32_t a, uint32_t b)
2781 {
2782 int64_t res = (int64_t)a - b;
@@ -2769,7 +2785,7 @@ static inline uint32_t asubu32(CPURISCVState *env, int vxrm,
2785 return (res >> 1) + round;
2786 }
2787
2772 -static inline uint64_t asubu64(CPURISCVState *env, int vxrm,
2788 +static inline uint64_t asubu64(CPURISCVState *env, uint8_t vxrm,
2789 uint64_t a, uint64_t b)
2790 {
2791 uint64_t res = (uint64_t)a - b;
@@ -2798,7 +2814,8 @@ GEN_VEXT_VX_RM(vasubu_vx_w, 4)
2814 GEN_VEXT_VX_RM(vasubu_vx_d, 8)
2815
2816 /* Vector Single-Width Fractional Multiply with Rounding and Saturation */
2801 -static inline int8_t vsmul8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2817 +static inline int8_t vsmul8(CPURISCVState *env, uint8_t vxrm, int8_t a,
2818 + int8_t b)
2819 {
2820 uint8_t round;
2821 int16_t res;
@@ -2818,7 +2835,7 @@ static inline int8_t vsmul8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2835 }
2836 }
2837
2821 -static int16_t vsmul16(CPURISCVState *env, int vxrm, int16_t a, int16_t b)
2838 +static int16_t vsmul16(CPURISCVState *env, uint8_t vxrm, int16_t a, int16_t b)
2839 {
2840 uint8_t round;
2841 int32_t res;
@@ -2838,7 +2855,7 @@ static int16_t vsmul16(CPURISCVState *env, int vxrm, int16_t a, int16_t b)
2855 }
2856 }
2857
2841 -static int32_t vsmul32(CPURISCVState *env, int vxrm, int32_t a, int32_t b)
2858 +static int32_t vsmul32(CPURISCVState *env, uint8_t vxrm, int32_t a, int32_t b)
2859 {
2860 uint8_t round;
2861 int64_t res;
@@ -2858,7 +2875,7 @@ static int32_t vsmul32(CPURISCVState *env, int vxrm, int32_t a, int32_t b)
2875 }
2876 }
2877
2861 -static int64_t vsmul64(CPURISCVState *env, int vxrm, int64_t a, int64_t b)
2878 +static int64_t vsmul64(CPURISCVState *env, uint8_t vxrm, int64_t a, int64_t b)
2879 {
2880 uint8_t round;
2881 uint64_t hi_64, lo_64;
@@ -2906,7 +2923,7 @@ GEN_VEXT_VX_RM(vsmul_vx_d, 8)
2923
2924 /* Vector Single-Width Scaling Shift Instructions */
2925 static inline uint8_t
2909 -vssrl8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t b)
2926 +vssrl8(CPURISCVState *env, uint8_t vxrm, uint8_t a, uint8_t b)
2927 {
2928 uint8_t round, shift = b & 0x7;
2929 uint8_t res;
@@ -2916,7 +2933,7 @@ vssrl8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t b)
2933 return res;
2934 }
2935 static inline uint16_t
2919 -vssrl16(CPURISCVState *env, int vxrm, uint16_t a, uint16_t b)
2936 +vssrl16(CPURISCVState *env, uint8_t vxrm, uint16_t a, uint16_t b)
2937 {
2938 uint8_t round, shift = b & 0xf;
2939
@@ -2924,7 +2941,7 @@ vssrl16(CPURISCVState *env, int vxrm, uint16_t a, uint16_t b)
2941 return (a >> shift) + round;
2942 }
2943 static inline uint32_t
2927 -vssrl32(CPURISCVState *env, int vxrm, uint32_t a, uint32_t b)
2944 +vssrl32(CPURISCVState *env, uint8_t vxrm, uint32_t a, uint32_t b)
2945 {
2946 uint8_t round, shift = b & 0x1f;
2947
@@ -2932,7 +2949,7 @@ vssrl32(CPURISCVState *env, int vxrm, uint32_t a, uint32_t b)
2949 return (a >> shift) + round;
2950 }
2951 static inline uint64_t
2935 -vssrl64(CPURISCVState *env, int vxrm, uint64_t a, uint64_t b)
2952 +vssrl64(CPURISCVState *env, uint8_t vxrm, uint64_t a, uint64_t b)
2953 {
2954 uint8_t round, shift = b & 0x3f;
2955
@@ -2958,7 +2975,7 @@ GEN_VEXT_VX_RM(vssrl_vx_w, 4)
2975 GEN_VEXT_VX_RM(vssrl_vx_d, 8)
2976
2977 static inline int8_t
2961 -vssra8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2978 +vssra8(CPURISCVState *env, uint8_t vxrm, int8_t a, int8_t b)
2979 {
2980 uint8_t round, shift = b & 0x7;
2981
@@ -2966,7 +2983,7 @@ vssra8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2983 return (a >> shift) + round;
2984 }
2985 static inline int16_t
2969 -vssra16(CPURISCVState *env, int vxrm, int16_t a, int16_t b)
2986 +vssra16(CPURISCVState *env, uint8_t vxrm, int16_t a, int16_t b)
2987 {
2988 uint8_t round, shift = b & 0xf;
2989
@@ -2974,7 +2991,7 @@ vssra16(CPURISCVState *env, int vxrm, int16_t a, int16_t b)
2991 return (a >> shift) + round;
2992 }
2993 static inline int32_t
2977 -vssra32(CPURISCVState *env, int vxrm, int32_t a, int32_t b)
2994 +vssra32(CPURISCVState *env, uint8_t vxrm, int32_t a, int32_t b)
2995 {
2996 uint8_t round, shift = b & 0x1f;
2997
@@ -2982,7 +2999,7 @@ vssra32(CPURISCVState *env, int vxrm, int32_t a, int32_t b)
2999 return (a >> shift) + round;
3000 }
3001 static inline int64_t
2985 -vssra64(CPURISCVState *env, int vxrm, int64_t a, int64_t b)
3002 +vssra64(CPURISCVState *env, uint8_t vxrm, int64_t a, int64_t b)
3003 {
3004 uint8_t round, shift = b & 0x3f;
3005
@@ -3010,7 +3027,7 @@ GEN_VEXT_VX_RM(vssra_vx_d, 8)
3027
3028 /* Vector Narrowing Fixed-Point Clip Instructions */
3029 static inline int8_t
3013 -vnclip8(CPURISCVState *env, int vxrm, int16_t a, int8_t b)
3030 +vnclip8(CPURISCVState *env, uint8_t vxrm, int16_t a, int8_t b)
3031 {
3032 uint8_t round, shift = b & 0xf;
3033 int16_t res;
@@ -3029,7 +3046,7 @@ vnclip8(CPURISCVState *env, int vxrm, int16_t a, int8_t b)
3046 }
3047
3048 static inline int16_t
3032 -vnclip16(CPURISCVState *env, int vxrm, int32_t a, int16_t b)
3049 +vnclip16(CPURISCVState *env, uint8_t vxrm, int32_t a, int16_t b)
3050 {
3051 uint8_t round, shift = b & 0x1f;
3052 int32_t res;
@@ -3048,7 +3065,7 @@ vnclip16(CPURISCVState *env, int vxrm, int32_t a, int16_t b)
3065 }
3066
3067 static inline int32_t
3051 -vnclip32(CPURISCVState *env, int vxrm, int64_t a, int32_t b)
3068 +vnclip32(CPURISCVState *env, uint8_t vxrm, int64_t a, int32_t b)
3069 {
3070 uint8_t round, shift = b & 0x3f;
3071 int64_t res;
@@ -3081,7 +3098,7 @@ GEN_VEXT_VX_RM(vnclip_wx_h, 2)
3098 GEN_VEXT_VX_RM(vnclip_wx_w, 4)
3099
3100 static inline uint8_t
3084 -vnclipu8(CPURISCVState *env, int vxrm, uint16_t a, uint8_t b)
3101 +vnclipu8(CPURISCVState *env, uint8_t vxrm, uint16_t a, uint8_t b)
3102 {
3103 uint8_t round, shift = b & 0xf;
3104 uint16_t res;
@@ -3097,7 +3114,7 @@ vnclipu8(CPURISCVState *env, int vxrm, uint16_t a, uint8_t b)
3114 }
3115
3116 static inline uint16_t
3100 -vnclipu16(CPURISCVState *env, int vxrm, uint32_t a, uint16_t b)
3117 +vnclipu16(CPURISCVState *env, uint8_t vxrm, uint32_t a, uint16_t b)
3118 {
3119 uint8_t round, shift = b & 0x1f;
3120 uint32_t res;
@@ -3113,7 +3130,7 @@ vnclipu16(CPURISCVState *env, int vxrm, uint32_t a, uint16_t b)
3130 }
3131
3132 static inline uint32_t
3116 -vnclipu32(CPURISCVState *env, int vxrm, uint64_t a, uint32_t b)
3133 +vnclipu32(CPURISCVState *env, uint8_t vxrm, uint64_t a, uint32_t b)
3134 {
3135 uint8_t round, shift = b & 0x3f;
3136 uint64_t res;