This is what I did, It's in branch https://gitlab.com/lygstate-qemu/qemu/-/tree/combined-binary-multi-targets?ref_type=heads
On Thu, Oct 1, 2026 at 11:57 PM Anton Johansson via qemu development <[email protected]> wrote: > > Replaces uses of target_ulong with fixed-size integers, this is a > prerequisite step to compiling cpu.c once for system-mode. > > Note: the widening of target_long to int64_t in adjust_addr_body() is > safe as rv32 is ruled out earlier in the function via the check > > /* do nothing for rv32 mode */ > if (riscv_cpu_mxl(env) == MXL_RV32) { > return addr; > } > > meaning target_long must be equal to int64_t anyway. > > Duplicate includes between vector_helper.c and vector_internals.h are > removed. > > Signed-off-by: Anton Johansson <[email protected]> > --- > target/riscv/internals.h | 31 +++++++++--------- > target/riscv/tcg/vector_internals.h | 5 +-- > target/riscv/tcg/vector_helper.c | 64 > +++++++++++++++++-------------------- > 3 files changed, 47 insertions(+), 53 deletions(-) > > diff --git a/target/riscv/internals.h b/target/riscv/internals.h > index 1ee7e99e98..c963fae321 100644 > --- a/target/riscv/internals.h > +++ b/target/riscv/internals.h > @@ -20,7 +20,6 @@ > #define RISCV_CPU_INTERNALS_H > > #include "exec/cpu-common.h" > -#include "exec/target_long.h" > #include "hw/core/registerfields.h" > #include "fpu/softfloat-types.h" > #include "target/riscv/cpu_bits.h" > @@ -98,10 +97,10 @@ FIELD(VDATA, NF, 7, 4) > FIELD(VDATA, WD, 7, 1) > > /* float point classify helpers */ > -target_ulong fclass_h_bf16(uint64_t frs1); > -target_ulong fclass_h(uint64_t frs1); > -target_ulong fclass_s(uint64_t frs1); > -target_ulong fclass_d(uint64_t frs1); > +uint16_t fclass_h_bf16(bfloat16 frs1); > +uint16_t fclass_h(float16 frs1); > +uint16_t fclass_s(float32 frs1); > +uint16_t fclass_d(float64 frs1); > > #ifndef CONFIG_USER_ONLY > extern const VMStateDescription vmstate_riscv_cpu; > @@ -185,7 +184,7 @@ static inline float16 check_nanbox_bf16(CPURISCVState > *env, uint64_t f) > } > } > > -static inline target_ulong get_xepc_mask(CPURISCVState *env) > +static inline uint64_t get_xepc_mask(CPURISCVState *env) > { > RISCVCPU *cpu = env_archcpu(env); > > @@ -196,9 +195,9 @@ static inline target_ulong get_xepc_mask(CPURISCVState > *env) > if (riscv_has_ext(env, RVC) || cpu->cfg.ext_zca || > cpu->cfg.ext_zcb || cpu->cfg.ext_zcd || cpu->cfg.ext_zce || > cpu->cfg.ext_zcf || cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt) { > - return ~(target_ulong)1; > + return ~1ull; > } else { > - return ~(target_ulong)3; > + return ~3ull; > } > } > > @@ -208,9 +207,9 @@ bool riscv_cpu_has_work(CPUState *cs); > #endif > > /* Zjpm addr masking routine */ > -static inline target_ulong adjust_addr_body(CPURISCVState *env, > - target_ulong addr, > - bool is_virt_addr) > +static inline uint64_t adjust_addr_body(CPURISCVState *env, > + uint64_t addr, > + bool is_virt_addr) > { > RISCVPmPmm pmm = PMM_FIELD_DISABLED; > uint32_t pmlen = 0; > @@ -239,7 +238,7 @@ static inline target_ulong adjust_addr_body(CPURISCVState > *env, > > /* sign/zero extend masked address by N-1 bit */ > if (signext) { > - addr = (target_long)addr >> pmlen; > + addr = (int64_t)addr >> pmlen; > } else { > addr = addr >> pmlen; > } > @@ -247,14 +246,14 @@ static inline target_ulong > adjust_addr_body(CPURISCVState *env, > return addr; > } > > -static inline target_ulong adjust_addr(CPURISCVState *env, > - target_ulong addr) > +static inline uint64_t adjust_addr(CPURISCVState *env, > + uint64_t addr) > { > return adjust_addr_body(env, addr, false); > } > > -static inline target_ulong adjust_addr_virt(CPURISCVState *env, > - target_ulong addr) > +static inline uint64_t adjust_addr_virt(CPURISCVState *env, > + uint64_t addr) > { > return adjust_addr_body(env, addr, true); > } > diff --git a/target/riscv/tcg/vector_internals.h > b/target/riscv/tcg/vector_internals.h > index 5681b81815..7e186add2d 100644 > --- a/target/riscv/tcg/vector_internals.h > +++ b/target/riscv/tcg/vector_internals.h > @@ -20,10 +20,11 @@ > #define TARGET_RISCV_VECTOR_INTERNALS_H > > #include "qemu/bitops.h" > +#include "exec/target_long.h" > #include "hw/core/registerfields.h" > -#include "cpu.h" > +#include "target/riscv/cpu.h" > +#include "target/riscv/internals.h" > #include "tcg/tcg-gvec-desc.h" > -#include "internals.h" > > #define VSTART_CHECK_EARLY_EXIT(env, vl) do { \ > if (env->vstart >= vl) { \ > diff --git a/target/riscv/tcg/vector_helper.c > b/target/riscv/tcg/vector_helper.c > index 0d1e4e0964..b4a07dbe13 100644 > --- a/target/riscv/tcg/vector_helper.c > +++ b/target/riscv/tcg/vector_helper.c > @@ -19,7 +19,7 @@ > #include "qemu/osdep.h" > #include "qemu/host-utils.h" > #include "qemu/bitops.h" > -#include "cpu.h" > +#include "target/riscv/tcg/vector_internals.h" > #include "exec/memop.h" > #include "accel/tcg/cpu-ldst.h" > #include "accel/tcg/probe.h" > @@ -29,8 +29,6 @@ > #include "exec/target_page.h" > #include "fpu/softfloat.h" > #include "tcg/tcg-gvec-desc.h" > -#include "internals.h" > -#include "vector_internals.h" > #include <math.h> > > static target_ulong vtype_reserved(CPURISCVState *env, target_ulong vtype) > @@ -4852,77 +4850,73 @@ GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32) > GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64) > > /* Vector Floating-Point Classify Instruction */ > -target_ulong fclass_h_bf16(uint64_t frs1) > +uint16_t fclass_h_bf16(bfloat16 frs1) > { > - bfloat16 f = frs1; > - bool sign = bfloat16_is_neg(f); > + bool sign = bfloat16_is_neg(frs1); > > - if (bfloat16_is_infinity(f)) { > + if (bfloat16_is_infinity(frs1)) { > return sign ? 1 << 0 : 1 << 7; > - } else if (bfloat16_is_zero(f)) { > + } else if (bfloat16_is_zero(frs1)) { > return sign ? 1 << 3 : 1 << 4; > - } else if (bfloat16_is_zero_or_denormal(f)) { > + } else if (bfloat16_is_zero_or_denormal(frs1)) { > return sign ? 1 << 2 : 1 << 5; > - } else if (bfloat16_is_any_nan(f)) { > + } else if (bfloat16_is_any_nan(frs1)) { > float_status s = { }; /* for snan_bit_is_one */ > - return bfloat16_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8; > + return bfloat16_is_quiet_nan(frs1, &s) ? 1 << 9 : 1 << 8; > } else { > return sign ? 1 << 1 : 1 << 6; > } > } > > -target_ulong fclass_h(uint64_t frs1) > +uint16_t fclass_h(float16 frs1) > { > - float16 f = frs1; > - bool sign = float16_is_neg(f); > + bool sign = float16_is_neg(frs1); > > - if (float16_is_infinity(f)) { > + if (float16_is_infinity(frs1)) { > return sign ? 1 << 0 : 1 << 7; > - } else if (float16_is_zero(f)) { > + } else if (float16_is_zero(frs1)) { > return sign ? 1 << 3 : 1 << 4; > - } else if (float16_is_zero_or_denormal(f)) { > + } else if (float16_is_zero_or_denormal(frs1)) { > return sign ? 1 << 2 : 1 << 5; > - } else if (float16_is_any_nan(f)) { > + } else if (float16_is_any_nan(frs1)) { > float_status s = { }; /* for snan_bit_is_one */ > - return float16_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8; > + return float16_is_quiet_nan(frs1, &s) ? 1 << 9 : 1 << 8; > } else { > return sign ? 1 << 1 : 1 << 6; > } > } > > -target_ulong fclass_s(uint64_t frs1) > +uint16_t fclass_s(float32 frs1) > { > - float32 f = frs1; > - bool sign = float32_is_neg(f); > + bool sign = float32_is_neg(frs1); > > - if (float32_is_infinity(f)) { > + if (float32_is_infinity(frs1)) { > return sign ? 1 << 0 : 1 << 7; > - } else if (float32_is_zero(f)) { > + } else if (float32_is_zero(frs1)) { > return sign ? 1 << 3 : 1 << 4; > - } else if (float32_is_zero_or_denormal(f)) { > + } else if (float32_is_zero_or_denormal(frs1)) { > return sign ? 1 << 2 : 1 << 5; > - } else if (float32_is_any_nan(f)) { > + } else if (float32_is_any_nan(frs1)) { > float_status s = { }; /* for snan_bit_is_one */ > - return float32_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8; > + return float32_is_quiet_nan(frs1, &s) ? 1 << 9 : 1 << 8; > } else { > return sign ? 1 << 1 : 1 << 6; > } > } > > -target_ulong fclass_d(uint64_t frs1) > +uint16_t fclass_d(float64 frs1) > { > - float64 f = frs1; > - bool sign = float64_is_neg(f); > + bool sign = float64_is_neg(frs1); > > - if (float64_is_infinity(f)) { > + if (float64_is_infinity(frs1)) { > return sign ? 1 << 0 : 1 << 7; > - } else if (float64_is_zero(f)) { > + } else if (float64_is_zero(frs1)) { > return sign ? 1 << 3 : 1 << 4; > - } else if (float64_is_zero_or_denormal(f)) { > + } else if (float64_is_zero_or_denormal(frs1)) { > return sign ? 1 << 2 : 1 << 5; > - } else if (float64_is_any_nan(f)) { > + } else if (float64_is_any_nan(frs1)) { > float_status s = { }; /* for snan_bit_is_one */ > - return float64_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8; > + return float64_is_quiet_nan(frs1, &s) ? 1 << 9 : 1 << 8; > } else { > return sign ? 1 << 1 : 1 << 6; > } > > -- > 2.52.0 > > -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo
From 3910e4b6ffbccbff6f63985fbab8c298cf39ccee Mon Sep 17 00:00:00 2001 From: Yonggang Luo <[email protected]> Date: Sat, 12 Sep 2026 00:16:28 +0800 Subject: [PATCH] target/riscv: preserve signed XLEN semantics without target_long Mask pointer-masked addresses with extract64/sextract64 at runtime XLEN instead of a target_long arithmetic shift. Pass vector vx scalars as int64_t after sextract64 from the helper tl slot so RV32 keeps bit 31 as the sign bit. Leave every target_ulong helper argument unchanged. Signed-off-by: Yonggang Luo <[email protected]> --- target/riscv/internals.h | 12 ++++++++---- target/riscv/tcg/vector_helper.c | 30 ++++++++++++++++------------- target/riscv/tcg/vector_internals.c | 2 +- target/riscv/tcg/vector_internals.h | 9 +++++---- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/target/riscv/internals.h b/target/riscv/internals.h index 1ee7e99e98..0844867246 100644 --- a/target/riscv/internals.h +++ b/target/riscv/internals.h @@ -214,6 +214,7 @@ static inline target_ulong adjust_addr_body(CPURISCVState *env, { RISCVPmPmm pmm = PMM_FIELD_DISABLED; uint32_t pmlen = 0; + unsigned kept; bool signext = false; /* do nothing for rv32 mode */ @@ -235,13 +236,16 @@ static inline target_ulong adjust_addr_body(CPURISCVState *env, signext = riscv_cpu_virt_mem_enabled(env, is_virt_addr); pmlen = riscv_pm_get_pmlen(pmm); - addr = addr << pmlen; - /* sign/zero extend masked address by N-1 bit */ + /* + * Drop the top pmlen bits of XLEN. Do not rely on target_ulong + * shift wrap; common-system target_ulong is always 64 bits. + */ + kept = target_long_bits() - pmlen; if (signext) { - addr = (target_long)addr >> pmlen; + addr = sextract64(addr, 0, kept); } else { - addr = addr >> pmlen; + addr = extract64(addr, 0, kept); } return addr; diff --git a/target/riscv/tcg/vector_helper.c b/target/riscv/tcg/vector_helper.c index 0d1e4e0964..3a2661b381 100644 --- a/target/riscv/tcg/vector_helper.c +++ b/target/riscv/tcg/vector_helper.c @@ -1240,6 +1240,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ uint32_t esz = sizeof(ETYPE); \ uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ uint32_t vta = vext_vta(desc); \ + ETYPE scalar = (ETYPE)sextract64(s1, 0, target_long_bits()); \ uint32_t i; \ \ VSTART_CHECK_EARLY_EXIT(env, vl); \ @@ -1248,7 +1249,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ ETYPE carry = vext_elem_mask(v0, i); \ \ - *((ETYPE *)vd + H(i)) = DO_OP(s2, (ETYPE)(target_long)s1, carry);\ + *((ETYPE *)vd + H(i)) = DO_OP(s2, scalar, carry); \ } \ env->vstart = 0; \ /* set tail elements to 1s */ \ @@ -1317,15 +1318,16 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ uint32_t vm = vext_vm(desc); \ uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3; \ uint32_t vta_all_1s = vext_vta_all_1s(desc); \ + ETYPE scalar; \ uint32_t i; \ \ VSTART_CHECK_EARLY_EXIT(env, vl); \ \ + scalar = (ETYPE)sextract64(s1, 0, target_long_bits()); \ for (i = env->vstart; i < vl; i++) { \ ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ ETYPE carry = !vm && vext_elem_mask(v0, i); \ - vext_set_elem_mask(vd, i, \ - DO_OP(s2, (ETYPE)(target_long)s1, carry)); \ + vext_set_elem_mask(vd, i, DO_OP(s2, scalar, carry)); \ } \ env->vstart = 0; \ /* @@ -1595,6 +1597,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3; \ uint32_t vta_all_1s = vext_vta_all_1s(desc); \ uint32_t vma = vext_vma(desc); \ + ETYPE scalar = (ETYPE)sextract64(s1, 0, target_long_bits()); \ uint32_t i; \ \ VSTART_CHECK_EARLY_EXIT(env, vl); \ @@ -1608,8 +1611,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ } \ continue; \ } \ - vext_set_elem_mask(vd, i, \ - DO_OP(s2, (ETYPE)(target_long)s1)); \ + vext_set_elem_mask(vd, i, DO_OP(s2, scalar)); \ } \ env->vstart = 0; \ /* @@ -2050,7 +2052,7 @@ GEN_VEXT_VV(vnmsub_vv_w, 4) GEN_VEXT_VV(vnmsub_vv_d, 8) #define OPIVX3(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \ -static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \ +static void do_##NAME(void *vd, int64_t s1, void *vs2, int i) \ { \ TX2 s2 = *((T2 *)vs2 + HS2(i)); \ TD d = *((TD *)vd + HD(i)); \ @@ -2239,14 +2241,14 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ uint32_t esz = sizeof(ETYPE); \ uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ uint32_t vta = vext_vta(desc); \ + ETYPE scalar = (ETYPE)sextract64(s1, 0, target_long_bits()); \ uint32_t i; \ \ VSTART_CHECK_EARLY_EXIT(env, vl); \ \ for (i = env->vstart; i < vl; i++) { \ ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ - ETYPE d = (!vext_elem_mask(v0, i) ? s2 : \ - (ETYPE)(target_long)s1); \ + ETYPE d = (!vext_elem_mask(v0, i) ? s2 : scalar); \ *((ETYPE *)vd + H(i)) = d; \ } \ env->vstart = 0; \ @@ -2397,12 +2399,12 @@ GEN_VEXT_VV_RM(vsaddu_vv_h, 2) GEN_VEXT_VV_RM(vsaddu_vv_w, 4) GEN_VEXT_VV_RM(vsaddu_vv_d, 8) -typedef void opivx2_rm_fn(void *vd, target_long s1, void *vs2, int i, +typedef void opivx2_rm_fn(void *vd, int64_t s1, void *vs2, int i, CPURISCVState *env, uint8_t vxrm); #define OPIVX2_RM(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \ static inline void \ -do_##NAME(void *vd, target_long s1, void *vs2, int i, \ +do_##NAME(void *vd, int64_t s1, void *vs2, int i, \ CPURISCVState *env, uint8_t vxrm) \ { \ TX2 s2 = *((T2 *)vs2 + HS2(i)); \ @@ -2410,7 +2412,7 @@ do_##NAME(void *vd, target_long s1, void *vs2, int i, \ } static inline void -vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2, +vext_vx_rm_1(void *vd, void *v0, int64_t s1, void *vs2, CPURISCVState *env, uint32_t vl, uint32_t vm, uint8_t vxrm, opivx2_rm_fn *fn, uint32_t vma, uint32_t esz) @@ -2427,7 +2429,7 @@ vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2, } static inline void -vext_vx_rm_2(void *vd, void *v0, target_long s1, void *vs2, +vext_vx_rm_2(void *vd, void *v0, int64_t s1, void *vs2, CPURISCVState *env, uint32_t desc, opivx2_rm_fn *fn, uint32_t esz) @@ -2468,7 +2470,9 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ void *vs2, CPURISCVState *env, \ uint32_t desc) \ { \ - vext_vx_rm_2(vd, v0, s1, vs2, env, desc, \ + int64_t scalar; \ + scalar = sextract64(s1, 0, target_long_bits()); \ + vext_vx_rm_2(vd, v0, scalar, vs2, env, desc, \ do_##NAME, ESZ); \ } diff --git a/target/riscv/tcg/vector_internals.c b/target/riscv/tcg/vector_internals.c index b490b1d398..9532705266 100644 --- a/target/riscv/tcg/vector_internals.c +++ b/target/riscv/tcg/vector_internals.c @@ -81,7 +81,7 @@ void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2, vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); } -void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, +void do_vext_vx(void *vd, void *v0, int64_t s1, void *vs2, CPURISCVState *env, uint32_t desc, opivx2_fn fn, uint32_t esz) { diff --git a/target/riscv/tcg/vector_internals.h b/target/riscv/tcg/vector_internals.h index 5681b81815..da093d561e 100644 --- a/target/riscv/tcg/vector_internals.h +++ b/target/riscv/tcg/vector_internals.h @@ -201,20 +201,20 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ do_##NAME, ESZ); \ } -typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i); +typedef void opivx2_fn(void *vd, int64_t s1, void *vs2, int i); /* * (T1)s1 gives the real operator type. * (TX1)(T1)s1 expands the operator type of widen or narrow operations. */ #define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \ -static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \ +static void do_##NAME(void *vd, int64_t s1, void *vs2, int i) \ { \ TX2 s2 = *((T2 *)vs2 + HS2(i)); \ *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1); \ } -void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, +void do_vext_vx(void *vd, void *v0, int64_t s1, void *vs2, CPURISCVState *env, uint32_t desc, opivx2_fn fn, uint32_t esz); @@ -224,7 +224,8 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ void *vs2, CPURISCVState *env, \ uint32_t desc) \ { \ - do_vext_vx(vd, v0, s1, vs2, env, desc, \ + do_vext_vx(vd, v0, sextract64(s1, 0, target_long_bits()), \ + vs2, env, desc, \ do_##NAME, ESZ); \ } -- 2.55.0.windows.3
