* [PATCH 00/22] target/sparc: floating-point cleanup
@ 2023-11-03 17:38 Richard Henderson
2023-11-03 17:38 ` [PATCH 01/22] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for ASI_M_BCOPY Richard Henderson
` (22 more replies)
0 siblings, 23 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Major changes:
(1) Get rid of the env->qt[01] temporaries and use TCGv_i128 for float128.
(2) Perform ieee exception check within the helpers, before any writeback
to the floating point registers.
(3) Split env->fsr into pieces to simplify update, especially compares.
r~
Based-on: 20231101041132.174501-1-richard.henderson@linaro.org
("[PATCH v2 00/21] target/sparc: Cleanup condition codes etc")
Richard Henderson (22):
target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for ASI_M_BCOPY
target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for ASI_M_BFILL
target/sparc: Remove gen_dest_fpr_F
target/sparc: Introduce gen_{load,store}_fpr_Q
target/sparc: Inline FNEG, FABS
target/sparc: Use i128 for FSQRTq
target/sparc: Use i128 for FADDq, FSUBq, FMULq, FDIVq
target/sparc: Use i128 for FqTOs, FqTOi
target/sparc: Use i128 for FqTOd, FqTOx
target/sparc: Use i128 for FCMPq, FCMPEq
target/sparc: Use i128 for FsTOq, FiTOq
target/sparc: Use i128 for FdTOq, FxTOq
target/sparc: Use i128 for Fdmulq
target/sparc: Remove qt0, qt1 temporaries
target/sparc: Introduce cpu_get_fsr, cpu_put_fsr
target/split: Split ver from env->fsr
target/sparc: Clear cexc and ftt in do_check_ieee_exceptions
target/sparc: Merge check_ieee_exceptions with FPop helpers
target/sparc: Split cexc and ftt from env->fsr
target/sparc: Remove cpu_fsr
target/sparc: Split fcc out of env->fsr
target/sparc: Remove FSR_FTT_NMASK, FSR_FTT_CEXC_NMASK
target/sparc/cpu.h | 39 +-
target/sparc/helper.h | 116 ++----
linux-user/sparc/cpu_loop.c | 2 +-
linux-user/sparc/signal.c | 14 +-
target/sparc/cpu.c | 32 +-
target/sparc/fop_helper.c | 510 +++++++++++++----------
target/sparc/gdbstub.c | 8 +-
target/sparc/ldst_helper.c | 3 -
target/sparc/machine.c | 38 +-
target/sparc/translate.c | 799 ++++++++++++------------------------
10 files changed, 680 insertions(+), 881 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 01/22] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for ASI_M_BCOPY
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 02/22] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for ASI_M_BFILL Richard Henderson
` (21 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Align the operation to the 32-byte cacheline.
Use 2 pair of i128 instead of 8 pair of i32.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 43 +++++++++++++++++++++++-----------------
1 file changed, 25 insertions(+), 18 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 6fc333a6b8..5d55856a54 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1727,28 +1727,35 @@ static void gen_st_asi(DisasContext *dc, DisasASI *da, TCGv src, TCGv addr)
case GET_ASI_BCOPY:
assert(TARGET_LONG_BITS == 32);
- /* Copy 32 bytes from the address in SRC to ADDR. */
- /* ??? The original qemu code suggests 4-byte alignment, dropping
- the low bits, but the only place I can see this used is in the
- Linux kernel with 32 byte alignment, which would make more sense
- as a cacheline-style operation. */
+ /*
+ * Copy 32 bytes from the address in SRC to ADDR.
+ *
+ * From Ross RT625 hyperSPARC manual, section 4.6:
+ * "Block Copy and Block Fill will work only on cache line boundaries."
+ *
+ * It does not specify if an unaliged address is truncated or trapped.
+ * Previous qemu behaviour was to truncate to 4 byte alignment, which
+ * is obviously wrong. The only place I can see this used is in the
+ * Linux kernel which begins with page alignment, advancing by 32,
+ * so is always aligned. Assume truncation as the simpler option.
+ *
+ * Since the loads and stores are paired, allow the copy to happen
+ * in the host endianness. The copy need not be atomic.
+ */
{
+ MemOp mop = MO_128 | MO_ATOM_IFALIGN_PAIR;
TCGv saddr = tcg_temp_new();
TCGv daddr = tcg_temp_new();
- TCGv four = tcg_constant_tl(4);
- TCGv_i32 tmp = tcg_temp_new_i32();
- int i;
+ TCGv_i128 tmp = tcg_temp_new_i128();
- tcg_gen_andi_tl(saddr, src, -4);
- tcg_gen_andi_tl(daddr, addr, -4);
- for (i = 0; i < 32; i += 4) {
- /* Since the loads and stores are paired, allow the
- copy to happen in the host endianness. */
- tcg_gen_qemu_ld_i32(tmp, saddr, da->mem_idx, MO_UL);
- tcg_gen_qemu_st_i32(tmp, daddr, da->mem_idx, MO_UL);
- tcg_gen_add_tl(saddr, saddr, four);
- tcg_gen_add_tl(daddr, daddr, four);
- }
+ tcg_gen_andi_tl(saddr, src, -32);
+ tcg_gen_andi_tl(daddr, addr, -32);
+ tcg_gen_qemu_ld_i128(tmp, saddr, da->mem_idx, mop);
+ tcg_gen_qemu_st_i128(tmp, daddr, da->mem_idx, mop);
+ tcg_gen_addi_tl(saddr, saddr, 16);
+ tcg_gen_addi_tl(daddr, daddr, 16);
+ tcg_gen_qemu_ld_i128(tmp, saddr, da->mem_idx, mop);
+ tcg_gen_qemu_st_i128(tmp, daddr, da->mem_idx, mop);
}
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 02/22] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for ASI_M_BFILL
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
2023-11-03 17:38 ` [PATCH 01/22] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for ASI_M_BCOPY Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 03/22] target/sparc: Remove gen_dest_fpr_F Richard Henderson
` (20 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Align the operation to the 32-byte cacheline.
Use 2 i128 instead of 4 i64.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 29 ++++++++++++++---------------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 5d55856a54..713ac5bbae 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2172,23 +2172,22 @@ static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
case GET_ASI_BFILL:
assert(TARGET_LONG_BITS == 32);
- /* Store 32 bytes of T64 to ADDR. */
- /* ??? The original qemu code suggests 8-byte alignment, dropping
- the low bits, but the only place I can see this used is in the
- Linux kernel with 32 byte alignment, which would make more sense
- as a cacheline-style operation. */
+ /*
+ * Store 32 bytes of [rd:rd+1] to ADDR.
+ * See comments for GET_ASI_COPY above.
+ */
{
- TCGv_i64 t64 = tcg_temp_new_i64();
- TCGv d_addr = tcg_temp_new();
- TCGv eight = tcg_constant_tl(8);
- int i;
+ MemOp mop = MO_TE | MO_128 | MO_ATOM_IFALIGN_PAIR;
+ TCGv_i64 t8 = tcg_temp_new_i64();
+ TCGv_i128 t16 = tcg_temp_new_i128();
+ TCGv daddr = tcg_temp_new();
- tcg_gen_concat_tl_i64(t64, lo, hi);
- tcg_gen_andi_tl(d_addr, addr, -8);
- for (i = 0; i < 32; i += 8) {
- tcg_gen_qemu_st_i64(t64, d_addr, da->mem_idx, da->memop);
- tcg_gen_add_tl(d_addr, d_addr, eight);
- }
+ tcg_gen_concat_tl_i64(t8, lo, hi);
+ tcg_gen_concat_i64_i128(t16, t8, t8);
+ tcg_gen_andi_tl(daddr, addr, -32);
+ tcg_gen_qemu_st_i128(t16, daddr, da->mem_idx, mop);
+ tcg_gen_addi_tl(daddr, daddr, 16);
+ tcg_gen_qemu_st_i128(t16, daddr, da->mem_idx, mop);
}
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 03/22] target/sparc: Remove gen_dest_fpr_F
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
2023-11-03 17:38 ` [PATCH 01/22] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for ASI_M_BCOPY Richard Henderson
2023-11-03 17:38 ` [PATCH 02/22] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for ASI_M_BFILL Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2024-01-30 7:54 ` Philippe Mathieu-Daudé
2023-11-03 17:38 ` [PATCH 04/22] target/sparc: Introduce gen_{load,store}_fpr_Q Richard Henderson
` (19 subsequent siblings)
22 siblings, 1 reply; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Replace with tcg_temp_new_i32.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 713ac5bbae..cdc85be807 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -246,11 +246,6 @@ static void gen_store_fpr_F(DisasContext *dc, unsigned int dst, TCGv_i32 v)
gen_update_fprs_dirty(dc, dst);
}
-static TCGv_i32 gen_dest_fpr_F(DisasContext *dc)
-{
- return tcg_temp_new_i32();
-}
-
static TCGv_i64 gen_load_fpr_D(DisasContext *dc, unsigned int src)
{
src = DFPREG(src);
@@ -1873,7 +1868,7 @@ static void gen_ldf_asi(DisasContext *dc, DisasASI *da, MemOp orig_size,
memop |= MO_ALIGN_4;
switch (size) {
case MO_32:
- d32 = gen_dest_fpr_F(dc);
+ d32 = tcg_temp_new_i32();
tcg_gen_qemu_ld_i32(d32, addr, da->mem_idx, memop);
gen_store_fpr_F(dc, rd, d32);
break;
@@ -1938,7 +1933,7 @@ static void gen_ldf_asi(DisasContext *dc, DisasASI *da, MemOp orig_size,
case MO_32:
d64 = tcg_temp_new_i64();
gen_helper_ld_asi(d64, tcg_env, addr, r_asi, r_mop);
- d32 = gen_dest_fpr_F(dc);
+ d32 = tcg_temp_new_i32();
tcg_gen_extrl_i64_i32(d32, d64);
gen_store_fpr_F(dc, rd, d32);
break;
@@ -2228,7 +2223,7 @@ static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
s1 = gen_load_fpr_F(dc, rs);
s2 = gen_load_fpr_F(dc, rd);
- dst = gen_dest_fpr_F(dc);
+ dst = tcg_temp_new_i32();
zero = tcg_constant_i32(0);
tcg_gen_movcond_i32(TCG_COND_NE, dst, c32, zero, s1, s2);
@@ -4497,7 +4492,7 @@ static bool do_fd(DisasContext *dc, arg_r_r *a,
return true;
}
- dst = gen_dest_fpr_F(dc);
+ dst = tcg_temp_new_i32();
src = gen_load_fpr_D(dc, a->rs);
func(dst, src);
gen_store_fpr_F(dc, a->rd, dst);
@@ -4539,7 +4534,7 @@ static bool do_env_fd(DisasContext *dc, arg_r_r *a,
}
gen_op_clear_ieee_excp_and_FTT();
- dst = gen_dest_fpr_F(dc);
+ dst = tcg_temp_new_i32();
src = gen_load_fpr_D(dc, a->rs);
func(dst, tcg_env, src);
gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
@@ -4697,7 +4692,7 @@ static bool do_env_fq(DisasContext *dc, arg_r_r *a,
gen_op_clear_ieee_excp_and_FTT();
gen_op_load_fpr_QT1(QFPREG(a->rs));
- dst = gen_dest_fpr_F(dc);
+ dst = tcg_temp_new_i32();
func(dst, tcg_env);
gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_F(dc, a->rd, dst);
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 04/22] target/sparc: Introduce gen_{load,store}_fpr_Q
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (2 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 03/22] target/sparc: Remove gen_dest_fpr_F Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2024-01-30 7:56 ` Philippe Mathieu-Daudé
2023-11-03 17:38 ` [PATCH 05/22] target/sparc: Inline FNEG, FABS Richard Henderson
` (18 subsequent siblings)
22 siblings, 1 reply; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Use them for trans_FMOVq.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index cdc85be807..0e494d3ebd 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -264,6 +264,22 @@ static TCGv_i64 gen_dest_fpr_D(DisasContext *dc, unsigned int dst)
return cpu_fpr[DFPREG(dst) / 2];
}
+static TCGv_i128 gen_load_fpr_Q(DisasContext *dc, unsigned int src)
+{
+ TCGv_i128 ret = tcg_temp_new_i128();
+
+ src = QFPREG(src);
+ tcg_gen_concat_i64_i128(ret, cpu_fpr[src / 2 + 1], cpu_fpr[src / 2]);
+ return ret;
+}
+
+static void gen_store_fpr_Q(DisasContext *dc, unsigned int dst, TCGv_i128 v)
+{
+ dst = DFPREG(dst);
+ tcg_gen_extr_i128_i64(cpu_fpr[dst / 2 + 1], cpu_fpr[dst / 2], v);
+ gen_update_fprs_dirty(dc, dst);
+}
+
static void gen_op_load_fpr_QT0(unsigned int src)
{
tcg_gen_st_i64(cpu_fpr[src / 2], tcg_env, offsetof(CPUSPARCState, qt0) +
@@ -4615,7 +4631,7 @@ TRANS(FsTOx, 64, do_env_df, a, gen_helper_fstox)
static bool trans_FMOVq(DisasContext *dc, arg_FMOVq *a)
{
- int rd, rs;
+ TCGv_i128 t;
if (!avail_64(dc)) {
return false;
@@ -4628,11 +4644,8 @@ static bool trans_FMOVq(DisasContext *dc, arg_FMOVq *a)
}
gen_op_clear_ieee_excp_and_FTT();
- rd = QFPREG(a->rd);
- rs = QFPREG(a->rs);
- tcg_gen_mov_i64(cpu_fpr[rd / 2], cpu_fpr[rs / 2]);
- tcg_gen_mov_i64(cpu_fpr[rd / 2 + 1], cpu_fpr[rs / 2 + 1]);
- gen_update_fprs_dirty(dc, rd);
+ t = gen_load_fpr_Q(dc, a->rs);
+ gen_store_fpr_Q(dc, a->rd, t);
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 05/22] target/sparc: Inline FNEG, FABS
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (3 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 04/22] target/sparc: Introduce gen_{load,store}_fpr_Q Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2024-01-30 8:04 ` Philippe Mathieu-Daudé
2024-01-30 8:40 ` Philippe Mathieu-Daudé
2023-11-03 17:38 ` [PATCH 06/22] target/sparc: Use i128 for FSQRTq Richard Henderson
` (17 subsequent siblings)
22 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
These are simple bit manipulation insns.
Begin using i128 for float128.
Implement FMOVq with do_qq.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 6 ----
target/sparc/fop_helper.c | 34 ---------------------
target/sparc/translate.c | 62 +++++++++++++++++++--------------------
3 files changed, 30 insertions(+), 72 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 55eff66283..74a1575d21 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -37,7 +37,6 @@ DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32)
#endif
DEF_HELPER_FLAGS_1(check_ieee_exceptions, TCG_CALL_NO_WG, tl, env)
DEF_HELPER_FLAGS_2(set_fsr, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_1(fabss, TCG_CALL_NO_RWG_SE, f32, f32)
DEF_HELPER_FLAGS_2(fsqrts, TCG_CALL_NO_RWG, f32, env, f32)
DEF_HELPER_FLAGS_2(fsqrtd, TCG_CALL_NO_RWG, f64, env, f64)
DEF_HELPER_FLAGS_3(fcmps, TCG_CALL_NO_WG, tl, env, f32, f32)
@@ -48,7 +47,6 @@ DEF_HELPER_FLAGS_1(fsqrtq, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_1(fcmpq, TCG_CALL_NO_WG, tl, env)
DEF_HELPER_FLAGS_1(fcmpeq, TCG_CALL_NO_WG, tl, env)
#ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_1(fabsd, TCG_CALL_NO_RWG_SE, f64, f64)
DEF_HELPER_FLAGS_3(fcmps_fcc1, TCG_CALL_NO_WG, tl, env, f32, f32)
DEF_HELPER_FLAGS_3(fcmps_fcc2, TCG_CALL_NO_WG, tl, env, f32, f32)
DEF_HELPER_FLAGS_3(fcmps_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32)
@@ -61,7 +59,6 @@ DEF_HELPER_FLAGS_3(fcmpes_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32)
DEF_HELPER_FLAGS_3(fcmped_fcc1, TCG_CALL_NO_WG, tl, env, f64, f64)
DEF_HELPER_FLAGS_3(fcmped_fcc2, TCG_CALL_NO_WG, tl, env, f64, f64)
DEF_HELPER_FLAGS_3(fcmped_fcc3, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_1(fabsq, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_1(fcmpq_fcc1, TCG_CALL_NO_WG, tl, env)
DEF_HELPER_FLAGS_1(fcmpq_fcc2, TCG_CALL_NO_WG, tl, env)
DEF_HELPER_FLAGS_1(fcmpq_fcc3, TCG_CALL_NO_WG, tl, env)
@@ -90,15 +87,12 @@ DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_RWG, f32, env, f32, f32)
DEF_HELPER_FLAGS_3(fsmuld, TCG_CALL_NO_RWG, f64, env, f32, f32)
DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_RWG, void, env, f64, f64)
-DEF_HELPER_FLAGS_1(fnegs, TCG_CALL_NO_RWG_SE, f32, f32)
DEF_HELPER_FLAGS_2(fitod, TCG_CALL_NO_RWG_SE, f64, env, s32)
DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_RWG, void, env, s32)
DEF_HELPER_FLAGS_2(fitos, TCG_CALL_NO_RWG, f32, env, s32)
#ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_1(fnegd, TCG_CALL_NO_RWG_SE, f64, f64)
-DEF_HELPER_FLAGS_1(fnegq, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_2(fxtos, TCG_CALL_NO_RWG, f32, env, s64)
DEF_HELPER_FLAGS_2(fxtod, TCG_CALL_NO_RWG, f64, env, s64)
DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_RWG, void, env, s64)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 0f8aa3abcd..d6fb769769 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -114,23 +114,6 @@ void helper_fdmulq(CPUSPARCState *env, float64 src1, float64 src2)
&env->fp_status);
}
-float32 helper_fnegs(float32 src)
-{
- return float32_chs(src);
-}
-
-#ifdef TARGET_SPARC64
-float64 helper_fnegd(float64 src)
-{
- return float64_chs(src);
-}
-
-F_HELPER(neg, q)
-{
- QT0 = float128_chs(QT1);
-}
-#endif
-
/* Integer to float conversion. */
float32 helper_fitos(CPUSPARCState *env, int32_t src)
{
@@ -229,23 +212,6 @@ int64_t helper_fqtox(CPUSPARCState *env)
}
#endif
-float32 helper_fabss(float32 src)
-{
- return float32_abs(src);
-}
-
-#ifdef TARGET_SPARC64
-float64 helper_fabsd(float64 src)
-{
- return float64_abs(src);
-}
-
-void helper_fabsq(CPUSPARCState *env)
-{
- QT0 = float128_abs(QT1);
-}
-#endif
-
float32 helper_fsqrts(CPUSPARCState *env, float32 src)
{
return float32_sqrt(src, &env->fp_status);
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 0e494d3ebd..254f185b83 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -43,9 +43,7 @@
#else
# define gen_helper_clear_softint(E, S) qemu_build_not_reached()
# define gen_helper_done(E) qemu_build_not_reached()
-# define gen_helper_fabsd(D, S) qemu_build_not_reached()
# define gen_helper_flushw(E) qemu_build_not_reached()
-# define gen_helper_fnegd(D, S) qemu_build_not_reached()
# define gen_helper_rdccr(D, E) qemu_build_not_reached()
# define gen_helper_rdcwp(D, E) qemu_build_not_reached()
# define gen_helper_restored(E) qemu_build_not_reached()
@@ -61,7 +59,6 @@
# define gen_helper_write_softint(E, S) qemu_build_not_reached()
# define gen_helper_wrpil(E, S) qemu_build_not_reached()
# define gen_helper_wrpstate(E, S) qemu_build_not_reached()
-# define gen_helper_fabsq ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fcmpeq16 ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fcmpeq32 ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fcmpgt16 ({ qemu_build_not_reached(); NULL; })
@@ -79,7 +76,6 @@
# define gen_helper_fmul8x16 ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fmuld8sux16 ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fmuld8ulx16 ({ qemu_build_not_reached(); NULL; })
-# define gen_helper_fnegq ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fpmerge ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fqtox ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fstox ({ qemu_build_not_reached(); NULL; })
@@ -1239,13 +1235,13 @@ static void gen_op_fmovs(TCGv_i32 dst, TCGv_i32 src)
static void gen_op_fnegs(TCGv_i32 dst, TCGv_i32 src)
{
gen_op_clear_ieee_excp_and_FTT();
- gen_helper_fnegs(dst, src);
+ tcg_gen_xori_i32(dst, src, 1u << 31);
}
static void gen_op_fabss(TCGv_i32 dst, TCGv_i32 src)
{
gen_op_clear_ieee_excp_and_FTT();
- gen_helper_fabss(dst, src);
+ tcg_gen_andi_i32(dst, src, ~(1u << 31));
}
static void gen_op_fmovd(TCGv_i64 dst, TCGv_i64 src)
@@ -1257,13 +1253,33 @@ static void gen_op_fmovd(TCGv_i64 dst, TCGv_i64 src)
static void gen_op_fnegd(TCGv_i64 dst, TCGv_i64 src)
{
gen_op_clear_ieee_excp_and_FTT();
- gen_helper_fnegd(dst, src);
+ tcg_gen_xori_i64(dst, src, 1ull << 63);
}
static void gen_op_fabsd(TCGv_i64 dst, TCGv_i64 src)
{
gen_op_clear_ieee_excp_and_FTT();
- gen_helper_fabsd(dst, src);
+ tcg_gen_andi_i64(dst, src, ~(1ull << 63));
+}
+
+static void gen_op_fnegq(TCGv_i128 dst, TCGv_i128 src)
+{
+ TCGv_i64 l = tcg_temp_new_i64();
+ TCGv_i64 h = tcg_temp_new_i64();
+
+ tcg_gen_extr_i128_i64(l, h, src);
+ tcg_gen_xori_i64(h, h, 1ull << 63);
+ tcg_gen_concat_i64_i128(dst, l, h);
+}
+
+static void gen_op_fabsq(TCGv_i128 dst, TCGv_i128 src)
+{
+ TCGv_i64 l = tcg_temp_new_i64();
+ TCGv_i64 h = tcg_temp_new_i64();
+
+ tcg_gen_extr_i128_i64(l, h, src);
+ tcg_gen_andi_i64(h, h, ~(1ull << 63));
+ tcg_gen_concat_i64_i128(dst, l, h);
}
#ifdef TARGET_SPARC64
@@ -4629,13 +4645,11 @@ TRANS(FiTOd, ALL, do_env_df, a, gen_helper_fitod)
TRANS(FsTOd, ALL, do_env_df, a, gen_helper_fstod)
TRANS(FsTOx, 64, do_env_df, a, gen_helper_fstox)
-static bool trans_FMOVq(DisasContext *dc, arg_FMOVq *a)
+static bool do_qq(DisasContext *dc, arg_r_r *a,
+ void (*func)(TCGv_i128, TCGv_i128))
{
TCGv_i128 t;
- if (!avail_64(dc)) {
- return false;
- }
if (gen_trap_ifnofpu(dc)) {
return true;
}
@@ -4645,30 +4659,14 @@ static bool trans_FMOVq(DisasContext *dc, arg_FMOVq *a)
gen_op_clear_ieee_excp_and_FTT();
t = gen_load_fpr_Q(dc, a->rs);
+ func(t, t);
gen_store_fpr_Q(dc, a->rd, t);
return advance_pc(dc);
}
-static bool do_qq(DisasContext *dc, arg_r_r *a,
- void (*func)(TCGv_env))
-{
- if (gen_trap_ifnofpu(dc)) {
- return true;
- }
- if (gen_trap_float128(dc)) {
- return true;
- }
-
- gen_op_clear_ieee_excp_and_FTT();
- gen_op_load_fpr_QT1(QFPREG(a->rs));
- func(tcg_env);
- gen_op_store_QT0_fpr(QFPREG(a->rd));
- gen_update_fprs_dirty(dc, QFPREG(a->rd));
- return advance_pc(dc);
-}
-
-TRANS(FNEGq, 64, do_qq, a, gen_helper_fnegq)
-TRANS(FABSq, 64, do_qq, a, gen_helper_fabsq)
+TRANS(FMOVq, 64, do_qq, a, tcg_gen_mov_i128)
+TRANS(FNEGq, 64, do_qq, a, gen_op_fnegq)
+TRANS(FABSq, 64, do_qq, a, gen_op_fabsq)
static bool do_env_qq(DisasContext *dc, arg_r_r *a,
void (*func)(TCGv_env))
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 06/22] target/sparc: Use i128 for FSQRTq
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (4 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 05/22] target/sparc: Inline FNEG, FABS Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 07/22] target/sparc: Use i128 for FADDq, FSUBq, FMULq, FDIVq Richard Henderson
` (16 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 2 +-
target/sparc/fop_helper.c | 26 ++++++++++++++++++++++++--
target/sparc/translate.c | 12 +++++++-----
3 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 74a1575d21..eea2fa570c 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -43,7 +43,7 @@ DEF_HELPER_FLAGS_3(fcmps, TCG_CALL_NO_WG, tl, env, f32, f32)
DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, tl, env, f64, f64)
DEF_HELPER_FLAGS_3(fcmpes, TCG_CALL_NO_WG, tl, env, f32, f32)
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_1(fsqrtq, TCG_CALL_NO_RWG, void, env)
+DEF_HELPER_FLAGS_2(fsqrtq, TCG_CALL_NO_RWG, i128, env, i128)
DEF_HELPER_FLAGS_1(fcmpq, TCG_CALL_NO_WG, tl, env)
DEF_HELPER_FLAGS_1(fcmpeq, TCG_CALL_NO_WG, tl, env)
#ifdef TARGET_SPARC64
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index d6fb769769..d639e50965 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -26,6 +26,28 @@
#define QT0 (env->qt0)
#define QT1 (env->qt1)
+static inline float128 f128_in(Int128 i)
+{
+ union {
+ Int128 i;
+ float128 f;
+ } u;
+
+ u.i = i;
+ return u.f;
+}
+
+static inline Int128 f128_ret(float128 f)
+{
+ union {
+ Int128 i;
+ float128 f;
+ } u;
+
+ u.f = f;
+ return u.i;
+}
+
static target_ulong do_check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
{
target_ulong status = get_float_exception_flags(&env->fp_status);
@@ -222,9 +244,9 @@ float64 helper_fsqrtd(CPUSPARCState *env, float64 src)
return float64_sqrt(src, &env->fp_status);
}
-void helper_fsqrtq(CPUSPARCState *env)
+Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
{
- QT0 = float128_sqrt(QT1, &env->fp_status);
+ return f128_ret(float128_sqrt(f128_in(src), &env->fp_status));
}
#define GEN_FCMP(name, size, reg1, reg2, FS, E) \
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 254f185b83..6c08bf909e 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4669,8 +4669,10 @@ TRANS(FNEGq, 64, do_qq, a, gen_op_fnegq)
TRANS(FABSq, 64, do_qq, a, gen_op_fabsq)
static bool do_env_qq(DisasContext *dc, arg_r_r *a,
- void (*func)(TCGv_env))
+ void (*func)(TCGv_i128, TCGv_env, TCGv_i128))
{
+ TCGv_i128 t;
+
if (gen_trap_ifnofpu(dc)) {
return true;
}
@@ -4679,11 +4681,11 @@ static bool do_env_qq(DisasContext *dc, arg_r_r *a,
}
gen_op_clear_ieee_excp_and_FTT();
- gen_op_load_fpr_QT1(QFPREG(a->rs));
- func(tcg_env);
+
+ t = gen_load_fpr_Q(dc, a->rs);
+ func(t, tcg_env, t);
gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
- gen_op_store_QT0_fpr(QFPREG(a->rd));
- gen_update_fprs_dirty(dc, QFPREG(a->rd));
+ gen_store_fpr_Q(dc, a->rd, t);
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 07/22] target/sparc: Use i128 for FADDq, FSUBq, FMULq, FDIVq
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (5 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 06/22] target/sparc: Use i128 for FSQRTq Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 08/22] target/sparc: Use i128 for FqTOs, FqTOi Richard Henderson
` (15 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 12 +++++-------
target/sparc/fop_helper.c | 29 ++++++++++++++---------------
target/sparc/translate.c | 13 +++++++------
3 files changed, 26 insertions(+), 28 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index eea2fa570c..0a030fc908 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -67,17 +67,16 @@ DEF_HELPER_FLAGS_1(fcmpeq_fcc2, TCG_CALL_NO_WG, tl, env)
DEF_HELPER_FLAGS_1(fcmpeq_fcc3, TCG_CALL_NO_WG, tl, env)
#endif
DEF_HELPER_2(raise_exception, noreturn, env, int)
-#define F_HELPER_0_1(name) \
- DEF_HELPER_FLAGS_1(f ## name, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_RWG, f64, env, f64, f64)
DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_RWG, f64, env, f64, f64)
DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_RWG, f64, env, f64, f64)
DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_RWG, f64, env, f64, f64)
-F_HELPER_0_1(addq)
-F_HELPER_0_1(subq)
-F_HELPER_0_1(mulq)
-F_HELPER_0_1(divq)
+
+DEF_HELPER_FLAGS_3(faddq, TCG_CALL_NO_RWG, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(fsubq, TCG_CALL_NO_RWG, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(fmulq, TCG_CALL_NO_RWG, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(fdivq, TCG_CALL_NO_RWG, i128, env, i128, i128)
DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_RWG, f32, env, f32, f32)
DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_RWG, f32, env, f32, f32)
@@ -135,6 +134,5 @@ VIS_CMPHELPER(cmpeq)
VIS_CMPHELPER(cmple)
VIS_CMPHELPER(cmpne)
#endif
-#undef F_HELPER_0_1
#undef VIS_HELPER
#undef VIS_CMPHELPER
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index d639e50965..ceb64d802f 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -98,22 +98,22 @@ target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
return do_check_ieee_exceptions(env, GETPC());
}
-#define F_HELPER(name, p) void helper_f##name##p(CPUSPARCState *env)
-
-#define F_BINOP(name) \
+#define F_BINOP(name) \
float32 helper_f ## name ## s (CPUSPARCState *env, float32 src1, \
- float32 src2) \
- { \
- return float32_ ## name (src1, src2, &env->fp_status); \
- } \
+ float32 src2) \
+ { \
+ return float32_ ## name (src1, src2, &env->fp_status); \
+ } \
float64 helper_f ## name ## d (CPUSPARCState * env, float64 src1,\
- float64 src2) \
- { \
- return float64_ ## name (src1, src2, &env->fp_status); \
- } \
- F_HELPER(name, q) \
- { \
- QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \
+ float64 src2) \
+ { \
+ return float64_ ## name (src1, src2, &env->fp_status); \
+ } \
+ Int128 helper_f ## name ## q(CPUSPARCState * env, Int128 src1, \
+ Int128 src2) \
+ { \
+ return f128_ret(float128_ ## name (f128_in(src1), f128_in(src2), \
+ &env->fp_status)); \
}
F_BINOP(add);
@@ -168,7 +168,6 @@ void helper_fxtoq(CPUSPARCState *env, int64_t src)
QT0 = int64_to_float128(src, &env->fp_status);
}
#endif
-#undef F_HELPER
/* floating point conversion */
float32 helper_fdtos(CPUSPARCState *env, float64 src)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 6c08bf909e..437f54ff19 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4976,8 +4976,10 @@ static bool do_dddd(DisasContext *dc, arg_r_r_r *a,
TRANS(PDIST, VIS1, do_dddd, a, gen_helper_pdist)
static bool do_env_qqq(DisasContext *dc, arg_r_r_r *a,
- void (*func)(TCGv_env))
+ void (*func)(TCGv_i128, TCGv_env, TCGv_i128, TCGv_i128))
{
+ TCGv_i128 src1, src2;
+
if (gen_trap_ifnofpu(dc)) {
return true;
}
@@ -4986,12 +4988,11 @@ static bool do_env_qqq(DisasContext *dc, arg_r_r_r *a,
}
gen_op_clear_ieee_excp_and_FTT();
- gen_op_load_fpr_QT0(QFPREG(a->rs1));
- gen_op_load_fpr_QT1(QFPREG(a->rs2));
- func(tcg_env);
+ src1 = gen_load_fpr_Q(dc, a->rs1);
+ src2 = gen_load_fpr_Q(dc, a->rs2);
+ func(src1, tcg_env, src1, src2);
gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
- gen_op_store_QT0_fpr(QFPREG(a->rd));
- gen_update_fprs_dirty(dc, QFPREG(a->rd));
+ gen_store_fpr_Q(dc, a->rd, src1);
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 08/22] target/sparc: Use i128 for FqTOs, FqTOi
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (6 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 07/22] target/sparc: Use i128 for FADDq, FSUBq, FMULq, FDIVq Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 09/22] target/sparc: Use i128 for FqTOd, FqTOx Richard Henderson
` (14 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 4 ++--
target/sparc/fop_helper.c | 8 ++++----
target/sparc/translate.c | 7 ++++---
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 0a030fc908..e770107eb0 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -98,13 +98,13 @@ DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_RWG, void, env, s64)
#endif
DEF_HELPER_FLAGS_2(fdtos, TCG_CALL_NO_RWG, f32, env, f64)
DEF_HELPER_FLAGS_2(fstod, TCG_CALL_NO_RWG, f64, env, f32)
-DEF_HELPER_FLAGS_1(fqtos, TCG_CALL_NO_RWG, f32, env)
+DEF_HELPER_FLAGS_2(fqtos, TCG_CALL_NO_RWG, f32, env, i128)
DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_RWG, void, env, f32)
DEF_HELPER_FLAGS_1(fqtod, TCG_CALL_NO_RWG, f64, env)
DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_RWG, void, env, f64)
DEF_HELPER_FLAGS_2(fstoi, TCG_CALL_NO_RWG, s32, env, f32)
DEF_HELPER_FLAGS_2(fdtoi, TCG_CALL_NO_RWG, s32, env, f64)
-DEF_HELPER_FLAGS_1(fqtoi, TCG_CALL_NO_RWG, s32, env)
+DEF_HELPER_FLAGS_2(fqtoi, TCG_CALL_NO_RWG, s32, env, i128)
#ifdef TARGET_SPARC64
DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_RWG, s64, env, f32)
DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_RWG, s64, env, f64)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index ceb64d802f..657a14575d 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -180,9 +180,9 @@ float64 helper_fstod(CPUSPARCState *env, float32 src)
return float32_to_float64(src, &env->fp_status);
}
-float32 helper_fqtos(CPUSPARCState *env)
+float32 helper_fqtos(CPUSPARCState *env, Int128 src)
{
- return float128_to_float32(QT1, &env->fp_status);
+ return float128_to_float32(f128_in(src), &env->fp_status);
}
void helper_fstoq(CPUSPARCState *env, float32 src)
@@ -211,9 +211,9 @@ int32_t helper_fdtoi(CPUSPARCState *env, float64 src)
return float64_to_int32_round_to_zero(src, &env->fp_status);
}
-int32_t helper_fqtoi(CPUSPARCState *env)
+int32_t helper_fqtoi(CPUSPARCState *env, Int128 src)
{
- return float128_to_int32_round_to_zero(QT1, &env->fp_status);
+ return float128_to_int32_round_to_zero(f128_in(src), &env->fp_status);
}
#ifdef TARGET_SPARC64
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 437f54ff19..34a774c8ef 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4692,8 +4692,9 @@ static bool do_env_qq(DisasContext *dc, arg_r_r *a,
TRANS(FSQRTq, ALL, do_env_qq, a, gen_helper_fsqrtq)
static bool do_env_fq(DisasContext *dc, arg_r_r *a,
- void (*func)(TCGv_i32, TCGv_env))
+ void (*func)(TCGv_i32, TCGv_env, TCGv_i128))
{
+ TCGv_i128 src;
TCGv_i32 dst;
if (gen_trap_ifnofpu(dc)) {
@@ -4704,9 +4705,9 @@ static bool do_env_fq(DisasContext *dc, arg_r_r *a,
}
gen_op_clear_ieee_excp_and_FTT();
- gen_op_load_fpr_QT1(QFPREG(a->rs));
+ src = gen_load_fpr_Q(dc, a->rs);
dst = tcg_temp_new_i32();
- func(dst, tcg_env);
+ func(dst, tcg_env, src);
gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_F(dc, a->rd, dst);
return advance_pc(dc);
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 09/22] target/sparc: Use i128 for FqTOd, FqTOx
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (7 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 08/22] target/sparc: Use i128 for FqTOs, FqTOi Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 10/22] target/sparc: Use i128 for FCMPq, FCMPEq Richard Henderson
` (13 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 4 ++--
target/sparc/fop_helper.c | 8 ++++----
target/sparc/translate.c | 7 ++++---
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index e770107eb0..4cb3451878 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -100,7 +100,7 @@ DEF_HELPER_FLAGS_2(fdtos, TCG_CALL_NO_RWG, f32, env, f64)
DEF_HELPER_FLAGS_2(fstod, TCG_CALL_NO_RWG, f64, env, f32)
DEF_HELPER_FLAGS_2(fqtos, TCG_CALL_NO_RWG, f32, env, i128)
DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_RWG, void, env, f32)
-DEF_HELPER_FLAGS_1(fqtod, TCG_CALL_NO_RWG, f64, env)
+DEF_HELPER_FLAGS_2(fqtod, TCG_CALL_NO_RWG, f64, env, i128)
DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_RWG, void, env, f64)
DEF_HELPER_FLAGS_2(fstoi, TCG_CALL_NO_RWG, s32, env, f32)
DEF_HELPER_FLAGS_2(fdtoi, TCG_CALL_NO_RWG, s32, env, f64)
@@ -108,7 +108,7 @@ DEF_HELPER_FLAGS_2(fqtoi, TCG_CALL_NO_RWG, s32, env, i128)
#ifdef TARGET_SPARC64
DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_RWG, s64, env, f32)
DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_RWG, s64, env, f64)
-DEF_HELPER_FLAGS_1(fqtox, TCG_CALL_NO_RWG, s64, env)
+DEF_HELPER_FLAGS_2(fqtox, TCG_CALL_NO_RWG, s64, env, i128)
DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 657a14575d..9f39b933e8 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -190,9 +190,9 @@ void helper_fstoq(CPUSPARCState *env, float32 src)
QT0 = float32_to_float128(src, &env->fp_status);
}
-float64 helper_fqtod(CPUSPARCState *env)
+float64 helper_fqtod(CPUSPARCState *env, Int128 src)
{
- return float128_to_float64(QT1, &env->fp_status);
+ return float128_to_float64(f128_in(src), &env->fp_status);
}
void helper_fdtoq(CPUSPARCState *env, float64 src)
@@ -227,9 +227,9 @@ int64_t helper_fdtox(CPUSPARCState *env, float64 src)
return float64_to_int64_round_to_zero(src, &env->fp_status);
}
-int64_t helper_fqtox(CPUSPARCState *env)
+int64_t helper_fqtox(CPUSPARCState *env, Int128 src)
{
- return float128_to_int64_round_to_zero(QT1, &env->fp_status);
+ return float128_to_int64_round_to_zero(f128_in(src), &env->fp_status);
}
#endif
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 34a774c8ef..ba0b7f32d2 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4717,8 +4717,9 @@ TRANS(FqTOs, ALL, do_env_fq, a, gen_helper_fqtos)
TRANS(FqTOi, ALL, do_env_fq, a, gen_helper_fqtoi)
static bool do_env_dq(DisasContext *dc, arg_r_r *a,
- void (*func)(TCGv_i64, TCGv_env))
+ void (*func)(TCGv_i64, TCGv_env, TCGv_i128))
{
+ TCGv_i128 src;
TCGv_i64 dst;
if (gen_trap_ifnofpu(dc)) {
@@ -4729,9 +4730,9 @@ static bool do_env_dq(DisasContext *dc, arg_r_r *a,
}
gen_op_clear_ieee_excp_and_FTT();
- gen_op_load_fpr_QT1(QFPREG(a->rs));
+ src = gen_load_fpr_Q(dc, a->rs);
dst = gen_dest_fpr_D(dc, a->rd);
- func(dst, tcg_env);
+ func(dst, tcg_env, src);
gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_D(dc, a->rd, dst);
return advance_pc(dc);
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 10/22] target/sparc: Use i128 for FCMPq, FCMPEq
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (8 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 09/22] target/sparc: Use i128 for FqTOd, FqTOx Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 11/22] target/sparc: Use i128 for FsTOq, FiTOq Richard Henderson
` (12 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 16 ++++++------
target/sparc/fop_helper.c | 23 +++++++++--------
target/sparc/translate.c | 54 +++++++++++++++------------------------
3 files changed, 41 insertions(+), 52 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 4cb3451878..7caae9a441 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -44,8 +44,8 @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, tl, env, f64, f64)
DEF_HELPER_FLAGS_3(fcmpes, TCG_CALL_NO_WG, tl, env, f32, f32)
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, tl, env, f64, f64)
DEF_HELPER_FLAGS_2(fsqrtq, TCG_CALL_NO_RWG, i128, env, i128)
-DEF_HELPER_FLAGS_1(fcmpq, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpeq, TCG_CALL_NO_WG, tl, env)
+DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, tl, env, i128, i128)
#ifdef TARGET_SPARC64
DEF_HELPER_FLAGS_3(fcmps_fcc1, TCG_CALL_NO_WG, tl, env, f32, f32)
DEF_HELPER_FLAGS_3(fcmps_fcc2, TCG_CALL_NO_WG, tl, env, f32, f32)
@@ -59,12 +59,12 @@ DEF_HELPER_FLAGS_3(fcmpes_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32)
DEF_HELPER_FLAGS_3(fcmped_fcc1, TCG_CALL_NO_WG, tl, env, f64, f64)
DEF_HELPER_FLAGS_3(fcmped_fcc2, TCG_CALL_NO_WG, tl, env, f64, f64)
DEF_HELPER_FLAGS_3(fcmped_fcc3, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_1(fcmpq_fcc1, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpq_fcc2, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpq_fcc3, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpeq_fcc1, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpeq_fcc2, TCG_CALL_NO_WG, tl, env)
-DEF_HELPER_FLAGS_1(fcmpeq_fcc3, TCG_CALL_NO_WG, tl, env)
+DEF_HELPER_FLAGS_3(fcmpq_fcc1, TCG_CALL_NO_WG, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpq_fcc2, TCG_CALL_NO_WG, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpq_fcc3, TCG_CALL_NO_WG, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq_fcc1, TCG_CALL_NO_WG, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq_fcc2, TCG_CALL_NO_WG, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq_fcc3, TCG_CALL_NO_WG, tl, env, i128, i128)
#endif
DEF_HELPER_2(raise_exception, noreturn, env, int)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 9f39b933e8..faf75e651f 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -248,9 +248,12 @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
return f128_ret(float128_sqrt(f128_in(src), &env->fp_status));
}
-#define GEN_FCMP(name, size, reg1, reg2, FS, E) \
- target_ulong glue(helper_, name) (CPUSPARCState *env) \
+#define GEN_FCMP(name, size, FS, E) \
+ target_ulong glue(helper_, name) (CPUSPARCState *env, \
+ Int128 src1, Int128 src2) \
{ \
+ float128 reg1 = f128_in(src1); \
+ float128 reg2 = f128_in(src2); \
FloatRelation ret; \
target_ulong fsr; \
if (E) { \
@@ -316,33 +319,33 @@ GEN_FCMP_T(fcmpd, float64, 0, 0);
GEN_FCMP_T(fcmpes, float32, 0, 1);
GEN_FCMP_T(fcmped, float64, 0, 1);
-GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0);
-GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1);
+GEN_FCMP(fcmpq, float128, 0, 0);
+GEN_FCMP(fcmpeq, float128, 0, 1);
#ifdef TARGET_SPARC64
GEN_FCMP_T(fcmps_fcc1, float32, 22, 0);
GEN_FCMP_T(fcmpd_fcc1, float64, 22, 0);
-GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
+GEN_FCMP(fcmpq_fcc1, float128, 22, 0);
GEN_FCMP_T(fcmps_fcc2, float32, 24, 0);
GEN_FCMP_T(fcmpd_fcc2, float64, 24, 0);
-GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
+GEN_FCMP(fcmpq_fcc2, float128, 24, 0);
GEN_FCMP_T(fcmps_fcc3, float32, 26, 0);
GEN_FCMP_T(fcmpd_fcc3, float64, 26, 0);
-GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
+GEN_FCMP(fcmpq_fcc3, float128, 26, 0);
GEN_FCMP_T(fcmpes_fcc1, float32, 22, 1);
GEN_FCMP_T(fcmped_fcc1, float64, 22, 1);
-GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
+GEN_FCMP(fcmpeq_fcc1, float128, 22, 1);
GEN_FCMP_T(fcmpes_fcc2, float32, 24, 1);
GEN_FCMP_T(fcmped_fcc2, float64, 24, 1);
-GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
+GEN_FCMP(fcmpeq_fcc2, float128, 24, 1);
GEN_FCMP_T(fcmpes_fcc3, float32, 26, 1);
GEN_FCMP_T(fcmped_fcc3, float64, 26, 1);
-GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
+GEN_FCMP(fcmpeq_fcc3, float128, 26, 1);
#endif
#undef GEN_FCMP_T
#undef GEN_FCMP
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index ba0b7f32d2..d4eea47c33 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -276,22 +276,6 @@ static void gen_store_fpr_Q(DisasContext *dc, unsigned int dst, TCGv_i128 v)
gen_update_fprs_dirty(dc, dst);
}
-static void gen_op_load_fpr_QT0(unsigned int src)
-{
- tcg_gen_st_i64(cpu_fpr[src / 2], tcg_env, offsetof(CPUSPARCState, qt0) +
- offsetof(CPU_QuadU, ll.upper));
- tcg_gen_st_i64(cpu_fpr[src/2 + 1], tcg_env, offsetof(CPUSPARCState, qt0) +
- offsetof(CPU_QuadU, ll.lower));
-}
-
-static void gen_op_load_fpr_QT1(unsigned int src)
-{
- tcg_gen_st_i64(cpu_fpr[src / 2], tcg_env, offsetof(CPUSPARCState, qt1) +
- offsetof(CPU_QuadU, ll.upper));
- tcg_gen_st_i64(cpu_fpr[src/2 + 1], tcg_env, offsetof(CPUSPARCState, qt1) +
- offsetof(CPU_QuadU, ll.lower));
-}
-
static void gen_op_store_QT0_fpr(unsigned int dst)
{
tcg_gen_ld_i64(cpu_fpr[dst / 2], tcg_env, offsetof(CPUSPARCState, qt0) +
@@ -1319,20 +1303,20 @@ static void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
}
}
-static void gen_op_fcmpq(int fccno)
+static void gen_op_fcmpq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
{
switch (fccno) {
case 0:
- gen_helper_fcmpq(cpu_fsr, tcg_env);
+ gen_helper_fcmpq(cpu_fsr, tcg_env, r_rs1, r_rs2);
break;
case 1:
- gen_helper_fcmpq_fcc1(cpu_fsr, tcg_env);
+ gen_helper_fcmpq_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
break;
case 2:
- gen_helper_fcmpq_fcc2(cpu_fsr, tcg_env);
+ gen_helper_fcmpq_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
break;
case 3:
- gen_helper_fcmpq_fcc3(cpu_fsr, tcg_env);
+ gen_helper_fcmpq_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
break;
}
}
@@ -1373,20 +1357,20 @@ static void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
}
}
-static void gen_op_fcmpeq(int fccno)
+static void gen_op_fcmpeq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
{
switch (fccno) {
case 0:
- gen_helper_fcmpeq(cpu_fsr, tcg_env);
+ gen_helper_fcmpeq(cpu_fsr, tcg_env, r_rs1, r_rs2);
break;
case 1:
- gen_helper_fcmpeq_fcc1(cpu_fsr, tcg_env);
+ gen_helper_fcmpeq_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
break;
case 2:
- gen_helper_fcmpeq_fcc2(cpu_fsr, tcg_env);
+ gen_helper_fcmpeq_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
break;
case 3:
- gen_helper_fcmpeq_fcc3(cpu_fsr, tcg_env);
+ gen_helper_fcmpeq_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
break;
}
}
@@ -1403,9 +1387,9 @@ static void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
gen_helper_fcmpd(cpu_fsr, tcg_env, r_rs1, r_rs2);
}
-static void gen_op_fcmpq(int fccno)
+static void gen_op_fcmpq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
{
- gen_helper_fcmpq(cpu_fsr, tcg_env);
+ gen_helper_fcmpq(cpu_fsr, tcg_env, r_rs1, r_rs2);
}
static void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
@@ -1418,9 +1402,9 @@ static void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
gen_helper_fcmped(cpu_fsr, tcg_env, r_rs1, r_rs2);
}
-static void gen_op_fcmpeq(int fccno)
+static void gen_op_fcmpeq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
{
- gen_helper_fcmpeq(cpu_fsr, tcg_env);
+ gen_helper_fcmpeq(cpu_fsr, tcg_env, r_rs1, r_rs2);
}
#endif
@@ -5144,6 +5128,8 @@ TRANS(FCMPEd, ALL, do_fcmpd, a, true)
static bool do_fcmpq(DisasContext *dc, arg_FCMPq *a, bool e)
{
+ TCGv_i128 src1, src2;
+
if (avail_32(dc) && a->cc != 0) {
return false;
}
@@ -5155,12 +5141,12 @@ static bool do_fcmpq(DisasContext *dc, arg_FCMPq *a, bool e)
}
gen_op_clear_ieee_excp_and_FTT();
- gen_op_load_fpr_QT0(QFPREG(a->rs1));
- gen_op_load_fpr_QT1(QFPREG(a->rs2));
+ src1 = gen_load_fpr_Q(dc, a->rs1);
+ src2 = gen_load_fpr_Q(dc, a->rs2);
if (e) {
- gen_op_fcmpeq(a->cc);
+ gen_op_fcmpeq(a->cc, src1, src2);
} else {
- gen_op_fcmpq(a->cc);
+ gen_op_fcmpq(a->cc, src1, src2);
}
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 11/22] target/sparc: Use i128 for FsTOq, FiTOq
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (9 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 10/22] target/sparc: Use i128 for FCMPq, FCMPEq Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 12/22] target/sparc: Use i128 for FdTOq, FxTOq Richard Henderson
` (11 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 4 ++--
target/sparc/fop_helper.c | 8 ++++----
target/sparc/translate.c | 9 +++++----
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 7caae9a441..5e93342583 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -87,7 +87,7 @@ DEF_HELPER_FLAGS_3(fsmuld, TCG_CALL_NO_RWG, f64, env, f32, f32)
DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_RWG, void, env, f64, f64)
DEF_HELPER_FLAGS_2(fitod, TCG_CALL_NO_RWG_SE, f64, env, s32)
-DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_RWG, void, env, s32)
+DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_RWG, i128, env, s32)
DEF_HELPER_FLAGS_2(fitos, TCG_CALL_NO_RWG, f32, env, s32)
@@ -99,7 +99,7 @@ DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_RWG, void, env, s64)
DEF_HELPER_FLAGS_2(fdtos, TCG_CALL_NO_RWG, f32, env, f64)
DEF_HELPER_FLAGS_2(fstod, TCG_CALL_NO_RWG, f64, env, f32)
DEF_HELPER_FLAGS_2(fqtos, TCG_CALL_NO_RWG, f32, env, i128)
-DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_RWG, void, env, f32)
+DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_RWG, i128, env, f32)
DEF_HELPER_FLAGS_2(fqtod, TCG_CALL_NO_RWG, f64, env, i128)
DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_RWG, void, env, f64)
DEF_HELPER_FLAGS_2(fstoi, TCG_CALL_NO_RWG, s32, env, f32)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index faf75e651f..c7dc835d28 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -147,9 +147,9 @@ float64 helper_fitod(CPUSPARCState *env, int32_t src)
return int32_to_float64(src, &env->fp_status);
}
-void helper_fitoq(CPUSPARCState *env, int32_t src)
+Int128 helper_fitoq(CPUSPARCState *env, int32_t src)
{
- QT0 = int32_to_float128(src, &env->fp_status);
+ return f128_ret(int32_to_float128(src, &env->fp_status));
}
#ifdef TARGET_SPARC64
@@ -185,9 +185,9 @@ float32 helper_fqtos(CPUSPARCState *env, Int128 src)
return float128_to_float32(f128_in(src), &env->fp_status);
}
-void helper_fstoq(CPUSPARCState *env, float32 src)
+Int128 helper_fstoq(CPUSPARCState *env, float32 src)
{
- QT0 = float32_to_float128(src, &env->fp_status);
+ return f128_ret(float32_to_float128(src, &env->fp_status));
}
float64 helper_fqtod(CPUSPARCState *env, Int128 src)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index d4eea47c33..1f96990316 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4726,9 +4726,10 @@ TRANS(FqTOd, ALL, do_env_dq, a, gen_helper_fqtod)
TRANS(FqTOx, 64, do_env_dq, a, gen_helper_fqtox)
static bool do_env_qf(DisasContext *dc, arg_r_r *a,
- void (*func)(TCGv_env, TCGv_i32))
+ void (*func)(TCGv_i128, TCGv_env, TCGv_i32))
{
TCGv_i32 src;
+ TCGv_i128 dst;
if (gen_trap_ifnofpu(dc)) {
return true;
@@ -4739,9 +4740,9 @@ static bool do_env_qf(DisasContext *dc, arg_r_r *a,
gen_op_clear_ieee_excp_and_FTT();
src = gen_load_fpr_F(dc, a->rs);
- func(tcg_env, src);
- gen_op_store_QT0_fpr(QFPREG(a->rd));
- gen_update_fprs_dirty(dc, QFPREG(a->rd));
+ dst = tcg_temp_new_i128();
+ func(dst, tcg_env, src);
+ gen_store_fpr_Q(dc, a->rd, dst);
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 12/22] target/sparc: Use i128 for FdTOq, FxTOq
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (10 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 11/22] target/sparc: Use i128 for FsTOq, FiTOq Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 13/22] target/sparc: Use i128 for Fdmulq Richard Henderson
` (10 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 4 ++--
target/sparc/fop_helper.c | 8 ++++----
target/sparc/translate.c | 9 +++++----
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 5e93342583..20f67f89b0 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -94,14 +94,14 @@ DEF_HELPER_FLAGS_2(fitos, TCG_CALL_NO_RWG, f32, env, s32)
#ifdef TARGET_SPARC64
DEF_HELPER_FLAGS_2(fxtos, TCG_CALL_NO_RWG, f32, env, s64)
DEF_HELPER_FLAGS_2(fxtod, TCG_CALL_NO_RWG, f64, env, s64)
-DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_RWG, void, env, s64)
+DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_RWG, i128, env, s64)
#endif
DEF_HELPER_FLAGS_2(fdtos, TCG_CALL_NO_RWG, f32, env, f64)
DEF_HELPER_FLAGS_2(fstod, TCG_CALL_NO_RWG, f64, env, f32)
DEF_HELPER_FLAGS_2(fqtos, TCG_CALL_NO_RWG, f32, env, i128)
DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_RWG, i128, env, f32)
DEF_HELPER_FLAGS_2(fqtod, TCG_CALL_NO_RWG, f64, env, i128)
-DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_RWG, void, env, f64)
+DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_RWG, i128, env, f64)
DEF_HELPER_FLAGS_2(fstoi, TCG_CALL_NO_RWG, s32, env, f32)
DEF_HELPER_FLAGS_2(fdtoi, TCG_CALL_NO_RWG, s32, env, f64)
DEF_HELPER_FLAGS_2(fqtoi, TCG_CALL_NO_RWG, s32, env, i128)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index c7dc835d28..9a0110e201 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -163,9 +163,9 @@ float64 helper_fxtod(CPUSPARCState *env, int64_t src)
return int64_to_float64(src, &env->fp_status);
}
-void helper_fxtoq(CPUSPARCState *env, int64_t src)
+Int128 helper_fxtoq(CPUSPARCState *env, int64_t src)
{
- QT0 = int64_to_float128(src, &env->fp_status);
+ return f128_ret(int64_to_float128(src, &env->fp_status));
}
#endif
@@ -195,9 +195,9 @@ float64 helper_fqtod(CPUSPARCState *env, Int128 src)
return float128_to_float64(f128_in(src), &env->fp_status);
}
-void helper_fdtoq(CPUSPARCState *env, float64 src)
+Int128 helper_fdtoq(CPUSPARCState *env, float64 src)
{
- QT0 = float64_to_float128(src, &env->fp_status);
+ return f128_ret(float64_to_float128(src, &env->fp_status));
}
/* Float to integer conversion. */
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 1f96990316..e01cbc5bcb 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4750,9 +4750,10 @@ TRANS(FiTOq, ALL, do_env_qf, a, gen_helper_fitoq)
TRANS(FsTOq, ALL, do_env_qf, a, gen_helper_fstoq)
static bool do_env_qd(DisasContext *dc, arg_r_r *a,
- void (*func)(TCGv_env, TCGv_i64))
+ void (*func)(TCGv_i128, TCGv_env, TCGv_i64))
{
TCGv_i64 src;
+ TCGv_i128 dst;
if (gen_trap_ifnofpu(dc)) {
return true;
@@ -4763,9 +4764,9 @@ static bool do_env_qd(DisasContext *dc, arg_r_r *a,
gen_op_clear_ieee_excp_and_FTT();
src = gen_load_fpr_D(dc, a->rs);
- func(tcg_env, src);
- gen_op_store_QT0_fpr(QFPREG(a->rd));
- gen_update_fprs_dirty(dc, QFPREG(a->rd));
+ dst = tcg_temp_new_i128();
+ func(dst, tcg_env, src);
+ gen_store_fpr_Q(dc, a->rd, dst);
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 13/22] target/sparc: Use i128 for Fdmulq
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (11 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 12/22] target/sparc: Use i128 for FdTOq, FxTOq Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 14/22] target/sparc: Remove qt0, qt1 temporaries Richard Henderson
` (9 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 2 +-
target/sparc/fop_helper.c | 8 ++++----
target/sparc/translate.c | 15 ++++-----------
3 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 20f67f89b0..f7aeb31169 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -84,7 +84,7 @@ DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_RWG, f32, env, f32, f32)
DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_RWG, f32, env, f32, f32)
DEF_HELPER_FLAGS_3(fsmuld, TCG_CALL_NO_RWG, f64, env, f32, f32)
-DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_RWG, void, env, f64, f64)
+DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_RWG, i128, env, f64, f64)
DEF_HELPER_FLAGS_2(fitod, TCG_CALL_NO_RWG_SE, f64, env, s32)
DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_RWG, i128, env, s32)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 9a0110e201..cd9b212597 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -129,11 +129,11 @@ float64 helper_fsmuld(CPUSPARCState *env, float32 src1, float32 src2)
&env->fp_status);
}
-void helper_fdmulq(CPUSPARCState *env, float64 src1, float64 src2)
+Int128 helper_fdmulq(CPUSPARCState *env, float64 src1, float64 src2)
{
- QT0 = float128_mul(float64_to_float128(src1, &env->fp_status),
- float64_to_float128(src2, &env->fp_status),
- &env->fp_status);
+ return f128_ret(float128_mul(float64_to_float128(src1, &env->fp_status),
+ float64_to_float128(src2, &env->fp_status),
+ &env->fp_status));
}
/* Integer to float conversion. */
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index e01cbc5bcb..99482df256 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -276,14 +276,6 @@ static void gen_store_fpr_Q(DisasContext *dc, unsigned int dst, TCGv_i128 v)
gen_update_fprs_dirty(dc, dst);
}
-static void gen_op_store_QT0_fpr(unsigned int dst)
-{
- tcg_gen_ld_i64(cpu_fpr[dst / 2], tcg_env, offsetof(CPUSPARCState, qt0) +
- offsetof(CPU_QuadU, ll.upper));
- tcg_gen_ld_i64(cpu_fpr[dst/2 + 1], tcg_env, offsetof(CPUSPARCState, qt0) +
- offsetof(CPU_QuadU, ll.lower));
-}
-
/* moves */
#ifdef CONFIG_USER_ONLY
#define supervisor(dc) 0
@@ -4992,6 +4984,7 @@ TRANS(FDIVq, ALL, do_env_qqq, a, gen_helper_fdivq)
static bool trans_FdMULq(DisasContext *dc, arg_r_r_r *a)
{
TCGv_i64 src1, src2;
+ TCGv_i128 dst;
if (gen_trap_ifnofpu(dc)) {
return true;
@@ -5003,10 +4996,10 @@ static bool trans_FdMULq(DisasContext *dc, arg_r_r_r *a)
gen_op_clear_ieee_excp_and_FTT();
src1 = gen_load_fpr_D(dc, a->rs1);
src2 = gen_load_fpr_D(dc, a->rs2);
- gen_helper_fdmulq(tcg_env, src1, src2);
+ dst = tcg_temp_new_i128();
+ gen_helper_fdmulq(dst, tcg_env, src1, src2);
gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
- gen_op_store_QT0_fpr(QFPREG(a->rd));
- gen_update_fprs_dirty(dc, QFPREG(a->rd));
+ gen_store_fpr_Q(dc, a->rd, dst);
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 14/22] target/sparc: Remove qt0, qt1 temporaries
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (12 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 13/22] target/sparc: Use i128 for Fdmulq Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 15/22] target/sparc: Introduce cpu_get_fsr, cpu_put_fsr Richard Henderson
` (8 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
These are no longer used for passing data to/from helpers.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/cpu.h | 2 --
target/sparc/fop_helper.c | 3 ---
target/sparc/ldst_helper.c | 3 ---
3 files changed, 8 deletions(-)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 3e361a5b75..446b38f3df 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -509,8 +509,6 @@ struct CPUArchState {
uint64_t mmubpregs[4];
uint64_t prom_addr;
#endif
- /* temporary float registers */
- float128 qt0, qt1;
float_status fp_status;
#if defined(TARGET_SPARC64)
#define MAXTL_MAX 8
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index cd9b212597..7353a61237 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -23,9 +23,6 @@
#include "exec/helper-proto.h"
#include "fpu/softfloat.h"
-#define QT0 (env->qt0)
-#define QT1 (env->qt1)
-
static inline float128 f128_in(Int128 i)
{
union {
diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index 09066d5487..fe984d44d7 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -66,9 +66,6 @@
#endif
#endif
-#define QT0 (env->qt0)
-#define QT1 (env->qt1)
-
#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
/* Calculates TSB pointer value for fault page size
* UltraSPARC IIi has fixed sizes (8k or 64k) for the page pointers
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 15/22] target/sparc: Introduce cpu_get_fsr, cpu_put_fsr
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (13 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 14/22] target/sparc: Remove qt0, qt1 temporaries Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2024-01-30 8:10 ` Philippe Mathieu-Daudé
2023-11-03 17:38 ` [PATCH 16/22] target/split: Split ver from env->fsr Richard Henderson
` (7 subsequent siblings)
22 siblings, 1 reply; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/cpu.h | 4 +++-
target/sparc/helper.h | 1 +
linux-user/sparc/cpu_loop.c | 2 +-
linux-user/sparc/signal.c | 14 +++++++++-----
target/sparc/cpu.c | 5 +++--
target/sparc/fop_helper.c | 21 ++++++++++++++++++--
target/sparc/gdbstub.c | 8 ++++----
target/sparc/machine.c | 38 +++++++++++++++++++++++++++++++++++--
target/sparc/translate.c | 7 ++++++-
9 files changed, 82 insertions(+), 18 deletions(-)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 446b38f3df..33c7d31fef 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -605,7 +605,9 @@ void sparc_restore_state_to_opc(CPUState *cs,
const TranslationBlock *tb,
const uint64_t *data);
-/* cpu-exec.c */
+/* fop_helper.c */
+target_ulong cpu_get_fsr(CPUSPARCState *);
+void cpu_put_fsr(CPUSPARCState *, target_ulong);
/* win_helper.c */
target_ulong cpu_get_psr(CPUSPARCState *env1);
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index f7aeb31169..cc8db50d75 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -36,6 +36,7 @@ DEF_HELPER_FLAGS_4(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, i32)
DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32)
#endif
DEF_HELPER_FLAGS_1(check_ieee_exceptions, TCG_CALL_NO_WG, tl, env)
+DEF_HELPER_FLAGS_1(get_fsr, TCG_CALL_NO_WG_SE, tl, env)
DEF_HELPER_FLAGS_2(set_fsr, TCG_CALL_NO_RWG, void, env, tl)
DEF_HELPER_FLAGS_2(fsqrts, TCG_CALL_NO_RWG, f32, env, f32)
DEF_HELPER_FLAGS_2(fsqrtd, TCG_CALL_NO_RWG, f64, env, f64)
diff --git a/linux-user/sparc/cpu_loop.c b/linux-user/sparc/cpu_loop.c
index 3c1bde00dd..50424a54df 100644
--- a/linux-user/sparc/cpu_loop.c
+++ b/linux-user/sparc/cpu_loop.c
@@ -293,7 +293,7 @@ void cpu_loop (CPUSPARCState *env)
case TT_FP_EXCP:
{
int code = TARGET_FPE_FLTUNK;
- target_ulong fsr = env->fsr;
+ target_ulong fsr = cpu_get_fsr(env);
if ((fsr & FSR_FTT_MASK) == FSR_FTT_IEEE_EXCP) {
if (fsr & FSR_NVC) {
diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c
index dfcae707e0..c2dc1000e2 100644
--- a/linux-user/sparc/signal.c
+++ b/linux-user/sparc/signal.c
@@ -199,20 +199,21 @@ static void save_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
for (i = 0; i < 32; ++i) {
__put_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
}
- __put_user(env->fsr, &fpu->si_fsr);
+ __put_user(cpu_get_fsr(env), &fpu->si_fsr);
__put_user(env->gsr, &fpu->si_gsr);
__put_user(env->fprs, &fpu->si_fprs);
#else
for (i = 0; i < 16; ++i) {
__put_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
}
- __put_user(env->fsr, &fpu->si_fsr);
+ __put_user(cpu_get_fsr(env), &fpu->si_fsr);
__put_user(0, &fpu->si_fpqdepth);
#endif
}
static void restore_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
{
+ target_ulong fsr;
int i;
#ifdef TARGET_SPARC64
@@ -230,15 +231,16 @@ static void restore_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
__get_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
}
}
- __get_user(env->fsr, &fpu->si_fsr);
__get_user(env->gsr, &fpu->si_gsr);
env->fprs |= fprs;
#else
for (i = 0; i < 16; ++i) {
__get_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
}
- __get_user(env->fsr, &fpu->si_fsr);
#endif
+
+ __get_user(fsr, &fpu->si_fsr);
+ cpu_put_fsr(env, fsr);
}
#ifdef TARGET_ARCH_HAS_SETUP_FRAME
@@ -662,6 +664,7 @@ void sparc64_set_context(CPUSPARCState *env)
__get_user(fenab, &(fpup->mcfpu_enab));
if (fenab) {
abi_ulong fprs;
+ abi_ulong fsr;
/*
* We use the FPRS from the guest only in deciding whether
@@ -690,7 +693,8 @@ void sparc64_set_context(CPUSPARCState *env)
__get_user(env->fpr[i].ll, &(fpup->mcfpu_fregs.dregs[i]));
}
}
- __get_user(env->fsr, &(fpup->mcfpu_fsr));
+ __get_user(fsr, &(fpup->mcfpu_fsr));
+ cpu_put_fsr(env, fsr);
__get_user(env->gsr, &(fpup->mcfpu_gsr));
}
unlock_user_struct(ucp, ucp_addr, 0);
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index befa7fc4eb..69dfa1dd4e 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -670,7 +670,7 @@ static void sparc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
env->cansave, env->canrestore, env->otherwin, env->wstate,
env->cleanwin, env->nwindows - 1 - env->cwp);
qemu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: %016x\n",
- env->fsr, env->y, env->fprs);
+ cpu_get_fsr(env), env->y, env->fprs);
#else
qemu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
@@ -679,7 +679,7 @@ static void sparc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
env->wim);
qemu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
- env->fsr, env->y);
+ cpu_get_fsr(env), env->y);
#endif
qemu_fprintf(f, "\n");
}
@@ -770,6 +770,7 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
env->version |= env->def.maxtl << 8;
env->version |= env->def.nwindows - 1;
#endif
+ cpu_put_fsr(env, 0);
cpu_exec_realizefn(cs, &local_err);
if (local_err != NULL) {
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 7353a61237..70b38011d2 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -347,10 +347,22 @@ GEN_FCMP(fcmpeq_fcc3, float128, 26, 1);
#undef GEN_FCMP_T
#undef GEN_FCMP
-static void set_fsr(CPUSPARCState *env, target_ulong fsr)
+target_ulong cpu_get_fsr(CPUSPARCState *env)
+{
+ return env->fsr;
+}
+
+target_ulong helper_get_fsr(CPUSPARCState *env)
+{
+ return cpu_get_fsr(env);
+}
+
+static void set_fsr_nonsplit(CPUSPARCState *env, target_ulong fsr)
{
int rnd_mode;
+ env->fsr = fsr;
+
switch (fsr & FSR_RD_MASK) {
case FSR_RD_NEAREST:
rnd_mode = float_round_nearest_even;
@@ -369,7 +381,12 @@ static void set_fsr(CPUSPARCState *env, target_ulong fsr)
set_float_rounding_mode(rnd_mode, &env->fp_status);
}
+void cpu_put_fsr(CPUSPARCState *env, target_ulong fsr)
+{
+ set_fsr_nonsplit(env, fsr);
+}
+
void helper_set_fsr(CPUSPARCState *env, target_ulong fsr)
{
- set_fsr(env, fsr);
+ set_fsr_nonsplit(env, fsr);
}
diff --git a/target/sparc/gdbstub.c b/target/sparc/gdbstub.c
index a1c8fdc4d5..d1586b2392 100644
--- a/target/sparc/gdbstub.c
+++ b/target/sparc/gdbstub.c
@@ -64,7 +64,7 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
case 69:
return gdb_get_rega(mem_buf, env->npc);
case 70:
- return gdb_get_rega(mem_buf, env->fsr);
+ return gdb_get_rega(mem_buf, cpu_get_fsr(env));
case 71:
return gdb_get_rega(mem_buf, 0); /* csr */
default:
@@ -94,7 +94,7 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
((env->pstate & 0xfff) << 8) |
cpu_get_cwp64(env));
case 83:
- return gdb_get_regl(mem_buf, env->fsr);
+ return gdb_get_regl(mem_buf, cpu_get_fsr(env));
case 84:
return gdb_get_regl(mem_buf, env->fprs);
case 85:
@@ -156,7 +156,7 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
env->npc = tmp;
break;
case 70:
- env->fsr = tmp;
+ cpu_put_fsr(env, tmp);
break;
default:
return 0;
@@ -191,7 +191,7 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
cpu_put_cwp64(env, tmp & 0xff);
break;
case 83:
- env->fsr = tmp;
+ cpu_put_fsr(env, tmp);
break;
case 84:
env->fprs = tmp;
diff --git a/target/sparc/machine.c b/target/sparc/machine.c
index 44dfc07014..e46f15adb8 100644
--- a/target/sparc/machine.c
+++ b/target/sparc/machine.c
@@ -83,6 +83,34 @@ static const VMStateInfo vmstate_psr = {
.put = put_psr,
};
+static int get_fsr(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field)
+{
+ SPARCCPU *cpu = opaque;
+ CPUSPARCState *env = &cpu->env;
+ target_ulong val = qemu_get_betl(f);
+
+ cpu_put_fsr(env, val);
+ return 0;
+}
+
+static int put_fsr(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field, JSONWriter *vmdesc)
+{
+ SPARCCPU *cpu = opaque;
+ CPUSPARCState *env = &cpu->env;
+ target_ulong val = cpu_get_fsr(env);
+
+ qemu_put_betl(f, val);
+ return 0;
+}
+
+static const VMStateInfo vmstate_fsr = {
+ .name = "fsr",
+ .get = get_fsr,
+ .put = put_fsr,
+};
+
#ifdef TARGET_SPARC64
static int get_xcc(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
@@ -157,7 +185,6 @@ const VMStateDescription vmstate_sparc_cpu = {
VMSTATE_UINTTL(env.npc, SPARCCPU),
VMSTATE_UINTTL(env.y, SPARCCPU),
{
-
.name = "psr",
.version_id = 0,
.size = sizeof(uint32_t),
@@ -165,7 +192,14 @@ const VMStateDescription vmstate_sparc_cpu = {
.flags = VMS_SINGLE,
.offset = 0,
},
- VMSTATE_UINTTL(env.fsr, SPARCCPU),
+ {
+ .name = "fsr",
+ .version_id = 0,
+ .size = sizeof(target_ulong),
+ .info = &vmstate_fsr,
+ .flags = VMS_SINGLE,
+ .offset = 0,
+ },
VMSTATE_UINTTL(env.tbr, SPARCCPU),
VMSTATE_INT32(env.interrupt_index, SPARCCPU),
VMSTATE_UINT32(env.pil_in, SPARCCPU),
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 99482df256..1d5f36dafc 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4417,13 +4417,18 @@ TRANS(LDXFSR, 64, do_ldfsr, a, MO_TEUQ, FSR_LDXFSR_MASK, FSR_LDXFSR_OLDMASK)
static bool do_stfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop)
{
TCGv addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ TCGv fsr;
+
if (addr == NULL) {
return false;
}
if (gen_trap_ifnofpu(dc)) {
return true;
}
- tcg_gen_qemu_st_tl(cpu_fsr, addr, dc->mem_idx, mop | MO_ALIGN);
+
+ fsr = tcg_temp_new();
+ gen_helper_get_fsr(fsr, tcg_env);
+ tcg_gen_qemu_st_tl(fsr, addr, dc->mem_idx, mop | MO_ALIGN);
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 16/22] target/split: Split ver from env->fsr
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (14 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 15/22] target/sparc: Introduce cpu_get_fsr, cpu_put_fsr Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2024-01-30 8:11 ` Philippe Mathieu-Daudé
2023-11-03 17:38 ` [PATCH 17/22] target/sparc: Clear cexc and ftt in do_check_ieee_exceptions Richard Henderson
` (6 subsequent siblings)
22 siblings, 1 reply; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
This field is read-only. It is easier to store it separately
and merge it only upon read.
While we're at it, use FSR_VER_SHIFT to initialize fpu_version.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/cpu.h | 3 +++
target/sparc/cpu.c | 27 +++++++++++++--------------
target/sparc/fop_helper.c | 9 +++++++--
3 files changed, 23 insertions(+), 16 deletions(-)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 33c7d31fef..8ff222595e 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -191,6 +191,9 @@ enum {
#define FSR_NXC (1ULL << 0)
#define FSR_CEXC_MASK (FSR_NVC | FSR_OFC | FSR_UFC | FSR_DZC | FSR_NXC)
+#define FSR_VER_SHIFT 17
+#define FSR_VER_MASK (7 << FSR_VER_SHIFT)
+
#define FSR_FTT2 (1ULL << 16)
#define FSR_FTT1 (1ULL << 15)
#define FSR_FTT0 (1ULL << 14)
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 69dfa1dd4e..bebfdbf313 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -368,7 +368,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "Fujitsu MB86904",
.iu_version = 0x04 << 24, /* Impl 0, ver 4 */
- .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
+ .fpu_version = 4 << FSR_VER_SHIFT, /* FPU version 4 (Meiko) */
.mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
.mmu_bm = 0x00004000,
.mmu_ctpr_mask = 0x00ffffc0,
@@ -381,7 +381,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "Fujitsu MB86907",
.iu_version = 0x05 << 24, /* Impl 0, ver 5 */
- .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
+ .fpu_version = 4 << FSR_VER_SHIFT, /* FPU version 4 (Meiko) */
.mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
.mmu_bm = 0x00004000,
.mmu_ctpr_mask = 0xffffffc0,
@@ -394,7 +394,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "TI MicroSparc I",
.iu_version = 0x41000000,
- .fpu_version = 4 << 17,
+ .fpu_version = 4 << FSR_VER_SHIFT,
.mmu_version = 0x41000000,
.mmu_bm = 0x00004000,
.mmu_ctpr_mask = 0x007ffff0,
@@ -407,7 +407,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "TI MicroSparc II",
.iu_version = 0x42000000,
- .fpu_version = 4 << 17,
+ .fpu_version = 4 << FSR_VER_SHIFT,
.mmu_version = 0x02000000,
.mmu_bm = 0x00004000,
.mmu_ctpr_mask = 0x00ffffc0,
@@ -420,7 +420,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "TI MicroSparc IIep",
.iu_version = 0x42000000,
- .fpu_version = 4 << 17,
+ .fpu_version = 4 << FSR_VER_SHIFT,
.mmu_version = 0x04000000,
.mmu_bm = 0x00004000,
.mmu_ctpr_mask = 0x00ffffc0,
@@ -433,7 +433,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "TI SuperSparc 40", /* STP1020NPGA */
.iu_version = 0x41000000, /* SuperSPARC 2.x */
- .fpu_version = 0 << 17,
+ .fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
.mmu_bm = 0x00002000,
.mmu_ctpr_mask = 0xffffffc0,
@@ -446,7 +446,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "TI SuperSparc 50", /* STP1020PGA */
.iu_version = 0x40000000, /* SuperSPARC 3.x */
- .fpu_version = 0 << 17,
+ .fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
.mmu_bm = 0x00002000,
.mmu_ctpr_mask = 0xffffffc0,
@@ -459,7 +459,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "TI SuperSparc 51",
.iu_version = 0x40000000, /* SuperSPARC 3.x */
- .fpu_version = 0 << 17,
+ .fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
.mmu_bm = 0x00002000,
.mmu_ctpr_mask = 0xffffffc0,
@@ -473,7 +473,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "TI SuperSparc 60", /* STP1020APGA */
.iu_version = 0x40000000, /* SuperSPARC 3.x */
- .fpu_version = 0 << 17,
+ .fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
.mmu_bm = 0x00002000,
.mmu_ctpr_mask = 0xffffffc0,
@@ -486,7 +486,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "TI SuperSparc 61",
.iu_version = 0x44000000, /* SuperSPARC 3.x */
- .fpu_version = 0 << 17,
+ .fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
.mmu_bm = 0x00002000,
.mmu_ctpr_mask = 0xffffffc0,
@@ -500,7 +500,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "TI SuperSparc II",
.iu_version = 0x40000000, /* SuperSPARC II 1.x */
- .fpu_version = 0 << 17,
+ .fpu_version = 0 << FSR_VER_SHIFT,
.mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
.mmu_bm = 0x00002000,
.mmu_ctpr_mask = 0xffffffc0,
@@ -514,7 +514,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "LEON2",
.iu_version = 0xf2000000,
- .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
+ .fpu_version = 4 << FSR_VER_SHIFT, /* FPU version 4 (Meiko) */
.mmu_version = 0xf2000000,
.mmu_bm = 0x00004000,
.mmu_ctpr_mask = 0x007ffff0,
@@ -527,7 +527,7 @@ static const sparc_def_t sparc_defs[] = {
{
.name = "LEON3",
.iu_version = 0xf3000000,
- .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
+ .fpu_version = 4 << FSR_VER_SHIFT, /* FPU version 4 (Meiko) */
.mmu_version = 0xf3000000,
.mmu_bm = 0x00000000,
.mmu_ctpr_mask = 0xfffffffc,
@@ -758,7 +758,6 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
#endif
env->version = env->def.iu_version;
- env->fsr = env->def.fpu_version;
env->nwindows = env->def.nwindows;
#if !defined(TARGET_SPARC64)
env->mmuregs[0] |= env->def.mmu_version;
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 70b38011d2..22b412adb5 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -349,7 +349,12 @@ GEN_FCMP(fcmpeq_fcc3, float128, 26, 1);
target_ulong cpu_get_fsr(CPUSPARCState *env)
{
- return env->fsr;
+ target_ulong fsr = env->fsr;
+
+ /* VER is kept completely separate until re-assembly. */
+ fsr |= env->def.fpu_version;
+
+ return fsr;
}
target_ulong helper_get_fsr(CPUSPARCState *env)
@@ -361,7 +366,7 @@ static void set_fsr_nonsplit(CPUSPARCState *env, target_ulong fsr)
{
int rnd_mode;
- env->fsr = fsr;
+ env->fsr = fsr & ~FSR_VER_MASK;
switch (fsr & FSR_RD_MASK) {
case FSR_RD_NEAREST:
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 17/22] target/sparc: Clear cexc and ftt in do_check_ieee_exceptions
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (15 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 16/22] target/split: Split ver from env->fsr Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 18/22] target/sparc: Merge check_ieee_exceptions with FPop helpers Richard Henderson
` (5 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Don't do the clearing explicitly before each FPop,
rather do it as part of the rest of exception handling.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/fop_helper.c | 2 ++
target/sparc/translate.c | 16 ----------------
2 files changed, 2 insertions(+), 16 deletions(-)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 22b412adb5..64f20e78f1 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -50,6 +50,8 @@ static target_ulong do_check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
target_ulong status = get_float_exception_flags(&env->fp_status);
target_ulong fsr = env->fsr;
+ fsr &= FSR_FTT_CEXC_NMASK;
+
if (unlikely(status)) {
/* Keep exception flags clear for next time. */
set_float_exception_flags(0, &env->fp_status);
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 1d5f36dafc..11d025f4ea 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4524,7 +4524,6 @@ static bool do_env_ff(DisasContext *dc, arg_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
tmp = gen_load_fpr_F(dc, a->rs);
func(tmp, tcg_env, tmp);
gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
@@ -4546,7 +4545,6 @@ static bool do_env_fd(DisasContext *dc, arg_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
dst = tcg_temp_new_i32();
src = gen_load_fpr_D(dc, a->rs);
func(dst, tcg_env, src);
@@ -4590,7 +4588,6 @@ static bool do_env_dd(DisasContext *dc, arg_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
dst = gen_dest_fpr_D(dc, a->rd);
src = gen_load_fpr_D(dc, a->rs);
func(dst, tcg_env, src);
@@ -4613,7 +4610,6 @@ static bool do_env_df(DisasContext *dc, arg_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
dst = gen_dest_fpr_D(dc, a->rd);
src = gen_load_fpr_F(dc, a->rs);
func(dst, tcg_env, src);
@@ -4661,8 +4657,6 @@ static bool do_env_qq(DisasContext *dc, arg_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
-
t = gen_load_fpr_Q(dc, a->rs);
func(t, tcg_env, t);
gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
@@ -4685,7 +4679,6 @@ static bool do_env_fq(DisasContext *dc, arg_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
src = gen_load_fpr_Q(dc, a->rs);
dst = tcg_temp_new_i32();
func(dst, tcg_env, src);
@@ -4710,7 +4703,6 @@ static bool do_env_dq(DisasContext *dc, arg_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
src = gen_load_fpr_Q(dc, a->rs);
dst = gen_dest_fpr_D(dc, a->rd);
func(dst, tcg_env, src);
@@ -4808,7 +4800,6 @@ static bool do_env_fff(DisasContext *dc, arg_r_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
src1 = gen_load_fpr_F(dc, a->rs1);
src2 = gen_load_fpr_F(dc, a->rs2);
func(src1, tcg_env, src1, src2);
@@ -4903,7 +4894,6 @@ static bool do_env_ddd(DisasContext *dc, arg_r_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
dst = gen_dest_fpr_D(dc, a->rd);
src1 = gen_load_fpr_D(dc, a->rs1);
src2 = gen_load_fpr_D(dc, a->rs2);
@@ -4930,7 +4920,6 @@ static bool trans_FsMULd(DisasContext *dc, arg_r_r_r *a)
return raise_unimpfpop(dc);
}
- gen_op_clear_ieee_excp_and_FTT();
dst = gen_dest_fpr_D(dc, a->rd);
src1 = gen_load_fpr_F(dc, a->rs1);
src2 = gen_load_fpr_F(dc, a->rs2);
@@ -4972,7 +4961,6 @@ static bool do_env_qqq(DisasContext *dc, arg_r_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
src1 = gen_load_fpr_Q(dc, a->rs1);
src2 = gen_load_fpr_Q(dc, a->rs2);
func(src1, tcg_env, src1, src2);
@@ -4998,7 +4986,6 @@ static bool trans_FdMULq(DisasContext *dc, arg_r_r_r *a)
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
src1 = gen_load_fpr_D(dc, a->rs1);
src2 = gen_load_fpr_D(dc, a->rs2);
dst = tcg_temp_new_i128();
@@ -5087,7 +5074,6 @@ static bool do_fcmps(DisasContext *dc, arg_FCMPs *a, bool e)
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
src1 = gen_load_fpr_F(dc, a->rs1);
src2 = gen_load_fpr_F(dc, a->rs2);
if (e) {
@@ -5112,7 +5098,6 @@ static bool do_fcmpd(DisasContext *dc, arg_FCMPd *a, bool e)
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
src1 = gen_load_fpr_D(dc, a->rs1);
src2 = gen_load_fpr_D(dc, a->rs2);
if (e) {
@@ -5140,7 +5125,6 @@ static bool do_fcmpq(DisasContext *dc, arg_FCMPq *a, bool e)
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
src1 = gen_load_fpr_Q(dc, a->rs1);
src2 = gen_load_fpr_Q(dc, a->rs2);
if (e) {
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 18/22] target/sparc: Merge check_ieee_exceptions with FPop helpers
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (16 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 17/22] target/sparc: Clear cexc and ftt in do_check_ieee_exceptions Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 19/22] target/sparc: Split cexc and ftt from env->fsr Richard Henderson
` (4 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
If an exception is to be raised, the destination fp register
should be unmodified. The current implementation is incorrect,
in that double results will be written back before calling
gen_helper_check_ieee_exceptions, despite the placement of
gen_store_fpr_D, since gen_dest_fpr_D returns cpu_fpr[].
We can simplify the entire implementation by having each
FPOp helper call check_ieee_exceptions. For the moment this
requires that all FPop helpers write to the TCG global cpu_fsr,
so remove TCG_CALL_NO_WG from the DEF_HELPER_FLAGS_*.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 119 +++++++++++----------
target/sparc/fop_helper.c | 215 ++++++++++++++++++++++++++++----------
target/sparc/translate.c | 14 ---
3 files changed, 219 insertions(+), 129 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index cc8db50d75..7c688edd62 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -35,81 +35,80 @@ DEF_HELPER_3(tsubcctv, tl, env, tl, tl)
DEF_HELPER_FLAGS_4(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, i32)
DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32)
#endif
-DEF_HELPER_FLAGS_1(check_ieee_exceptions, TCG_CALL_NO_WG, tl, env)
DEF_HELPER_FLAGS_1(get_fsr, TCG_CALL_NO_WG_SE, tl, env)
DEF_HELPER_FLAGS_2(set_fsr, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_2(fsqrts, TCG_CALL_NO_RWG, f32, env, f32)
-DEF_HELPER_FLAGS_2(fsqrtd, TCG_CALL_NO_RWG, f64, env, f64)
-DEF_HELPER_FLAGS_3(fcmps, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpes, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_2(fsqrtq, TCG_CALL_NO_RWG, i128, env, i128)
-DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, tl, env, i128, i128)
+DEF_HELPER_FLAGS_2(fsqrts, 0, f32, env, f32)
+DEF_HELPER_FLAGS_2(fsqrtd, 0, f64, env, f64)
+DEF_HELPER_FLAGS_2(fsqrtq, 0, i128, env, i128)
+DEF_HELPER_FLAGS_3(fcmps, 0, tl, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmpd, 0, tl, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpes, 0, tl, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmped, 0, tl, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpq, 0, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq, 0, tl, env, i128, i128)
#ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_3(fcmps_fcc1, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmps_fcc2, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmps_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpd_fcc1, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpd_fcc2, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpd_fcc3, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpes_fcc1, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpes_fcc2, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpes_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmped_fcc1, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmped_fcc2, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmped_fcc3, TCG_CALL_NO_WG, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpq_fcc1, TCG_CALL_NO_WG, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpq_fcc2, TCG_CALL_NO_WG, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpq_fcc3, TCG_CALL_NO_WG, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq_fcc1, TCG_CALL_NO_WG, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq_fcc2, TCG_CALL_NO_WG, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq_fcc3, TCG_CALL_NO_WG, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmps_fcc1, 0, tl, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmps_fcc2, 0, tl, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmps_fcc3, 0, tl, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmpd_fcc1, 0, tl, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpd_fcc2, 0, tl, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpd_fcc3, 0, tl, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpes_fcc1, 0, tl, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmpes_fcc2, 0, tl, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmpes_fcc3, 0, tl, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmped_fcc1, 0, tl, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmped_fcc2, 0, tl, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmped_fcc3, 0, tl, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpq_fcc1, 0, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpq_fcc2, 0, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpq_fcc3, 0, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq_fcc1, 0, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq_fcc2, 0, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq_fcc3, 0, tl, env, i128, i128)
#endif
DEF_HELPER_2(raise_exception, noreturn, env, int)
-DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_RWG, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_RWG, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_RWG, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_RWG, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(faddd, 0, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(fsubd, 0, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(fmuld, 0, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(fdivd, 0, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(faddq, TCG_CALL_NO_RWG, i128, env, i128, i128)
-DEF_HELPER_FLAGS_3(fsubq, TCG_CALL_NO_RWG, i128, env, i128, i128)
-DEF_HELPER_FLAGS_3(fmulq, TCG_CALL_NO_RWG, i128, env, i128, i128)
-DEF_HELPER_FLAGS_3(fdivq, TCG_CALL_NO_RWG, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(faddq, 0, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(fsubq, 0, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(fmulq, 0, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(fdivq, 0, i128, env, i128, i128)
-DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_RWG, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_RWG, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_RWG, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_RWG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fadds, 0, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fsubs, 0, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fmuls, 0, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fdivs, 0, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fsmuld, TCG_CALL_NO_RWG, f64, env, f32, f32)
-DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_RWG, i128, env, f64, f64)
+DEF_HELPER_FLAGS_3(fsmuld, 0, f64, env, f32, f32)
+DEF_HELPER_FLAGS_3(fdmulq, 0, i128, env, f64, f64)
-DEF_HELPER_FLAGS_2(fitod, TCG_CALL_NO_RWG_SE, f64, env, s32)
-DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_RWG, i128, env, s32)
+DEF_HELPER_FLAGS_2(fitod, 0, f64, env, s32)
+DEF_HELPER_FLAGS_2(fitoq, 0, i128, env, s32)
-DEF_HELPER_FLAGS_2(fitos, TCG_CALL_NO_RWG, f32, env, s32)
+DEF_HELPER_FLAGS_2(fitos, 0, f32, env, s32)
#ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_2(fxtos, TCG_CALL_NO_RWG, f32, env, s64)
-DEF_HELPER_FLAGS_2(fxtod, TCG_CALL_NO_RWG, f64, env, s64)
-DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_RWG, i128, env, s64)
+DEF_HELPER_FLAGS_2(fxtos, 0, f32, env, s64)
+DEF_HELPER_FLAGS_2(fxtod, 0, f64, env, s64)
+DEF_HELPER_FLAGS_2(fxtoq, 0, i128, env, s64)
#endif
-DEF_HELPER_FLAGS_2(fdtos, TCG_CALL_NO_RWG, f32, env, f64)
-DEF_HELPER_FLAGS_2(fstod, TCG_CALL_NO_RWG, f64, env, f32)
-DEF_HELPER_FLAGS_2(fqtos, TCG_CALL_NO_RWG, f32, env, i128)
-DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_RWG, i128, env, f32)
-DEF_HELPER_FLAGS_2(fqtod, TCG_CALL_NO_RWG, f64, env, i128)
-DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_RWG, i128, env, f64)
-DEF_HELPER_FLAGS_2(fstoi, TCG_CALL_NO_RWG, s32, env, f32)
-DEF_HELPER_FLAGS_2(fdtoi, TCG_CALL_NO_RWG, s32, env, f64)
-DEF_HELPER_FLAGS_2(fqtoi, TCG_CALL_NO_RWG, s32, env, i128)
+DEF_HELPER_FLAGS_2(fdtos, 0, f32, env, f64)
+DEF_HELPER_FLAGS_2(fstod, 0, f64, env, f32)
+DEF_HELPER_FLAGS_2(fqtos, 0, f32, env, i128)
+DEF_HELPER_FLAGS_2(fstoq, 0, i128, env, f32)
+DEF_HELPER_FLAGS_2(fqtod, 0, f64, env, i128)
+DEF_HELPER_FLAGS_2(fdtoq, 0, i128, env, f64)
+DEF_HELPER_FLAGS_2(fstoi, 0, s32, env, f32)
+DEF_HELPER_FLAGS_2(fdtoi, 0, s32, env, f64)
+DEF_HELPER_FLAGS_2(fqtoi, 0, s32, env, i128)
#ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_RWG, s64, env, f32)
-DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_RWG, s64, env, f64)
-DEF_HELPER_FLAGS_2(fqtox, TCG_CALL_NO_RWG, s64, env, i128)
+DEF_HELPER_FLAGS_2(fstox, 0, s64, env, f32)
+DEF_HELPER_FLAGS_2(fdtox, 0, s64, env, f64)
+DEF_HELPER_FLAGS_2(fqtox, 0, s64, env, i128)
DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 64f20e78f1..755117ea08 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -45,7 +45,7 @@ static inline Int128 f128_ret(float128 f)
return u.i;
}
-static target_ulong do_check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
+static void check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
{
target_ulong status = get_float_exception_flags(&env->fp_status);
target_ulong fsr = env->fsr;
@@ -89,162 +89,265 @@ static target_ulong do_check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
}
}
- return fsr;
+ env->fsr = fsr;
}
-target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
+float32 helper_fadds(CPUSPARCState *env, float32 src1, float32 src2)
{
- return do_check_ieee_exceptions(env, GETPC());
+ float32 ret = float32_add(src1, src2, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
-#define F_BINOP(name) \
- float32 helper_f ## name ## s (CPUSPARCState *env, float32 src1, \
- float32 src2) \
- { \
- return float32_ ## name (src1, src2, &env->fp_status); \
- } \
- float64 helper_f ## name ## d (CPUSPARCState * env, float64 src1,\
- float64 src2) \
- { \
- return float64_ ## name (src1, src2, &env->fp_status); \
- } \
- Int128 helper_f ## name ## q(CPUSPARCState * env, Int128 src1, \
- Int128 src2) \
- { \
- return f128_ret(float128_ ## name (f128_in(src1), f128_in(src2), \
- &env->fp_status)); \
- }
+float32 helper_fsubs(CPUSPARCState *env, float32 src1, float32 src2)
+{
+ float32 ret = float32_sub(src1, src2, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
+}
-F_BINOP(add);
-F_BINOP(sub);
-F_BINOP(mul);
-F_BINOP(div);
-#undef F_BINOP
+float32 helper_fmuls(CPUSPARCState *env, float32 src1, float32 src2)
+{
+ float32 ret = float32_mul(src1, src2, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
+}
+
+float32 helper_fdivs(CPUSPARCState *env, float32 src1, float32 src2)
+{
+ float32 ret = float32_div(src1, src2, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
+}
+
+float64 helper_faddd(CPUSPARCState *env, float64 src1, float64 src2)
+{
+ float64 ret = float64_add(src1, src2, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
+}
+
+float64 helper_fsubd(CPUSPARCState *env, float64 src1, float64 src2)
+{
+ float64 ret = float64_sub(src1, src2, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
+}
+
+float64 helper_fmuld(CPUSPARCState *env, float64 src1, float64 src2)
+{
+ float64 ret = float64_mul(src1, src2, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
+}
+
+float64 helper_fdivd(CPUSPARCState *env, float64 src1, float64 src2)
+{
+ float64 ret = float64_div(src1, src2, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
+}
+
+Int128 helper_faddq(CPUSPARCState *env, Int128 src1, Int128 src2)
+{
+ float128 ret = float128_add(f128_in(src1), f128_in(src2), &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return f128_ret(ret);
+}
+
+Int128 helper_fsubq(CPUSPARCState *env, Int128 src1, Int128 src2)
+{
+ float128 ret = float128_sub(f128_in(src1), f128_in(src2), &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return f128_ret(ret);
+}
+
+Int128 helper_fmulq(CPUSPARCState *env, Int128 src1, Int128 src2)
+{
+ float128 ret = float128_mul(f128_in(src1), f128_in(src2), &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return f128_ret(ret);
+}
+
+Int128 helper_fdivq(CPUSPARCState *env, Int128 src1, Int128 src2)
+{
+ float128 ret = float128_div(f128_in(src1), f128_in(src2), &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return f128_ret(ret);
+}
float64 helper_fsmuld(CPUSPARCState *env, float32 src1, float32 src2)
{
- return float64_mul(float32_to_float64(src1, &env->fp_status),
- float32_to_float64(src2, &env->fp_status),
- &env->fp_status);
+ float64 ret = float64_mul(float32_to_float64(src1, &env->fp_status),
+ float32_to_float64(src2, &env->fp_status),
+ &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
Int128 helper_fdmulq(CPUSPARCState *env, float64 src1, float64 src2)
{
- return f128_ret(float128_mul(float64_to_float128(src1, &env->fp_status),
- float64_to_float128(src2, &env->fp_status),
- &env->fp_status));
+ float128 ret = float128_mul(float64_to_float128(src1, &env->fp_status),
+ float64_to_float128(src2, &env->fp_status),
+ &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return f128_ret(ret);
}
/* Integer to float conversion. */
float32 helper_fitos(CPUSPARCState *env, int32_t src)
{
- return int32_to_float32(src, &env->fp_status);
+ float32 ret = int32_to_float32(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
float64 helper_fitod(CPUSPARCState *env, int32_t src)
{
- return int32_to_float64(src, &env->fp_status);
+ float64 ret = int32_to_float64(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
Int128 helper_fitoq(CPUSPARCState *env, int32_t src)
{
- return f128_ret(int32_to_float128(src, &env->fp_status));
+ float128 ret = int32_to_float128(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return f128_ret(ret);
}
#ifdef TARGET_SPARC64
float32 helper_fxtos(CPUSPARCState *env, int64_t src)
{
- return int64_to_float32(src, &env->fp_status);
+ float32 ret = int64_to_float32(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
float64 helper_fxtod(CPUSPARCState *env, int64_t src)
{
- return int64_to_float64(src, &env->fp_status);
+ float64 ret = int64_to_float64(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
Int128 helper_fxtoq(CPUSPARCState *env, int64_t src)
{
- return f128_ret(int64_to_float128(src, &env->fp_status));
+ float128 ret = int64_to_float128(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return f128_ret(ret);
}
#endif
/* floating point conversion */
float32 helper_fdtos(CPUSPARCState *env, float64 src)
{
- return float64_to_float32(src, &env->fp_status);
+ float32 ret = float64_to_float32(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
float64 helper_fstod(CPUSPARCState *env, float32 src)
{
- return float32_to_float64(src, &env->fp_status);
+ float64 ret = float32_to_float64(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
float32 helper_fqtos(CPUSPARCState *env, Int128 src)
{
- return float128_to_float32(f128_in(src), &env->fp_status);
+ float32 ret = float128_to_float32(f128_in(src), &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
Int128 helper_fstoq(CPUSPARCState *env, float32 src)
{
- return f128_ret(float32_to_float128(src, &env->fp_status));
+ float128 ret = float32_to_float128(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return f128_ret(ret);
}
float64 helper_fqtod(CPUSPARCState *env, Int128 src)
{
- return float128_to_float64(f128_in(src), &env->fp_status);
+ float64 ret = float128_to_float64(f128_in(src), &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
Int128 helper_fdtoq(CPUSPARCState *env, float64 src)
{
- return f128_ret(float64_to_float128(src, &env->fp_status));
+ float128 ret = float64_to_float128(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return f128_ret(ret);
}
/* Float to integer conversion. */
int32_t helper_fstoi(CPUSPARCState *env, float32 src)
{
- return float32_to_int32_round_to_zero(src, &env->fp_status);
+ int32_t ret = float32_to_int32_round_to_zero(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
int32_t helper_fdtoi(CPUSPARCState *env, float64 src)
{
- return float64_to_int32_round_to_zero(src, &env->fp_status);
+ int32_t ret = float64_to_int32_round_to_zero(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
int32_t helper_fqtoi(CPUSPARCState *env, Int128 src)
{
- return float128_to_int32_round_to_zero(f128_in(src), &env->fp_status);
+ int32_t ret = float128_to_int32_round_to_zero(f128_in(src),
+ &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
#ifdef TARGET_SPARC64
int64_t helper_fstox(CPUSPARCState *env, float32 src)
{
- return float32_to_int64_round_to_zero(src, &env->fp_status);
+ int64_t ret = float32_to_int64_round_to_zero(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
int64_t helper_fdtox(CPUSPARCState *env, float64 src)
{
- return float64_to_int64_round_to_zero(src, &env->fp_status);
+ int64_t ret = float64_to_int64_round_to_zero(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
int64_t helper_fqtox(CPUSPARCState *env, Int128 src)
{
- return float128_to_int64_round_to_zero(f128_in(src), &env->fp_status);
+ int64_t ret = float128_to_int64_round_to_zero(f128_in(src),
+ &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
#endif
float32 helper_fsqrts(CPUSPARCState *env, float32 src)
{
- return float32_sqrt(src, &env->fp_status);
+ float32 ret = float32_sqrt(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
float64 helper_fsqrtd(CPUSPARCState *env, float64 src)
{
- return float64_sqrt(src, &env->fp_status);
+ float64 ret = float64_sqrt(src, &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return ret;
}
Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
{
- return f128_ret(float128_sqrt(f128_in(src), &env->fp_status));
+ float128 ret = float128_sqrt(f128_in(src), &env->fp_status);
+ check_ieee_exceptions(env, GETPC());
+ return f128_ret(ret);
}
#define GEN_FCMP(name, size, FS, E) \
@@ -261,7 +364,8 @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
ret = glue(size, _compare_quiet)(reg1, reg2, \
&env->fp_status); \
} \
- fsr = do_check_ieee_exceptions(env, GETPC()); \
+ check_ieee_exceptions(env, GETPC()); \
+ fsr = env->fsr; \
switch (ret) { \
case float_relation_unordered: \
fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
@@ -292,7 +396,8 @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
ret = glue(size, _compare_quiet)(src1, src2, \
&env->fp_status); \
} \
- fsr = do_check_ieee_exceptions(env, GETPC()); \
+ check_ieee_exceptions(env, GETPC()); \
+ fsr = env->fsr; \
switch (ret) { \
case float_relation_unordered: \
fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 11d025f4ea..8787cb3bfe 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4526,7 +4526,6 @@ static bool do_env_ff(DisasContext *dc, arg_r_r *a,
tmp = gen_load_fpr_F(dc, a->rs);
func(tmp, tcg_env, tmp);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_F(dc, a->rd, tmp);
return advance_pc(dc);
}
@@ -4548,7 +4547,6 @@ static bool do_env_fd(DisasContext *dc, arg_r_r *a,
dst = tcg_temp_new_i32();
src = gen_load_fpr_D(dc, a->rs);
func(dst, tcg_env, src);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_F(dc, a->rd, dst);
return advance_pc(dc);
}
@@ -4591,7 +4589,6 @@ static bool do_env_dd(DisasContext *dc, arg_r_r *a,
dst = gen_dest_fpr_D(dc, a->rd);
src = gen_load_fpr_D(dc, a->rs);
func(dst, tcg_env, src);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_D(dc, a->rd, dst);
return advance_pc(dc);
}
@@ -4613,7 +4610,6 @@ static bool do_env_df(DisasContext *dc, arg_r_r *a,
dst = gen_dest_fpr_D(dc, a->rd);
src = gen_load_fpr_F(dc, a->rs);
func(dst, tcg_env, src);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_D(dc, a->rd, dst);
return advance_pc(dc);
}
@@ -4659,7 +4655,6 @@ static bool do_env_qq(DisasContext *dc, arg_r_r *a,
t = gen_load_fpr_Q(dc, a->rs);
func(t, tcg_env, t);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_Q(dc, a->rd, t);
return advance_pc(dc);
}
@@ -4682,7 +4677,6 @@ static bool do_env_fq(DisasContext *dc, arg_r_r *a,
src = gen_load_fpr_Q(dc, a->rs);
dst = tcg_temp_new_i32();
func(dst, tcg_env, src);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_F(dc, a->rd, dst);
return advance_pc(dc);
}
@@ -4706,7 +4700,6 @@ static bool do_env_dq(DisasContext *dc, arg_r_r *a,
src = gen_load_fpr_Q(dc, a->rs);
dst = gen_dest_fpr_D(dc, a->rd);
func(dst, tcg_env, src);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_D(dc, a->rd, dst);
return advance_pc(dc);
}
@@ -4727,7 +4720,6 @@ static bool do_env_qf(DisasContext *dc, arg_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
src = gen_load_fpr_F(dc, a->rs);
dst = tcg_temp_new_i128();
func(dst, tcg_env, src);
@@ -4751,7 +4743,6 @@ static bool do_env_qd(DisasContext *dc, arg_r_r *a,
return true;
}
- gen_op_clear_ieee_excp_and_FTT();
src = gen_load_fpr_D(dc, a->rs);
dst = tcg_temp_new_i128();
func(dst, tcg_env, src);
@@ -4803,7 +4794,6 @@ static bool do_env_fff(DisasContext *dc, arg_r_r_r *a,
src1 = gen_load_fpr_F(dc, a->rs1);
src2 = gen_load_fpr_F(dc, a->rs2);
func(src1, tcg_env, src1, src2);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_F(dc, a->rd, src1);
return advance_pc(dc);
}
@@ -4898,7 +4888,6 @@ static bool do_env_ddd(DisasContext *dc, arg_r_r_r *a,
src1 = gen_load_fpr_D(dc, a->rs1);
src2 = gen_load_fpr_D(dc, a->rs2);
func(dst, tcg_env, src1, src2);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_D(dc, a->rd, dst);
return advance_pc(dc);
}
@@ -4924,7 +4913,6 @@ static bool trans_FsMULd(DisasContext *dc, arg_r_r_r *a)
src1 = gen_load_fpr_F(dc, a->rs1);
src2 = gen_load_fpr_F(dc, a->rs2);
gen_helper_fsmuld(dst, tcg_env, src1, src2);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_D(dc, a->rd, dst);
return advance_pc(dc);
}
@@ -4964,7 +4952,6 @@ static bool do_env_qqq(DisasContext *dc, arg_r_r_r *a,
src1 = gen_load_fpr_Q(dc, a->rs1);
src2 = gen_load_fpr_Q(dc, a->rs2);
func(src1, tcg_env, src1, src2);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_Q(dc, a->rd, src1);
return advance_pc(dc);
}
@@ -4990,7 +4977,6 @@ static bool trans_FdMULq(DisasContext *dc, arg_r_r_r *a)
src2 = gen_load_fpr_D(dc, a->rs2);
dst = tcg_temp_new_i128();
gen_helper_fdmulq(dst, tcg_env, src1, src2);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
gen_store_fpr_Q(dc, a->rd, dst);
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 19/22] target/sparc: Split cexc and ftt from env->fsr
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (17 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 18/22] target/sparc: Merge check_ieee_exceptions with FPop helpers Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 20/22] target/sparc: Remove cpu_fsr Richard Henderson
` (3 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
These two fields are adjusted by all FPop insns.
Having them separate makes it easier to set without masking.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/cpu.h | 7 +++++-
target/sparc/helper.h | 2 +-
target/sparc/fop_helper.c | 46 ++++++++++++++++++---------------------
target/sparc/translate.c | 31 ++++++++++++++++----------
4 files changed, 48 insertions(+), 38 deletions(-)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 8ff222595e..90a7dfb004 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -176,6 +176,7 @@ enum {
#define FSR_DZM (1ULL << 24)
#define FSR_NXM (1ULL << 23)
#define FSR_TEM_MASK (FSR_NVM | FSR_OFM | FSR_UFM | FSR_DZM | FSR_NXM)
+#define FSR_TEM_SHIFT 23
#define FSR_NVA (1ULL << 9)
#define FSR_OFA (1ULL << 8)
@@ -183,6 +184,7 @@ enum {
#define FSR_DZA (1ULL << 6)
#define FSR_NXA (1ULL << 5)
#define FSR_AEXC_MASK (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
+#define FSR_AEXC_SHIFT 5
#define FSR_NVC (1ULL << 4)
#define FSR_OFC (1ULL << 3)
@@ -464,7 +466,10 @@ struct CPUArchState {
target_ulong cond; /* conditional branch result (XXX: save it in a
temporary register when possible) */
- target_ulong fsr; /* FPU state register */
+ /* FPU State Register, in parts */
+ target_ulong fsr; /* rm, tem, aexc, fcc* */
+ uint32_t fsr_cexc_ftt; /* cexc, ftt */
+
CPU_DoubleU fpr[TARGET_DPREGS]; /* floating point registers */
uint32_t cwp; /* index of current register window (extracted
from PSR) */
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 7c688edd62..7466164468 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -36,7 +36,7 @@ DEF_HELPER_FLAGS_4(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, i32)
DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32)
#endif
DEF_HELPER_FLAGS_1(get_fsr, TCG_CALL_NO_WG_SE, tl, env)
-DEF_HELPER_FLAGS_2(set_fsr, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(set_fsr_noftt, 0, void, env, tl)
DEF_HELPER_FLAGS_2(fsqrts, 0, f32, env, f32)
DEF_HELPER_FLAGS_2(fsqrtd, 0, f64, env, f64)
DEF_HELPER_FLAGS_2(fsqrtq, 0, i128, env, i128)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 755117ea08..ac30f88810 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -48,9 +48,7 @@ static inline Int128 f128_ret(float128 f)
static void check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
{
target_ulong status = get_float_exception_flags(&env->fp_status);
- target_ulong fsr = env->fsr;
-
- fsr &= FSR_FTT_CEXC_NMASK;
+ uint32_t cexc = 0;
if (unlikely(status)) {
/* Keep exception flags clear for next time. */
@@ -58,38 +56,33 @@ static void check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
/* Copy IEEE 754 flags into FSR */
if (status & float_flag_invalid) {
- fsr |= FSR_NVC;
+ cexc |= FSR_NVC;
}
if (status & float_flag_overflow) {
- fsr |= FSR_OFC;
+ cexc |= FSR_OFC;
}
if (status & float_flag_underflow) {
- fsr |= FSR_UFC;
+ cexc |= FSR_UFC;
}
if (status & float_flag_divbyzero) {
- fsr |= FSR_DZC;
+ cexc |= FSR_DZC;
}
if (status & float_flag_inexact) {
- fsr |= FSR_NXC;
+ cexc |= FSR_NXC;
}
- if ((fsr & FSR_CEXC_MASK) & ((fsr & FSR_TEM_MASK) >> 23)) {
- CPUState *cs = env_cpu(env);
-
- /* Unmasked exception, generate a trap. Note that while
- the helper is marked as NO_WG, we can get away with
- writing to cpu state along the exception path, since
- TCG generated code will never see the write. */
- env->fsr = fsr | FSR_FTT_IEEE_EXCP;
- cs->exception_index = TT_FP_EXCP;
- cpu_loop_exit_restore(cs, ra);
- } else {
- /* Accumulate exceptions */
- fsr |= (fsr & FSR_CEXC_MASK) << 5;
+ if (cexc & (env->fsr >> FSR_TEM_SHIFT)) {
+ /* Unmasked exception, generate an IEEE trap. */
+ env->fsr_cexc_ftt = cexc | FSR_FTT_IEEE_EXCP;
+ cpu_raise_exception_ra(env, TT_FP_EXCP, ra);
}
+
+ /* Accumulate exceptions */
+ env->fsr |= cexc << FSR_AEXC_SHIFT;
}
- env->fsr = fsr;
+ /* No trap, so FTT is cleared. */
+ env->fsr_cexc_ftt = cexc;
}
float32 helper_fadds(CPUSPARCState *env, float32 src1, float32 src2)
@@ -456,7 +449,7 @@ GEN_FCMP(fcmpeq_fcc3, float128, 26, 1);
target_ulong cpu_get_fsr(CPUSPARCState *env)
{
- target_ulong fsr = env->fsr;
+ target_ulong fsr = env->fsr | env->fsr_cexc_ftt;
/* VER is kept completely separate until re-assembly. */
fsr |= env->def.fpu_version;
@@ -473,7 +466,7 @@ static void set_fsr_nonsplit(CPUSPARCState *env, target_ulong fsr)
{
int rnd_mode;
- env->fsr = fsr & ~FSR_VER_MASK;
+ env->fsr = fsr & ~(FSR_VER_MASK | FSR_CEXC_MASK | FSR_FTT_MASK);
switch (fsr & FSR_RD_MASK) {
case FSR_RD_NEAREST:
@@ -495,10 +488,13 @@ static void set_fsr_nonsplit(CPUSPARCState *env, target_ulong fsr)
void cpu_put_fsr(CPUSPARCState *env, target_ulong fsr)
{
+ env->fsr_cexc_ftt = fsr & (FSR_CEXC_MASK | FSR_FTT_MASK);
set_fsr_nonsplit(env, fsr);
}
-void helper_set_fsr(CPUSPARCState *env, target_ulong fsr)
+void helper_set_fsr_noftt(CPUSPARCState *env, target_ulong fsr)
{
+ env->fsr_cexc_ftt &= FSR_FTT_MASK;
+ env->fsr_cexc_ftt |= fsr & FSR_CEXC_MASK;
set_fsr_nonsplit(env, fsr);
}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 8787cb3bfe..d2145dcc0b 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1199,7 +1199,8 @@ static bool gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
static void gen_op_clear_ieee_excp_and_FTT(void)
{
- tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
+ tcg_gen_st_i32(tcg_constant_i32(0), tcg_env,
+ offsetof(CPUSPARCState, fsr_cexc_ftt));
}
static void gen_op_fmovs(TCGv_i32 dst, TCGv_i32 src)
@@ -1400,10 +1401,15 @@ static void gen_op_fcmpeq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
}
#endif
-static void gen_op_fpexception_im(DisasContext *dc, int fsr_flags)
+static void gen_op_fpexception_im(DisasContext *dc, int ftt)
{
- tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
- tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
+ /*
+ * CEXC is only set when succesfully completing an FPop,
+ * or when raising FSR_FTT_IEEE_EXCP, i.e. check_ieee_exception.
+ * Thus we can simply store FTT into this field.
+ */
+ tcg_gen_st_i32(tcg_constant_i32(ftt), tcg_env,
+ offsetof(CPUSPARCState, fsr_cexc_ftt));
gen_exception(dc, TT_FP_EXCP);
}
@@ -4395,19 +4401,22 @@ static bool trans_STDFQ(DisasContext *dc, arg_STDFQ *a)
static bool do_ldfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop,
target_ulong new_mask, target_ulong old_mask)
{
- TCGv tmp, addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ TCGv addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ TCGv tnew, told;
+
if (addr == NULL) {
return false;
}
if (gen_trap_ifnofpu(dc)) {
return true;
}
- tmp = tcg_temp_new();
- tcg_gen_qemu_ld_tl(tmp, addr, dc->mem_idx, mop | MO_ALIGN);
- tcg_gen_andi_tl(tmp, tmp, new_mask);
- tcg_gen_andi_tl(cpu_fsr, cpu_fsr, old_mask);
- tcg_gen_or_tl(cpu_fsr, cpu_fsr, tmp);
- gen_helper_set_fsr(tcg_env, cpu_fsr);
+ tnew = tcg_temp_new();
+ told = tcg_temp_new();
+ tcg_gen_qemu_ld_tl(tnew, addr, dc->mem_idx, mop | MO_ALIGN);
+ tcg_gen_andi_tl(tnew, tnew, new_mask);
+ tcg_gen_andi_tl(told, cpu_fsr, old_mask);
+ tcg_gen_or_tl(tnew, tnew, told);
+ gen_helper_set_fsr_noftt(tcg_env, tnew);
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 20/22] target/sparc: Remove cpu_fsr
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (18 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 19/22] target/sparc: Split cexc and ftt from env->fsr Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 21/22] target/sparc: Split fcc out of env->fsr Richard Henderson
` (2 subsequent siblings)
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Drop this field as a tcg global, loading it explicitly in the
few places required. This means that all FPop helpers may
once again be TCG_CALL_NO_WG.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 120 +++++++++++++++++++-------------------
target/sparc/fop_helper.c | 9 ++-
target/sparc/translate.c | 98 ++++++++++++++++---------------
3 files changed, 114 insertions(+), 113 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 7466164468..c8e14fe371 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -36,79 +36,79 @@ DEF_HELPER_FLAGS_4(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, i32)
DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32)
#endif
DEF_HELPER_FLAGS_1(get_fsr, TCG_CALL_NO_WG_SE, tl, env)
-DEF_HELPER_FLAGS_2(set_fsr_noftt, 0, void, env, tl)
-DEF_HELPER_FLAGS_2(fsqrts, 0, f32, env, f32)
-DEF_HELPER_FLAGS_2(fsqrtd, 0, f64, env, f64)
-DEF_HELPER_FLAGS_2(fsqrtq, 0, i128, env, i128)
-DEF_HELPER_FLAGS_3(fcmps, 0, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpd, 0, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpes, 0, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmped, 0, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpq, 0, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq, 0, tl, env, i128, i128)
+DEF_HELPER_FLAGS_2(set_fsr_noftt, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(fsqrts, TCG_CALL_NO_WG, f32, env, f32)
+DEF_HELPER_FLAGS_2(fsqrtd, TCG_CALL_NO_WG, f64, env, f64)
+DEF_HELPER_FLAGS_2(fsqrtq, TCG_CALL_NO_WG, i128, env, i128)
+DEF_HELPER_FLAGS_3(fcmps, TCG_CALL_NO_WG, void, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, void, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpes, TCG_CALL_NO_WG, void, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, void, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, void, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, void, env, i128, i128)
#ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_3(fcmps_fcc1, 0, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmps_fcc2, 0, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmps_fcc3, 0, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpd_fcc1, 0, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpd_fcc2, 0, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpd_fcc3, 0, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpes_fcc1, 0, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpes_fcc2, 0, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpes_fcc3, 0, tl, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmped_fcc1, 0, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmped_fcc2, 0, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmped_fcc3, 0, tl, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpq_fcc1, 0, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpq_fcc2, 0, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpq_fcc3, 0, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq_fcc1, 0, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq_fcc2, 0, tl, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq_fcc3, 0, tl, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmps_fcc1, TCG_CALL_NO_WG, void, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmps_fcc2, TCG_CALL_NO_WG, void, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmps_fcc3, TCG_CALL_NO_WG, void, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmpd_fcc1, TCG_CALL_NO_WG, void, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpd_fcc2, TCG_CALL_NO_WG, void, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpd_fcc3, TCG_CALL_NO_WG, void, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpes_fcc1, TCG_CALL_NO_WG, void, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmpes_fcc2, TCG_CALL_NO_WG, void, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmpes_fcc3, TCG_CALL_NO_WG, void, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmped_fcc1, TCG_CALL_NO_WG, void, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmped_fcc2, TCG_CALL_NO_WG, void, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmped_fcc3, TCG_CALL_NO_WG, void, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpq_fcc1, TCG_CALL_NO_WG, void, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpq_fcc2, TCG_CALL_NO_WG, void, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpq_fcc3, TCG_CALL_NO_WG, void, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq_fcc1, TCG_CALL_NO_WG, void, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq_fcc2, TCG_CALL_NO_WG, void, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq_fcc3, TCG_CALL_NO_WG, void, env, i128, i128)
#endif
DEF_HELPER_2(raise_exception, noreturn, env, int)
-DEF_HELPER_FLAGS_3(faddd, 0, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(fsubd, 0, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(fmuld, 0, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(fdivd, 0, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_WG, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_WG, f64, env, f64, f64)
-DEF_HELPER_FLAGS_3(faddq, 0, i128, env, i128, i128)
-DEF_HELPER_FLAGS_3(fsubq, 0, i128, env, i128, i128)
-DEF_HELPER_FLAGS_3(fmulq, 0, i128, env, i128, i128)
-DEF_HELPER_FLAGS_3(fdivq, 0, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(faddq, TCG_CALL_NO_WG, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(fsubq, TCG_CALL_NO_WG, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(fmulq, TCG_CALL_NO_WG, i128, env, i128, i128)
+DEF_HELPER_FLAGS_3(fdivq, TCG_CALL_NO_WG, i128, env, i128, i128)
-DEF_HELPER_FLAGS_3(fadds, 0, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fsubs, 0, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fmuls, 0, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fdivs, 0, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_WG, f32, env, f32, f32)
-DEF_HELPER_FLAGS_3(fsmuld, 0, f64, env, f32, f32)
-DEF_HELPER_FLAGS_3(fdmulq, 0, i128, env, f64, f64)
+DEF_HELPER_FLAGS_3(fsmuld, TCG_CALL_NO_WG, f64, env, f32, f32)
+DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_WG, i128, env, f64, f64)
-DEF_HELPER_FLAGS_2(fitod, 0, f64, env, s32)
-DEF_HELPER_FLAGS_2(fitoq, 0, i128, env, s32)
+DEF_HELPER_FLAGS_2(fitod, TCG_CALL_NO_WG, f64, env, s32)
+DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_WG, i128, env, s32)
-DEF_HELPER_FLAGS_2(fitos, 0, f32, env, s32)
+DEF_HELPER_FLAGS_2(fitos, TCG_CALL_NO_WG, f32, env, s32)
#ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_2(fxtos, 0, f32, env, s64)
-DEF_HELPER_FLAGS_2(fxtod, 0, f64, env, s64)
-DEF_HELPER_FLAGS_2(fxtoq, 0, i128, env, s64)
+DEF_HELPER_FLAGS_2(fxtos, TCG_CALL_NO_WG, f32, env, s64)
+DEF_HELPER_FLAGS_2(fxtod, TCG_CALL_NO_WG, f64, env, s64)
+DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_WG, i128, env, s64)
#endif
-DEF_HELPER_FLAGS_2(fdtos, 0, f32, env, f64)
-DEF_HELPER_FLAGS_2(fstod, 0, f64, env, f32)
-DEF_HELPER_FLAGS_2(fqtos, 0, f32, env, i128)
-DEF_HELPER_FLAGS_2(fstoq, 0, i128, env, f32)
-DEF_HELPER_FLAGS_2(fqtod, 0, f64, env, i128)
-DEF_HELPER_FLAGS_2(fdtoq, 0, i128, env, f64)
-DEF_HELPER_FLAGS_2(fstoi, 0, s32, env, f32)
-DEF_HELPER_FLAGS_2(fdtoi, 0, s32, env, f64)
-DEF_HELPER_FLAGS_2(fqtoi, 0, s32, env, i128)
+DEF_HELPER_FLAGS_2(fdtos, TCG_CALL_NO_WG, f32, env, f64)
+DEF_HELPER_FLAGS_2(fstod, TCG_CALL_NO_WG, f64, env, f32)
+DEF_HELPER_FLAGS_2(fqtos, TCG_CALL_NO_WG, f32, env, i128)
+DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_WG, i128, env, f32)
+DEF_HELPER_FLAGS_2(fqtod, TCG_CALL_NO_WG, f64, env, i128)
+DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_WG, i128, env, f64)
+DEF_HELPER_FLAGS_2(fstoi, TCG_CALL_NO_WG, s32, env, f32)
+DEF_HELPER_FLAGS_2(fdtoi, TCG_CALL_NO_WG, s32, env, f64)
+DEF_HELPER_FLAGS_2(fqtoi, TCG_CALL_NO_WG, s32, env, i128)
#ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_2(fstox, 0, s64, env, f32)
-DEF_HELPER_FLAGS_2(fdtox, 0, s64, env, f64)
-DEF_HELPER_FLAGS_2(fqtox, 0, s64, env, i128)
+DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_WG, s64, env, f32)
+DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_WG, s64, env, f64)
+DEF_HELPER_FLAGS_2(fqtox, TCG_CALL_NO_WG, s64, env, i128)
DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index ac30f88810..796f448bfd 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -344,8 +344,7 @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
}
#define GEN_FCMP(name, size, FS, E) \
- target_ulong glue(helper_, name) (CPUSPARCState *env, \
- Int128 src1, Int128 src2) \
+ void glue(helper_, name)(CPUSPARCState *env, Int128 src1, Int128 src2) \
{ \
float128 reg1 = f128_in(src1); \
float128 reg2 = f128_in(src2); \
@@ -376,10 +375,10 @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
break; \
} \
- return fsr; \
+ env->fsr = fsr; \
}
#define GEN_FCMP_T(name, size, FS, E) \
- target_ulong glue(helper_, name)(CPUSPARCState *env, size src1, size src2)\
+ void glue(helper_, name)(CPUSPARCState *env, size src1, size src2) \
{ \
FloatRelation ret; \
target_ulong fsr; \
@@ -407,7 +406,7 @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
break; \
} \
- return fsr; \
+ env->fsr = fsr; \
}
GEN_FCMP_T(fcmps, float32, 0, 0);
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index d2145dcc0b..4eb6291b81 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -99,7 +99,7 @@
/* global register indexes */
static TCGv_ptr cpu_regwptr;
-static TCGv cpu_fsr, cpu_pc, cpu_npc;
+static TCGv cpu_pc, cpu_npc;
static TCGv cpu_regs[32];
static TCGv cpu_y;
static TCGv cpu_tbr;
@@ -1097,7 +1097,7 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
{
unsigned int offset;
- TCGv r_dst;
+ TCGv r_dst, fsr;
/* For now we still generate a straight boolean result. */
cmp->cond = TCG_COND_NE;
@@ -1120,54 +1120,56 @@ static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
break;
}
+ fsr = tcg_temp_new();
+ tcg_gen_ld_tl(fsr, tcg_env, offsetof(CPUSPARCState, fsr));
switch (cond) {
case 0x0:
gen_op_eval_bn(r_dst);
break;
case 0x1:
- gen_op_eval_fbne(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbne(r_dst, fsr, offset);
break;
case 0x2:
- gen_op_eval_fblg(r_dst, cpu_fsr, offset);
+ gen_op_eval_fblg(r_dst, fsr, offset);
break;
case 0x3:
- gen_op_eval_fbul(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbul(r_dst, fsr, offset);
break;
case 0x4:
- gen_op_eval_fbl(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbl(r_dst, fsr, offset);
break;
case 0x5:
- gen_op_eval_fbug(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbug(r_dst, fsr, offset);
break;
case 0x6:
- gen_op_eval_fbg(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbg(r_dst, fsr, offset);
break;
case 0x7:
- gen_op_eval_fbu(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbu(r_dst, fsr, offset);
break;
case 0x8:
gen_op_eval_ba(r_dst);
break;
case 0x9:
- gen_op_eval_fbe(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbe(r_dst, fsr, offset);
break;
case 0xa:
- gen_op_eval_fbue(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbue(r_dst, fsr, offset);
break;
case 0xb:
- gen_op_eval_fbge(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbge(r_dst, fsr, offset);
break;
case 0xc:
- gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbuge(r_dst, fsr, offset);
break;
case 0xd:
- gen_op_eval_fble(r_dst, cpu_fsr, offset);
+ gen_op_eval_fble(r_dst, fsr, offset);
break;
case 0xe:
- gen_op_eval_fbule(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbule(r_dst, fsr, offset);
break;
case 0xf:
- gen_op_eval_fbo(r_dst, cpu_fsr, offset);
+ gen_op_eval_fbo(r_dst, fsr, offset);
break;
}
}
@@ -1264,16 +1266,16 @@ static void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
{
switch (fccno) {
case 0:
- gen_helper_fcmps(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmps(tcg_env, r_rs1, r_rs2);
break;
case 1:
- gen_helper_fcmps_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmps_fcc1(tcg_env, r_rs1, r_rs2);
break;
case 2:
- gen_helper_fcmps_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmps_fcc2(tcg_env, r_rs1, r_rs2);
break;
case 3:
- gen_helper_fcmps_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmps_fcc3(tcg_env, r_rs1, r_rs2);
break;
}
}
@@ -1282,16 +1284,16 @@ static void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
{
switch (fccno) {
case 0:
- gen_helper_fcmpd(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpd(tcg_env, r_rs1, r_rs2);
break;
case 1:
- gen_helper_fcmpd_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpd_fcc1(tcg_env, r_rs1, r_rs2);
break;
case 2:
- gen_helper_fcmpd_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpd_fcc2(tcg_env, r_rs1, r_rs2);
break;
case 3:
- gen_helper_fcmpd_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpd_fcc3(tcg_env, r_rs1, r_rs2);
break;
}
}
@@ -1300,16 +1302,16 @@ static void gen_op_fcmpq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
{
switch (fccno) {
case 0:
- gen_helper_fcmpq(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpq(tcg_env, r_rs1, r_rs2);
break;
case 1:
- gen_helper_fcmpq_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpq_fcc1(tcg_env, r_rs1, r_rs2);
break;
case 2:
- gen_helper_fcmpq_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpq_fcc2(tcg_env, r_rs1, r_rs2);
break;
case 3:
- gen_helper_fcmpq_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpq_fcc3(tcg_env, r_rs1, r_rs2);
break;
}
}
@@ -1318,16 +1320,16 @@ static void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
{
switch (fccno) {
case 0:
- gen_helper_fcmpes(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpes(tcg_env, r_rs1, r_rs2);
break;
case 1:
- gen_helper_fcmpes_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpes_fcc1(tcg_env, r_rs1, r_rs2);
break;
case 2:
- gen_helper_fcmpes_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpes_fcc2(tcg_env, r_rs1, r_rs2);
break;
case 3:
- gen_helper_fcmpes_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpes_fcc3(tcg_env, r_rs1, r_rs2);
break;
}
}
@@ -1336,16 +1338,16 @@ static void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
{
switch (fccno) {
case 0:
- gen_helper_fcmped(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmped(tcg_env, r_rs1, r_rs2);
break;
case 1:
- gen_helper_fcmped_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmped_fcc1(tcg_env, r_rs1, r_rs2);
break;
case 2:
- gen_helper_fcmped_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmped_fcc2(tcg_env, r_rs1, r_rs2);
break;
case 3:
- gen_helper_fcmped_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmped_fcc3(tcg_env, r_rs1, r_rs2);
break;
}
}
@@ -1354,16 +1356,16 @@ static void gen_op_fcmpeq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
{
switch (fccno) {
case 0:
- gen_helper_fcmpeq(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpeq(tcg_env, r_rs1, r_rs2);
break;
case 1:
- gen_helper_fcmpeq_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpeq_fcc1(tcg_env, r_rs1, r_rs2);
break;
case 2:
- gen_helper_fcmpeq_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpeq_fcc2(tcg_env, r_rs1, r_rs2);
break;
case 3:
- gen_helper_fcmpeq_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpeq_fcc3(tcg_env, r_rs1, r_rs2);
break;
}
}
@@ -1372,32 +1374,32 @@ static void gen_op_fcmpeq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
static void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
{
- gen_helper_fcmps(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmps(tcg_env, r_rs1, r_rs2);
}
static void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
{
- gen_helper_fcmpd(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpd(tcg_env, r_rs1, r_rs2);
}
static void gen_op_fcmpq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
{
- gen_helper_fcmpq(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpq(tcg_env, r_rs1, r_rs2);
}
static void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
{
- gen_helper_fcmpes(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpes(tcg_env, r_rs1, r_rs2);
}
static void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
{
- gen_helper_fcmped(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmped(tcg_env, r_rs1, r_rs2);
}
static void gen_op_fcmpeq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
{
- gen_helper_fcmpeq(cpu_fsr, tcg_env, r_rs1, r_rs2);
+ gen_helper_fcmpeq(tcg_env, r_rs1, r_rs2);
}
#endif
@@ -4413,8 +4415,9 @@ static bool do_ldfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop,
tnew = tcg_temp_new();
told = tcg_temp_new();
tcg_gen_qemu_ld_tl(tnew, addr, dc->mem_idx, mop | MO_ALIGN);
+ tcg_gen_ld_tl(told, tcg_env, offsetof(CPUSPARCState, fsr));
tcg_gen_andi_tl(tnew, tnew, new_mask);
- tcg_gen_andi_tl(told, cpu_fsr, old_mask);
+ tcg_gen_andi_tl(told, told, old_mask);
tcg_gen_or_tl(tnew, tnew, told);
gen_helper_set_fsr_noftt(tcg_env, tnew);
return advance_pc(dc);
@@ -5342,7 +5345,6 @@ void sparc_tcg_init(void)
{ &cpu_icc_Z, offsetof(CPUSPARCState, icc_Z), "icc_Z" },
{ &cpu_icc_C, offsetof(CPUSPARCState, icc_C), "icc_C" },
{ &cpu_cond, offsetof(CPUSPARCState, cond), "cond" },
- { &cpu_fsr, offsetof(CPUSPARCState, fsr), "fsr" },
{ &cpu_pc, offsetof(CPUSPARCState, pc), "pc" },
{ &cpu_npc, offsetof(CPUSPARCState, npc), "npc" },
{ &cpu_y, offsetof(CPUSPARCState, y), "y" },
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 21/22] target/sparc: Split fcc out of env->fsr
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (19 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 20/22] target/sparc: Remove cpu_fsr Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 22/22] target/sparc: Remove FSR_FTT_NMASK, FSR_FTT_CEXC_NMASK Richard Henderson
2024-01-28 6:49 ` [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Represent each fcc field separately from the rest of fsr.
This vastly simplifies floating-point comparisons.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/cpu.h | 20 +-
target/sparc/helper.h | 34 +--
target/sparc/fop_helper.c | 169 ++++++-------
target/sparc/translate.c | 503 +++++++++-----------------------------
4 files changed, 201 insertions(+), 525 deletions(-)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 90a7dfb004..30bab9a7b3 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -31,8 +31,10 @@
#if !defined(TARGET_SPARC64)
#define TARGET_DPREGS 16
+#define TARGET_FCCREGS 1
#else
#define TARGET_DPREGS 32
+#define TARGET_FCCREGS 4
#endif
/*#define EXCP_INTERRUPT 0x100*/
@@ -203,24 +205,19 @@ enum {
#ifdef TARGET_SPARC64
#define FSR_FTT_NMASK 0xfffffffffffe3fffULL
#define FSR_FTT_CEXC_NMASK 0xfffffffffffe3fe0ULL
-#define FSR_LDFSR_OLDMASK 0x0000003f000fc000ULL
-#define FSR_LDXFSR_MASK 0x0000003fcfc00fffULL
-#define FSR_LDXFSR_OLDMASK 0x00000000000fc000ULL
#else
#define FSR_FTT_NMASK 0xfffe3fffULL
#define FSR_FTT_CEXC_NMASK 0xfffe3fe0ULL
-#define FSR_LDFSR_OLDMASK 0x000fc000ULL
#endif
-#define FSR_LDFSR_MASK 0xcfc00fffULL
#define FSR_FTT_IEEE_EXCP (1ULL << 14)
#define FSR_FTT_UNIMPFPOP (3ULL << 14)
#define FSR_FTT_SEQ_ERROR (4ULL << 14)
#define FSR_FTT_INVAL_FPR (6ULL << 14)
-#define FSR_FCC1_SHIFT 11
-#define FSR_FCC1 (1ULL << FSR_FCC1_SHIFT)
-#define FSR_FCC0_SHIFT 10
-#define FSR_FCC0 (1ULL << FSR_FCC0_SHIFT)
+#define FSR_FCC0_SHIFT 10
+#define FSR_FCC1_SHIFT 32
+#define FSR_FCC2_SHIFT 34
+#define FSR_FCC3_SHIFT 36
/* MMU */
#define MMU_E (1<<0)
@@ -467,8 +464,9 @@ struct CPUArchState {
temporary register when possible) */
/* FPU State Register, in parts */
- target_ulong fsr; /* rm, tem, aexc, fcc* */
- uint32_t fsr_cexc_ftt; /* cexc, ftt */
+ uint32_t fsr; /* rm, tem, aexc */
+ uint32_t fsr_cexc_ftt; /* cexc, ftt */
+ uint32_t fcc[TARGET_FCCREGS]; /* fcc* */
CPU_DoubleU fpr[TARGET_DPREGS]; /* floating point registers */
uint32_t cwp; /* index of current register window (extracted
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index c8e14fe371..6a42ba4e9e 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -36,36 +36,16 @@ DEF_HELPER_FLAGS_4(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, i32)
DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32)
#endif
DEF_HELPER_FLAGS_1(get_fsr, TCG_CALL_NO_WG_SE, tl, env)
-DEF_HELPER_FLAGS_2(set_fsr_noftt, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(set_fsr_nofcc_noftt, TCG_CALL_NO_RWG, void, env, i32)
DEF_HELPER_FLAGS_2(fsqrts, TCG_CALL_NO_WG, f32, env, f32)
DEF_HELPER_FLAGS_2(fsqrtd, TCG_CALL_NO_WG, f64, env, f64)
DEF_HELPER_FLAGS_2(fsqrtq, TCG_CALL_NO_WG, i128, env, i128)
-DEF_HELPER_FLAGS_3(fcmps, TCG_CALL_NO_WG, void, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, void, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpes, TCG_CALL_NO_WG, void, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, void, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, void, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, void, env, i128, i128)
-#ifdef TARGET_SPARC64
-DEF_HELPER_FLAGS_3(fcmps_fcc1, TCG_CALL_NO_WG, void, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmps_fcc2, TCG_CALL_NO_WG, void, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmps_fcc3, TCG_CALL_NO_WG, void, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpd_fcc1, TCG_CALL_NO_WG, void, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpd_fcc2, TCG_CALL_NO_WG, void, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpd_fcc3, TCG_CALL_NO_WG, void, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpes_fcc1, TCG_CALL_NO_WG, void, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpes_fcc2, TCG_CALL_NO_WG, void, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmpes_fcc3, TCG_CALL_NO_WG, void, env, f32, f32)
-DEF_HELPER_FLAGS_3(fcmped_fcc1, TCG_CALL_NO_WG, void, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmped_fcc2, TCG_CALL_NO_WG, void, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmped_fcc3, TCG_CALL_NO_WG, void, env, f64, f64)
-DEF_HELPER_FLAGS_3(fcmpq_fcc1, TCG_CALL_NO_WG, void, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpq_fcc2, TCG_CALL_NO_WG, void, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpq_fcc3, TCG_CALL_NO_WG, void, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq_fcc1, TCG_CALL_NO_WG, void, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq_fcc2, TCG_CALL_NO_WG, void, env, i128, i128)
-DEF_HELPER_FLAGS_3(fcmpeq_fcc3, TCG_CALL_NO_WG, void, env, i128, i128)
-#endif
+DEF_HELPER_FLAGS_3(fcmps, TCG_CALL_NO_WG, i32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmpes, TCG_CALL_NO_WG, i32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
+DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
+DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
DEF_HELPER_2(raise_exception, noreturn, env, int)
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 796f448bfd..1205a599ef 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -343,113 +343,80 @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
return f128_ret(ret);
}
-#define GEN_FCMP(name, size, FS, E) \
- void glue(helper_, name)(CPUSPARCState *env, Int128 src1, Int128 src2) \
- { \
- float128 reg1 = f128_in(src1); \
- float128 reg2 = f128_in(src2); \
- FloatRelation ret; \
- target_ulong fsr; \
- if (E) { \
- ret = glue(size, _compare)(reg1, reg2, &env->fp_status); \
- } else { \
- ret = glue(size, _compare_quiet)(reg1, reg2, \
- &env->fp_status); \
- } \
- check_ieee_exceptions(env, GETPC()); \
- fsr = env->fsr; \
- switch (ret) { \
- case float_relation_unordered: \
- fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
- fsr |= FSR_NVA; \
- break; \
- case float_relation_less: \
- fsr &= ~(FSR_FCC1) << FS; \
- fsr |= FSR_FCC0 << FS; \
- break; \
- case float_relation_greater: \
- fsr &= ~(FSR_FCC0) << FS; \
- fsr |= FSR_FCC1 << FS; \
- break; \
- default: \
- fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
- break; \
- } \
- env->fsr = fsr; \
- }
-#define GEN_FCMP_T(name, size, FS, E) \
- void glue(helper_, name)(CPUSPARCState *env, size src1, size src2) \
- { \
- FloatRelation ret; \
- target_ulong fsr; \
- if (E) { \
- ret = glue(size, _compare)(src1, src2, &env->fp_status); \
- } else { \
- ret = glue(size, _compare_quiet)(src1, src2, \
- &env->fp_status); \
- } \
- check_ieee_exceptions(env, GETPC()); \
- fsr = env->fsr; \
- switch (ret) { \
- case float_relation_unordered: \
- fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
- break; \
- case float_relation_less: \
- fsr &= ~(FSR_FCC1 << FS); \
- fsr |= FSR_FCC0 << FS; \
- break; \
- case float_relation_greater: \
- fsr &= ~(FSR_FCC0 << FS); \
- fsr |= FSR_FCC1 << FS; \
- break; \
- default: \
- fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
- break; \
- } \
- env->fsr = fsr; \
+static uint32_t finish_fcmp(CPUSPARCState *env, FloatRelation r, uintptr_t ra)
+{
+ check_ieee_exceptions(env, ra);
+
+ /*
+ * FCC values:
+ * 0 =
+ * 1 <
+ * 2 >
+ * 3 unordered
+ */
+ switch (r) {
+ case float_relation_equal:
+ return 0;
+ case float_relation_less:
+ return 1;
+ case float_relation_greater:
+ return 2;
+ case float_relation_unordered:
+ env->fsr |= FSR_NVA;
+ return 3;
}
+ g_assert_not_reached();
+}
-GEN_FCMP_T(fcmps, float32, 0, 0);
-GEN_FCMP_T(fcmpd, float64, 0, 0);
+uint32_t helper_fcmps(CPUSPARCState *env, float32 src1, float32 src2)
+{
+ FloatRelation r = float32_compare_quiet(src1, src2, &env->fp_status);
+ return finish_fcmp(env, r, GETPC());
+}
-GEN_FCMP_T(fcmpes, float32, 0, 1);
-GEN_FCMP_T(fcmped, float64, 0, 1);
+uint32_t helper_fcmpes(CPUSPARCState *env, float32 src1, float32 src2)
+{
+ FloatRelation r = float32_compare(src1, src2, &env->fp_status);
+ return finish_fcmp(env, r, GETPC());
+}
-GEN_FCMP(fcmpq, float128, 0, 0);
-GEN_FCMP(fcmpeq, float128, 0, 1);
+uint32_t helper_fcmpd(CPUSPARCState *env, float64 src1, float64 src2)
+{
+ FloatRelation r = float64_compare_quiet(src1, src2, &env->fp_status);
+ return finish_fcmp(env, r, GETPC());
+}
-#ifdef TARGET_SPARC64
-GEN_FCMP_T(fcmps_fcc1, float32, 22, 0);
-GEN_FCMP_T(fcmpd_fcc1, float64, 22, 0);
-GEN_FCMP(fcmpq_fcc1, float128, 22, 0);
+uint32_t helper_fcmped(CPUSPARCState *env, float64 src1, float64 src2)
+{
+ FloatRelation r = float64_compare(src1, src2, &env->fp_status);
+ return finish_fcmp(env, r, GETPC());
+}
-GEN_FCMP_T(fcmps_fcc2, float32, 24, 0);
-GEN_FCMP_T(fcmpd_fcc2, float64, 24, 0);
-GEN_FCMP(fcmpq_fcc2, float128, 24, 0);
+uint32_t helper_fcmpq(CPUSPARCState *env, Int128 src1, Int128 src2)
+{
+ FloatRelation r = float128_compare_quiet(f128_in(src1), f128_in(src2),
+ &env->fp_status);
+ return finish_fcmp(env, r, GETPC());
+}
-GEN_FCMP_T(fcmps_fcc3, float32, 26, 0);
-GEN_FCMP_T(fcmpd_fcc3, float64, 26, 0);
-GEN_FCMP(fcmpq_fcc3, float128, 26, 0);
-
-GEN_FCMP_T(fcmpes_fcc1, float32, 22, 1);
-GEN_FCMP_T(fcmped_fcc1, float64, 22, 1);
-GEN_FCMP(fcmpeq_fcc1, float128, 22, 1);
-
-GEN_FCMP_T(fcmpes_fcc2, float32, 24, 1);
-GEN_FCMP_T(fcmped_fcc2, float64, 24, 1);
-GEN_FCMP(fcmpeq_fcc2, float128, 24, 1);
-
-GEN_FCMP_T(fcmpes_fcc3, float32, 26, 1);
-GEN_FCMP_T(fcmped_fcc3, float64, 26, 1);
-GEN_FCMP(fcmpeq_fcc3, float128, 26, 1);
-#endif
-#undef GEN_FCMP_T
-#undef GEN_FCMP
+uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
+{
+ FloatRelation r = float128_compare(f128_in(src1), f128_in(src2),
+ &env->fp_status);
+ return finish_fcmp(env, r, GETPC());
+}
target_ulong cpu_get_fsr(CPUSPARCState *env)
{
target_ulong fsr = env->fsr | env->fsr_cexc_ftt;
+ fsr |= env->fcc[0] << FSR_FCC0_SHIFT;
+#ifdef TARGET_SPARC64
+ fsr |= (uint64_t)env->fcc[1] << FSR_FCC1_SHIFT;
+ fsr |= (uint64_t)env->fcc[2] << FSR_FCC2_SHIFT;
+ fsr |= (uint64_t)env->fcc[3] << FSR_FCC3_SHIFT;
+#endif
+
/* VER is kept completely separate until re-assembly. */
fsr |= env->def.fpu_version;
@@ -465,7 +432,7 @@ static void set_fsr_nonsplit(CPUSPARCState *env, target_ulong fsr)
{
int rnd_mode;
- env->fsr = fsr & ~(FSR_VER_MASK | FSR_CEXC_MASK | FSR_FTT_MASK);
+ env->fsr = fsr & (FSR_RD_MASK | FSR_TEM_MASK | FSR_AEXC_MASK);
switch (fsr & FSR_RD_MASK) {
case FSR_RD_NEAREST:
@@ -488,10 +455,18 @@ static void set_fsr_nonsplit(CPUSPARCState *env, target_ulong fsr)
void cpu_put_fsr(CPUSPARCState *env, target_ulong fsr)
{
env->fsr_cexc_ftt = fsr & (FSR_CEXC_MASK | FSR_FTT_MASK);
+
+ env->fcc[0] = extract32(fsr, FSR_FCC0_SHIFT, 2);
+#ifdef TARGET_SPARC64
+ env->fcc[1] = extract64(fsr, FSR_FCC1_SHIFT, 2);
+ env->fcc[2] = extract64(fsr, FSR_FCC2_SHIFT, 2);
+ env->fcc[3] = extract64(fsr, FSR_FCC3_SHIFT, 2);
+#endif
+
set_fsr_nonsplit(env, fsr);
}
-void helper_set_fsr_noftt(CPUSPARCState *env, target_ulong fsr)
+void helper_set_fsr_nofcc_noftt(CPUSPARCState *env, uint32_t fsr)
{
env->fsr_cexc_ftt &= FSR_FTT_MASK;
env->fsr_cexc_ftt |= fsr & FSR_CEXC_MASK;
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 4eb6291b81..b83b4369fd 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -83,8 +83,6 @@
# define gen_helper_fxtoq ({ qemu_build_not_reached(); NULL; })
# define gen_helper_fxtos ({ qemu_build_not_reached(); NULL; })
# define gen_helper_pdist ({ qemu_build_not_reached(); NULL; })
-# define FSR_LDXFSR_MASK 0
-# define FSR_LDXFSR_OLDMASK 0
# define MAXTL_MASK 0
#endif
@@ -130,6 +128,7 @@ static TCGv cpu_gsr;
/* Floating point registers */
static TCGv_i64 cpu_fpr[TARGET_DPREGS];
+static TCGv_i32 cpu_fcc[TARGET_FCCREGS];
#define env_field_offsetof(X) offsetof(CPUSPARCState, X)
#ifdef TARGET_SPARC64
@@ -719,159 +718,6 @@ static void gen_op_bshuffle(TCGv_i64 dst, TCGv_i64 src1, TCGv_i64 src2)
#endif
}
-// 1
-static void gen_op_eval_ba(TCGv dst)
-{
- tcg_gen_movi_tl(dst, 1);
-}
-
-// 0
-static void gen_op_eval_bn(TCGv dst)
-{
- tcg_gen_movi_tl(dst, 0);
-}
-
-/*
- FPSR bit field FCC1 | FCC0:
- 0 =
- 1 <
- 2 >
- 3 unordered
-*/
-static void gen_mov_reg_FCC0(TCGv reg, TCGv src,
- unsigned int fcc_offset)
-{
- tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
- tcg_gen_andi_tl(reg, reg, 0x1);
-}
-
-static void gen_mov_reg_FCC1(TCGv reg, TCGv src, unsigned int fcc_offset)
-{
- tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
- tcg_gen_andi_tl(reg, reg, 0x1);
-}
-
-// !0: FCC0 | FCC1
-static void gen_op_eval_fbne(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- TCGv t0 = tcg_temp_new();
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(t0, src, fcc_offset);
- tcg_gen_or_tl(dst, dst, t0);
-}
-
-// 1 or 2: FCC0 ^ FCC1
-static void gen_op_eval_fblg(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- TCGv t0 = tcg_temp_new();
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(t0, src, fcc_offset);
- tcg_gen_xor_tl(dst, dst, t0);
-}
-
-// 1 or 3: FCC0
-static void gen_op_eval_fbul(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- gen_mov_reg_FCC0(dst, src, fcc_offset);
-}
-
-// 1: FCC0 & !FCC1
-static void gen_op_eval_fbl(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- TCGv t0 = tcg_temp_new();
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(t0, src, fcc_offset);
- tcg_gen_andc_tl(dst, dst, t0);
-}
-
-// 2 or 3: FCC1
-static void gen_op_eval_fbug(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- gen_mov_reg_FCC1(dst, src, fcc_offset);
-}
-
-// 2: !FCC0 & FCC1
-static void gen_op_eval_fbg(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- TCGv t0 = tcg_temp_new();
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(t0, src, fcc_offset);
- tcg_gen_andc_tl(dst, t0, dst);
-}
-
-// 3: FCC0 & FCC1
-static void gen_op_eval_fbu(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- TCGv t0 = tcg_temp_new();
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(t0, src, fcc_offset);
- tcg_gen_and_tl(dst, dst, t0);
-}
-
-// 0: !(FCC0 | FCC1)
-static void gen_op_eval_fbe(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- TCGv t0 = tcg_temp_new();
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(t0, src, fcc_offset);
- tcg_gen_or_tl(dst, dst, t0);
- tcg_gen_xori_tl(dst, dst, 0x1);
-}
-
-// 0 or 3: !(FCC0 ^ FCC1)
-static void gen_op_eval_fbue(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- TCGv t0 = tcg_temp_new();
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(t0, src, fcc_offset);
- tcg_gen_xor_tl(dst, dst, t0);
- tcg_gen_xori_tl(dst, dst, 0x1);
-}
-
-// 0 or 2: !FCC0
-static void gen_op_eval_fbge(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- tcg_gen_xori_tl(dst, dst, 0x1);
-}
-
-// !1: !(FCC0 & !FCC1)
-static void gen_op_eval_fbuge(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- TCGv t0 = tcg_temp_new();
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(t0, src, fcc_offset);
- tcg_gen_andc_tl(dst, dst, t0);
- tcg_gen_xori_tl(dst, dst, 0x1);
-}
-
-// 0 or 1: !FCC1
-static void gen_op_eval_fble(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- gen_mov_reg_FCC1(dst, src, fcc_offset);
- tcg_gen_xori_tl(dst, dst, 0x1);
-}
-
-// !2: !(!FCC0 & FCC1)
-static void gen_op_eval_fbule(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- TCGv t0 = tcg_temp_new();
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(t0, src, fcc_offset);
- tcg_gen_andc_tl(dst, t0, dst);
- tcg_gen_xori_tl(dst, dst, 0x1);
-}
-
-// !3: !(FCC0 & FCC1)
-static void gen_op_eval_fbo(TCGv dst, TCGv src, unsigned int fcc_offset)
-{
- TCGv t0 = tcg_temp_new();
- gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(t0, src, fcc_offset);
- tcg_gen_and_tl(dst, dst, t0);
- tcg_gen_xori_tl(dst, dst, 0x1);
-}
-
static void finishing_insn(DisasContext *dc)
{
/*
@@ -1096,82 +942,62 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
{
- unsigned int offset;
- TCGv r_dst, fsr;
+ TCGv_i32 fcc = cpu_fcc[cc];
+ TCGv_i32 c1 = fcc;
+ int c2 = 0;
+ TCGCond tcond;
- /* For now we still generate a straight boolean result. */
- cmp->cond = TCG_COND_NE;
- cmp->c1 = r_dst = tcg_temp_new();
- cmp->c2 = 0;
-
- switch (cc) {
- default:
- case 0x0:
- offset = 0;
+ /*
+ * FCC values:
+ * 0 =
+ * 1 <
+ * 2 >
+ * 3 unordered
+ */
+ switch (cond & 7) {
+ case 0x0: /* fbn */
+ tcond = TCG_COND_NEVER;
break;
- case 0x1:
- offset = 32 - 10;
+ case 0x1: /* fbne : !0 */
+ tcond = TCG_COND_NE;
break;
- case 0x2:
- offset = 34 - 10;
+ case 0x2: /* fblg : 1 or 2 */
+ /* fcc in {1,2} - 1 -> fcc in {0,1} */
+ c1 = tcg_temp_new_i32();
+ tcg_gen_addi_i32(c1, fcc, -1);
+ c2 = 1;
+ tcond = TCG_COND_LEU;
break;
- case 0x3:
- offset = 36 - 10;
+ case 0x3: /* fbul : 1 or 3 */
+ c1 = tcg_temp_new_i32();
+ tcg_gen_andi_i32(c1, fcc, 1);
+ tcond = TCG_COND_NE;
+ break;
+ case 0x4: /* fbl : 1 */
+ c2 = 1;
+ tcond = TCG_COND_EQ;
+ break;
+ case 0x5: /* fbug : 2 or 3 */
+ c2 = 2;
+ tcond = TCG_COND_GEU;
+ break;
+ case 0x6: /* fbg : 2 */
+ c2 = 2;
+ tcond = TCG_COND_EQ;
+ break;
+ case 0x7: /* fbu : 3 */
+ c2 = 3;
+ tcond = TCG_COND_EQ;
break;
}
-
- fsr = tcg_temp_new();
- tcg_gen_ld_tl(fsr, tcg_env, offsetof(CPUSPARCState, fsr));
- switch (cond) {
- case 0x0:
- gen_op_eval_bn(r_dst);
- break;
- case 0x1:
- gen_op_eval_fbne(r_dst, fsr, offset);
- break;
- case 0x2:
- gen_op_eval_fblg(r_dst, fsr, offset);
- break;
- case 0x3:
- gen_op_eval_fbul(r_dst, fsr, offset);
- break;
- case 0x4:
- gen_op_eval_fbl(r_dst, fsr, offset);
- break;
- case 0x5:
- gen_op_eval_fbug(r_dst, fsr, offset);
- break;
- case 0x6:
- gen_op_eval_fbg(r_dst, fsr, offset);
- break;
- case 0x7:
- gen_op_eval_fbu(r_dst, fsr, offset);
- break;
- case 0x8:
- gen_op_eval_ba(r_dst);
- break;
- case 0x9:
- gen_op_eval_fbe(r_dst, fsr, offset);
- break;
- case 0xa:
- gen_op_eval_fbue(r_dst, fsr, offset);
- break;
- case 0xb:
- gen_op_eval_fbge(r_dst, fsr, offset);
- break;
- case 0xc:
- gen_op_eval_fbuge(r_dst, fsr, offset);
- break;
- case 0xd:
- gen_op_eval_fble(r_dst, fsr, offset);
- break;
- case 0xe:
- gen_op_eval_fbule(r_dst, fsr, offset);
- break;
- case 0xf:
- gen_op_eval_fbo(r_dst, fsr, offset);
- break;
+ if (cond & 8) {
+ tcond = tcg_invert_cond(tcond);
}
+
+ cmp->cond = tcond;
+ cmp->c2 = c2;
+ cmp->c1 = tcg_temp_new();
+ tcg_gen_extu_i32_tl(cmp->c1, c1);
}
static bool gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
@@ -1261,148 +1087,6 @@ static void gen_op_fabsq(TCGv_i128 dst, TCGv_i128 src)
tcg_gen_concat_i64_i128(dst, l, h);
}
-#ifdef TARGET_SPARC64
-static void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
-{
- switch (fccno) {
- case 0:
- gen_helper_fcmps(tcg_env, r_rs1, r_rs2);
- break;
- case 1:
- gen_helper_fcmps_fcc1(tcg_env, r_rs1, r_rs2);
- break;
- case 2:
- gen_helper_fcmps_fcc2(tcg_env, r_rs1, r_rs2);
- break;
- case 3:
- gen_helper_fcmps_fcc3(tcg_env, r_rs1, r_rs2);
- break;
- }
-}
-
-static void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
-{
- switch (fccno) {
- case 0:
- gen_helper_fcmpd(tcg_env, r_rs1, r_rs2);
- break;
- case 1:
- gen_helper_fcmpd_fcc1(tcg_env, r_rs1, r_rs2);
- break;
- case 2:
- gen_helper_fcmpd_fcc2(tcg_env, r_rs1, r_rs2);
- break;
- case 3:
- gen_helper_fcmpd_fcc3(tcg_env, r_rs1, r_rs2);
- break;
- }
-}
-
-static void gen_op_fcmpq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
-{
- switch (fccno) {
- case 0:
- gen_helper_fcmpq(tcg_env, r_rs1, r_rs2);
- break;
- case 1:
- gen_helper_fcmpq_fcc1(tcg_env, r_rs1, r_rs2);
- break;
- case 2:
- gen_helper_fcmpq_fcc2(tcg_env, r_rs1, r_rs2);
- break;
- case 3:
- gen_helper_fcmpq_fcc3(tcg_env, r_rs1, r_rs2);
- break;
- }
-}
-
-static void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
-{
- switch (fccno) {
- case 0:
- gen_helper_fcmpes(tcg_env, r_rs1, r_rs2);
- break;
- case 1:
- gen_helper_fcmpes_fcc1(tcg_env, r_rs1, r_rs2);
- break;
- case 2:
- gen_helper_fcmpes_fcc2(tcg_env, r_rs1, r_rs2);
- break;
- case 3:
- gen_helper_fcmpes_fcc3(tcg_env, r_rs1, r_rs2);
- break;
- }
-}
-
-static void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
-{
- switch (fccno) {
- case 0:
- gen_helper_fcmped(tcg_env, r_rs1, r_rs2);
- break;
- case 1:
- gen_helper_fcmped_fcc1(tcg_env, r_rs1, r_rs2);
- break;
- case 2:
- gen_helper_fcmped_fcc2(tcg_env, r_rs1, r_rs2);
- break;
- case 3:
- gen_helper_fcmped_fcc3(tcg_env, r_rs1, r_rs2);
- break;
- }
-}
-
-static void gen_op_fcmpeq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
-{
- switch (fccno) {
- case 0:
- gen_helper_fcmpeq(tcg_env, r_rs1, r_rs2);
- break;
- case 1:
- gen_helper_fcmpeq_fcc1(tcg_env, r_rs1, r_rs2);
- break;
- case 2:
- gen_helper_fcmpeq_fcc2(tcg_env, r_rs1, r_rs2);
- break;
- case 3:
- gen_helper_fcmpeq_fcc3(tcg_env, r_rs1, r_rs2);
- break;
- }
-}
-
-#else
-
-static void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
-{
- gen_helper_fcmps(tcg_env, r_rs1, r_rs2);
-}
-
-static void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
-{
- gen_helper_fcmpd(tcg_env, r_rs1, r_rs2);
-}
-
-static void gen_op_fcmpq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
-{
- gen_helper_fcmpq(tcg_env, r_rs1, r_rs2);
-}
-
-static void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
-{
- gen_helper_fcmpes(tcg_env, r_rs1, r_rs2);
-}
-
-static void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
-{
- gen_helper_fcmped(tcg_env, r_rs1, r_rs2);
-}
-
-static void gen_op_fcmpeq(int fccno, TCGv_i128 r_rs1, TCGv_i128 r_rs2)
-{
- gen_helper_fcmpeq(tcg_env, r_rs1, r_rs2);
-}
-#endif
-
static void gen_op_fpexception_im(DisasContext *dc, int ftt)
{
/*
@@ -4400,11 +4084,10 @@ static bool trans_STDFQ(DisasContext *dc, arg_STDFQ *a)
return true;
}
-static bool do_ldfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop,
- target_ulong new_mask, target_ulong old_mask)
+static bool trans_LDFSR(DisasContext *dc, arg_r_r_ri *a)
{
TCGv addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
- TCGv tnew, told;
+ TCGv_i32 tmp;
if (addr == NULL) {
return false;
@@ -4412,19 +4095,48 @@ static bool do_ldfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop,
if (gen_trap_ifnofpu(dc)) {
return true;
}
- tnew = tcg_temp_new();
- told = tcg_temp_new();
- tcg_gen_qemu_ld_tl(tnew, addr, dc->mem_idx, mop | MO_ALIGN);
- tcg_gen_ld_tl(told, tcg_env, offsetof(CPUSPARCState, fsr));
- tcg_gen_andi_tl(tnew, tnew, new_mask);
- tcg_gen_andi_tl(told, told, old_mask);
- tcg_gen_or_tl(tnew, tnew, told);
- gen_helper_set_fsr_noftt(tcg_env, tnew);
+
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld_i32(tmp, addr, dc->mem_idx, MO_TEUL | MO_ALIGN);
+
+ tcg_gen_extract_i32(cpu_fcc[0], tmp, FSR_FCC0_SHIFT, 2);
+ /* LDFSR does not change FCC[1-3]. */
+
+ gen_helper_set_fsr_nofcc_noftt(tcg_env, tmp);
return advance_pc(dc);
}
-TRANS(LDFSR, ALL, do_ldfsr, a, MO_TEUL, FSR_LDFSR_MASK, FSR_LDFSR_OLDMASK)
-TRANS(LDXFSR, 64, do_ldfsr, a, MO_TEUQ, FSR_LDXFSR_MASK, FSR_LDXFSR_OLDMASK)
+static bool trans_LDXFSR(DisasContext *dc, arg_r_r_ri *a)
+{
+#ifdef TARGET_SPARC64
+ TCGv addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ TCGv_i64 t64;
+ TCGv_i32 lo, hi;
+
+ if (addr == NULL) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ t64 = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_i64(t64, addr, dc->mem_idx, MO_TEUQ | MO_ALIGN);
+
+ lo = tcg_temp_new_i32();
+ hi = cpu_fcc[3];
+ tcg_gen_extr_i64_i32(lo, hi, t64);
+ tcg_gen_extract_i32(cpu_fcc[0], lo, FSR_FCC0_SHIFT, 2);
+ tcg_gen_extract_i32(cpu_fcc[1], hi, FSR_FCC1_SHIFT - 32, 2);
+ tcg_gen_extract_i32(cpu_fcc[2], hi, FSR_FCC2_SHIFT - 32, 2);
+ tcg_gen_extract_i32(cpu_fcc[3], hi, FSR_FCC3_SHIFT - 32, 2);
+
+ gen_helper_set_fsr_nofcc_noftt(tcg_env, lo);
+ return advance_pc(dc);
+#else
+ return false;
+#endif
+}
static bool do_stfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop)
{
@@ -5075,9 +4787,9 @@ static bool do_fcmps(DisasContext *dc, arg_FCMPs *a, bool e)
src1 = gen_load_fpr_F(dc, a->rs1);
src2 = gen_load_fpr_F(dc, a->rs2);
if (e) {
- gen_op_fcmpes(a->cc, src1, src2);
+ gen_helper_fcmpes(cpu_fcc[a->cc], tcg_env, src1, src2);
} else {
- gen_op_fcmps(a->cc, src1, src2);
+ gen_helper_fcmps(cpu_fcc[a->cc], tcg_env, src1, src2);
}
return advance_pc(dc);
}
@@ -5099,9 +4811,9 @@ static bool do_fcmpd(DisasContext *dc, arg_FCMPd *a, bool e)
src1 = gen_load_fpr_D(dc, a->rs1);
src2 = gen_load_fpr_D(dc, a->rs2);
if (e) {
- gen_op_fcmped(a->cc, src1, src2);
+ gen_helper_fcmped(cpu_fcc[a->cc], tcg_env, src1, src2);
} else {
- gen_op_fcmpd(a->cc, src1, src2);
+ gen_helper_fcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
}
return advance_pc(dc);
}
@@ -5126,9 +4838,9 @@ static bool do_fcmpq(DisasContext *dc, arg_FCMPq *a, bool e)
src1 = gen_load_fpr_Q(dc, a->rs1);
src2 = gen_load_fpr_Q(dc, a->rs2);
if (e) {
- gen_op_fcmpeq(a->cc, src1, src2);
+ gen_helper_fcmpeq(cpu_fcc[a->cc], tcg_env, src1, src2);
} else {
- gen_op_fcmpq(a->cc, src1, src2);
+ gen_helper_fcmpq(cpu_fcc[a->cc], tcg_env, src1, src2);
}
return advance_pc(dc);
}
@@ -5334,6 +5046,18 @@ void sparc_tcg_init(void)
"f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
};
+ static const struct { TCGv_i32 *ptr; int off; const char *name; } r32[] = {
+#ifdef TARGET_SPARC64
+ { &cpu_fprs, offsetof(CPUSPARCState, fprs), "fprs" },
+ { &cpu_fcc[0], offsetof(CPUSPARCState, fcc[0]), "fcc0" },
+ { &cpu_fcc[1], offsetof(CPUSPARCState, fcc[1]), "fcc1" },
+ { &cpu_fcc[2], offsetof(CPUSPARCState, fcc[2]), "fcc2" },
+ { &cpu_fcc[3], offsetof(CPUSPARCState, fcc[3]), "fcc3" },
+#else
+ { &cpu_fcc[0], offsetof(CPUSPARCState, fcc[0]), "fcc" },
+#endif
+ };
+
static const struct { TCGv *ptr; int off; const char *name; } rtl[] = {
#ifdef TARGET_SPARC64
{ &cpu_gsr, offsetof(CPUSPARCState, gsr), "gsr" },
@@ -5357,6 +5081,10 @@ void sparc_tcg_init(void)
offsetof(CPUSPARCState, regwptr),
"regwptr");
+ for (i = 0; i < ARRAY_SIZE(r32); ++i) {
+ *r32[i].ptr = tcg_global_mem_new_i32(tcg_env, r32[i].off, r32[i].name);
+ }
+
for (i = 0; i < ARRAY_SIZE(rtl); ++i) {
*rtl[i].ptr = tcg_global_mem_new(tcg_env, rtl[i].off, rtl[i].name);
}
@@ -5379,11 +5107,6 @@ void sparc_tcg_init(void)
offsetof(CPUSPARCState, fpr[i]),
fregnames[i]);
}
-
-#ifdef TARGET_SPARC64
- cpu_fprs = tcg_global_mem_new_i32(tcg_env,
- offsetof(CPUSPARCState, fprs), "fprs");
-#endif
}
void sparc_restore_state_to_opc(CPUState *cs,
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH 22/22] target/sparc: Remove FSR_FTT_NMASK, FSR_FTT_CEXC_NMASK
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (20 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 21/22] target/sparc: Split fcc out of env->fsr Richard Henderson
@ 2023-11-03 17:38 ` Richard Henderson
2024-01-28 6:49 ` [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
22 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-11-03 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
These macros are no longer used.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/cpu.h | 7 -------
1 file changed, 7 deletions(-)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 30bab9a7b3..9ca9fb30ff 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -202,13 +202,6 @@ enum {
#define FSR_FTT1 (1ULL << 15)
#define FSR_FTT0 (1ULL << 14)
#define FSR_FTT_MASK (FSR_FTT2 | FSR_FTT1 | FSR_FTT0)
-#ifdef TARGET_SPARC64
-#define FSR_FTT_NMASK 0xfffffffffffe3fffULL
-#define FSR_FTT_CEXC_NMASK 0xfffffffffffe3fe0ULL
-#else
-#define FSR_FTT_NMASK 0xfffe3fffULL
-#define FSR_FTT_CEXC_NMASK 0xfffe3fe0ULL
-#endif
#define FSR_FTT_IEEE_EXCP (1ULL << 14)
#define FSR_FTT_UNIMPFPOP (3ULL << 14)
#define FSR_FTT_SEQ_ERROR (4ULL << 14)
--
2.34.1
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH 00/22] target/sparc: floating-point cleanup
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
` (21 preceding siblings ...)
2023-11-03 17:38 ` [PATCH 22/22] target/sparc: Remove FSR_FTT_NMASK, FSR_FTT_CEXC_NMASK Richard Henderson
@ 2024-01-28 6:49 ` Richard Henderson
2024-01-29 21:50 ` Mark Cave-Ayland
2024-01-31 21:49 ` Mark Cave-Ayland
22 siblings, 2 replies; 35+ messages in thread
From: Richard Henderson @ 2024-01-28 6:49 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
On 11/4/23 03:38, Richard Henderson wrote:
> Major changes:
>
> (1) Get rid of the env->qt[01] temporaries and use TCGv_i128 for float128.
> (2) Perform ieee exception check within the helpers, before any writeback
> to the floating point registers.
> (3) Split env->fsr into pieces to simplify update, especially compares.
>
>
> r~
>
>
> Based-on: 20231101041132.174501-1-richard.henderson@linaro.org
> ("[PATCH v2 00/21] target/sparc: Cleanup condition codes etc")
Ping.
Prerequisites are upstream, and it rebases cleanly on master.
For reference,
https://gitlab.com/rth7680/qemu/-/commits/tgt-sparc-fp
r~
>
>
> Richard Henderson (22):
> target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for ASI_M_BCOPY
> target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for ASI_M_BFILL
> target/sparc: Remove gen_dest_fpr_F
> target/sparc: Introduce gen_{load,store}_fpr_Q
> target/sparc: Inline FNEG, FABS
> target/sparc: Use i128 for FSQRTq
> target/sparc: Use i128 for FADDq, FSUBq, FMULq, FDIVq
> target/sparc: Use i128 for FqTOs, FqTOi
> target/sparc: Use i128 for FqTOd, FqTOx
> target/sparc: Use i128 for FCMPq, FCMPEq
> target/sparc: Use i128 for FsTOq, FiTOq
> target/sparc: Use i128 for FdTOq, FxTOq
> target/sparc: Use i128 for Fdmulq
> target/sparc: Remove qt0, qt1 temporaries
> target/sparc: Introduce cpu_get_fsr, cpu_put_fsr
> target/split: Split ver from env->fsr
> target/sparc: Clear cexc and ftt in do_check_ieee_exceptions
> target/sparc: Merge check_ieee_exceptions with FPop helpers
> target/sparc: Split cexc and ftt from env->fsr
> target/sparc: Remove cpu_fsr
> target/sparc: Split fcc out of env->fsr
> target/sparc: Remove FSR_FTT_NMASK, FSR_FTT_CEXC_NMASK
>
> target/sparc/cpu.h | 39 +-
> target/sparc/helper.h | 116 ++----
> linux-user/sparc/cpu_loop.c | 2 +-
> linux-user/sparc/signal.c | 14 +-
> target/sparc/cpu.c | 32 +-
> target/sparc/fop_helper.c | 510 +++++++++++++----------
> target/sparc/gdbstub.c | 8 +-
> target/sparc/ldst_helper.c | 3 -
> target/sparc/machine.c | 38 +-
> target/sparc/translate.c | 799 ++++++++++++------------------------
> 10 files changed, 680 insertions(+), 881 deletions(-)
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 00/22] target/sparc: floating-point cleanup
2024-01-28 6:49 ` [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
@ 2024-01-29 21:50 ` Mark Cave-Ayland
2024-01-31 21:49 ` Mark Cave-Ayland
1 sibling, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2024-01-29 21:50 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 28/01/2024 06:49, Richard Henderson wrote:
> On 11/4/23 03:38, Richard Henderson wrote:
>> Major changes:
>>
>> (1) Get rid of the env->qt[01] temporaries and use TCGv_i128 for float128.
>> (2) Perform ieee exception check within the helpers, before any writeback
>> to the floating point registers.
>> (3) Split env->fsr into pieces to simplify update, especially compares.
>>
>>
>> r~
>>
>>
>> Based-on: 20231101041132.174501-1-richard.henderson@linaro.org
>> ("[PATCH v2 00/21] target/sparc: Cleanup condition codes etc")
>
> Ping.
>
> Prerequisites are upstream, and it rebases cleanly on master.
> For reference,
>
> https://gitlab.com/rth7680/qemu/-/commits/tgt-sparc-fp
>
> r~
Oops looks like I forgot about this series. I'm not sure I have any images that
explicitly test floating point operations, but I can at least run it through my
OpenBIOS test images and check for regressions over the next couple of days.
>> Richard Henderson (22):
>> target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for ASI_M_BCOPY
>> target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for ASI_M_BFILL
>> target/sparc: Remove gen_dest_fpr_F
>> target/sparc: Introduce gen_{load,store}_fpr_Q
>> target/sparc: Inline FNEG, FABS
>> target/sparc: Use i128 for FSQRTq
>> target/sparc: Use i128 for FADDq, FSUBq, FMULq, FDIVq
>> target/sparc: Use i128 for FqTOs, FqTOi
>> target/sparc: Use i128 for FqTOd, FqTOx
>> target/sparc: Use i128 for FCMPq, FCMPEq
>> target/sparc: Use i128 for FsTOq, FiTOq
>> target/sparc: Use i128 for FdTOq, FxTOq
>> target/sparc: Use i128 for Fdmulq
>> target/sparc: Remove qt0, qt1 temporaries
>> target/sparc: Introduce cpu_get_fsr, cpu_put_fsr
>> target/split: Split ver from env->fsr
>> target/sparc: Clear cexc and ftt in do_check_ieee_exceptions
>> target/sparc: Merge check_ieee_exceptions with FPop helpers
>> target/sparc: Split cexc and ftt from env->fsr
>> target/sparc: Remove cpu_fsr
>> target/sparc: Split fcc out of env->fsr
>> target/sparc: Remove FSR_FTT_NMASK, FSR_FTT_CEXC_NMASK
>>
>> target/sparc/cpu.h | 39 +-
>> target/sparc/helper.h | 116 ++----
>> linux-user/sparc/cpu_loop.c | 2 +-
>> linux-user/sparc/signal.c | 14 +-
>> target/sparc/cpu.c | 32 +-
>> target/sparc/fop_helper.c | 510 +++++++++++++----------
>> target/sparc/gdbstub.c | 8 +-
>> target/sparc/ldst_helper.c | 3 -
>> target/sparc/machine.c | 38 +-
>> target/sparc/translate.c | 799 ++++++++++++------------------------
>> 10 files changed, 680 insertions(+), 881 deletions(-)
ATB,
Mark.
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 03/22] target/sparc: Remove gen_dest_fpr_F
2023-11-03 17:38 ` [PATCH 03/22] target/sparc: Remove gen_dest_fpr_F Richard Henderson
@ 2024-01-30 7:54 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-01-30 7:54 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: mark.cave-ayland
On 3/11/23 18:38, Richard Henderson wrote:
> Replace with tcg_temp_new_i32.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/sparc/translate.c | 17 ++++++-----------
> 1 file changed, 6 insertions(+), 11 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 04/22] target/sparc: Introduce gen_{load,store}_fpr_Q
2023-11-03 17:38 ` [PATCH 04/22] target/sparc: Introduce gen_{load,store}_fpr_Q Richard Henderson
@ 2024-01-30 7:56 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-01-30 7:56 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: mark.cave-ayland
On 3/11/23 18:38, Richard Henderson wrote:
> Use them for trans_FMOVq.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/sparc/translate.c | 25 +++++++++++++++++++------
> 1 file changed, 19 insertions(+), 6 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 05/22] target/sparc: Inline FNEG, FABS
2023-11-03 17:38 ` [PATCH 05/22] target/sparc: Inline FNEG, FABS Richard Henderson
@ 2024-01-30 8:04 ` Philippe Mathieu-Daudé
2024-01-30 8:40 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-01-30 8:04 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: mark.cave-ayland
On 3/11/23 18:38, Richard Henderson wrote:
> These are simple bit manipulation insns.
> Begin using i128 for float128.
> Implement FMOVq with do_qq.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/sparc/helper.h | 6 ----
> target/sparc/fop_helper.c | 34 ---------------------
> target/sparc/translate.c | 62 +++++++++++++++++++--------------------
> 3 files changed, 30 insertions(+), 72 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 15/22] target/sparc: Introduce cpu_get_fsr, cpu_put_fsr
2023-11-03 17:38 ` [PATCH 15/22] target/sparc: Introduce cpu_get_fsr, cpu_put_fsr Richard Henderson
@ 2024-01-30 8:10 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-01-30 8:10 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: mark.cave-ayland
On 3/11/23 18:38, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/sparc/cpu.h | 4 +++-
> target/sparc/helper.h | 1 +
> linux-user/sparc/cpu_loop.c | 2 +-
> linux-user/sparc/signal.c | 14 +++++++++-----
> target/sparc/cpu.c | 5 +++--
> target/sparc/fop_helper.c | 21 ++++++++++++++++++--
> target/sparc/gdbstub.c | 8 ++++----
> target/sparc/machine.c | 38 +++++++++++++++++++++++++++++++++++--
> target/sparc/translate.c | 7 ++++++-
> 9 files changed, 82 insertions(+), 18 deletions(-)
> diff --git a/target/sparc/machine.c b/target/sparc/machine.c
> index 44dfc07014..e46f15adb8 100644
> --- a/target/sparc/machine.c
> +++ b/target/sparc/machine.c
> @@ -83,6 +83,34 @@ static const VMStateInfo vmstate_psr = {
> .put = put_psr,
> };
>
> +static int get_fsr(QEMUFile *f, void *opaque, size_t size,
> + const VMStateField *field)
> +{
> + SPARCCPU *cpu = opaque;
> + CPUSPARCState *env = &cpu->env;
> + target_ulong val = qemu_get_betl(f);
> +
> + cpu_put_fsr(env, val);
Preferably directly using cpu_env(), otherwise:
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> + return 0;
> +}
> +
> +static int put_fsr(QEMUFile *f, void *opaque, size_t size,
> + const VMStateField *field, JSONWriter *vmdesc)
> +{
> + SPARCCPU *cpu = opaque;
> + CPUSPARCState *env = &cpu->env;
> + target_ulong val = cpu_get_fsr(env);
(Ditto)
> +
> + qemu_put_betl(f, val);
> + return 0;
> +}
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 16/22] target/split: Split ver from env->fsr
2023-11-03 17:38 ` [PATCH 16/22] target/split: Split ver from env->fsr Richard Henderson
@ 2024-01-30 8:11 ` Philippe Mathieu-Daudé
2024-01-30 12:56 ` BALATON Zoltan
0 siblings, 1 reply; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-01-30 8:11 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: mark.cave-ayland
On 3/11/23 18:38, Richard Henderson wrote:
> This field is read-only. It is easier to store it separately
> and merge it only upon read.
>
> While we're at it, use FSR_VER_SHIFT to initialize fpu_version.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/sparc/cpu.h | 3 +++
> target/sparc/cpu.c | 27 +++++++++++++--------------
> target/sparc/fop_helper.c | 9 +++++++--
> 3 files changed, 23 insertions(+), 16 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 05/22] target/sparc: Inline FNEG, FABS
2023-11-03 17:38 ` [PATCH 05/22] target/sparc: Inline FNEG, FABS Richard Henderson
2024-01-30 8:04 ` Philippe Mathieu-Daudé
@ 2024-01-30 8:40 ` Philippe Mathieu-Daudé
2024-02-02 4:32 ` Richard Henderson
1 sibling, 1 reply; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-01-30 8:40 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: mark.cave-ayland
Hi Richard,
On 3/11/23 18:38, Richard Henderson wrote:
> These are simple bit manipulation insns.
> Begin using i128 for float128.
> Implement FMOVq with do_qq.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/sparc/helper.h | 6 ----
> target/sparc/fop_helper.c | 34 ---------------------
> target/sparc/translate.c | 62 +++++++++++++++++++--------------------
> 3 files changed, 30 insertions(+), 72 deletions(-)
> @@ -1239,13 +1235,13 @@ static void gen_op_fmovs(TCGv_i32 dst, TCGv_i32 src)
> static void gen_op_fnegs(TCGv_i32 dst, TCGv_i32 src)
> {
> gen_op_clear_ieee_excp_and_FTT();
> - gen_helper_fnegs(dst, src);
> + tcg_gen_xori_i32(dst, src, 1u << 31);
> }
>
> static void gen_op_fabss(TCGv_i32 dst, TCGv_i32 src)
> {
> gen_op_clear_ieee_excp_and_FTT();
> - gen_helper_fabss(dst, src);
> + tcg_gen_andi_i32(dst, src, ~(1u << 31));
> }
>
> static void gen_op_fmovd(TCGv_i64 dst, TCGv_i64 src)
> @@ -1257,13 +1253,33 @@ static void gen_op_fmovd(TCGv_i64 dst, TCGv_i64 src)
> static void gen_op_fnegd(TCGv_i64 dst, TCGv_i64 src)
> {
> gen_op_clear_ieee_excp_and_FTT();
> - gen_helper_fnegd(dst, src);
> + tcg_gen_xori_i64(dst, src, 1ull << 63);
> }
>
> static void gen_op_fabsd(TCGv_i64 dst, TCGv_i64 src)
> {
> gen_op_clear_ieee_excp_and_FTT();
> - gen_helper_fabsd(dst, src);
> + tcg_gen_andi_i64(dst, src, ~(1ull << 63));
> +}
> +
> +static void gen_op_fnegq(TCGv_i128 dst, TCGv_i128 src)
> +{
> + TCGv_i64 l = tcg_temp_new_i64();
> + TCGv_i64 h = tcg_temp_new_i64();
> +
> + tcg_gen_extr_i128_i64(l, h, src);
> + tcg_gen_xori_i64(h, h, 1ull << 63);
> + tcg_gen_concat_i64_i128(dst, l, h);
> +}
> +
> +static void gen_op_fabsq(TCGv_i128 dst, TCGv_i128 src)
> +{
> + TCGv_i64 l = tcg_temp_new_i64();
> + TCGv_i64 h = tcg_temp_new_i64();
> +
> + tcg_gen_extr_i128_i64(l, h, src);
> + tcg_gen_andi_i64(h, h, ~(1ull << 63));
> + tcg_gen_concat_i64_i128(dst, l, h);
> }
Why not extract these as generic TCG FPU helpers?
$ git grep -wE 'float...?_(chs|abs)' target/
target/arm/tcg/helper-a64.c:214: a = float16_chs(a);
target/arm/tcg/helper-a64.c:229: a = float32_chs(a);
target/arm/tcg/helper-a64.c:244: a = float64_chs(a);
target/arm/tcg/helper-a64.c:259: a = float16_chs(a);
target/arm/tcg/helper-a64.c:274: a = float32_chs(a);
target/arm/tcg/helper-a64.c:289: a = float64_chs(a);
target/arm/tcg/helper-a64.c:632: float16 f0 = float16_abs(a);
target/arm/tcg/helper-a64.c:633: float16 f1 = float16_abs(b);
target/arm/tcg/helper-a64.c:642: float16 f0 = float16_abs(a);
target/arm/tcg/helper-a64.c:643: float16 f1 = float16_abs(b);
target/arm/tcg/mve_helper.c:2840: return float16_abs(float16_sub(a,
b, s));
target/arm/tcg/mve_helper.c:2845: return float32_abs(float32_sub(a,
b, s));
target/arm/tcg/mve_helper.c:2854: return
float16_maxnum(float16_abs(a), float16_abs(b), s);
target/arm/tcg/mve_helper.c:2859: return
float32_maxnum(float32_abs(a), float32_abs(b), s);
target/arm/tcg/mve_helper.c:2864: return
float16_minnum(float16_abs(a), float16_abs(b), s);
target/arm/tcg/mve_helper.c:2869: return
float32_minnum(float32_abs(a), float32_abs(b), s);
target/arm/tcg/neon_helper.c:1513: float32 f0 =
float32_abs(make_float32(a));
target/arm/tcg/neon_helper.c:1514: float32 f1 =
float32_abs(make_float32(b));
target/arm/tcg/neon_helper.c:1521: float32 f0 =
float32_abs(make_float32(a));
target/arm/tcg/neon_helper.c:1522: float32 f1 =
float32_abs(make_float32(b));
target/arm/tcg/neon_helper.c:1529: float64 f0 =
float64_abs(make_float64(a));
target/arm/tcg/neon_helper.c:1530: float64 f1 =
float64_abs(make_float64(b));
target/arm/tcg/neon_helper.c:1537: float64 f0 =
float64_abs(make_float64(a));
target/arm/tcg/neon_helper.c:1538: float64 f1 =
float64_abs(make_float64(b));
target/arm/tcg/sve_helper.c:4227:DO_REDUCE(sve_fmaxv_h, float16, H1_2,
max, float16_chs(float16_infinity))
target/arm/tcg/sve_helper.c:4228:DO_REDUCE(sve_fmaxv_s, float32, H1_4,
max, float32_chs(float32_infinity))
target/arm/tcg/sve_helper.c:4229:DO_REDUCE(sve_fmaxv_d, float64, H1_8,
max, float64_chs(float64_infinity))
target/arm/tcg/sve_helper.c:4345: return float16_abs(float16_sub(a,
b, s));
target/arm/tcg/sve_helper.c:4350: return float32_abs(float32_sub(a,
b, s));
target/arm/tcg/sve_helper.c:4355: return float64_abs(float64_sub(a,
b, s));
target/arm/tcg/sve_helper.c:4997: mm = float16_abs(mm);
target/arm/tcg/sve_helper.c:5019: mm = float32_abs(mm);
target/arm/tcg/sve_helper.c:5045: mm = float64_abs(mm);
target/arm/tcg/sve_helper.c:5062: float16 neg_real =
float16_chs(neg_imag);
target/arm/tcg/sve_helper.c:5094: float32 neg_real =
float32_chs(neg_imag);
target/arm/tcg/sve_helper.c:5126: float64 neg_real =
float64_chs(neg_imag);
target/arm/tcg/vec_helper.c:996: return -float16_le(float16_abs(op2),
float16_abs(op1), stat);
target/arm/tcg/vec_helper.c:1001: return
-float32_le(float32_abs(op2), float32_abs(op1), stat);
target/arm/tcg/vec_helper.c:1006: return
-float16_lt(float16_abs(op2), float16_abs(op1), stat);
target/arm/tcg/vec_helper.c:1011: return
-float32_lt(float32_abs(op2), float32_abs(op1), stat);
target/arm/tcg/vec_helper.c:1124: return float16_abs(float16_sub(op1,
op2, stat));
target/arm/tcg/vec_helper.c:1129: return float32_abs(float32_sub(op1,
op2, stat));
target/arm/tcg/vec_helper.c:1304: return
float16_muladd(float16_chs(op1), op2, dest, 0, stat);
target/arm/tcg/vec_helper.c:1310: return
float32_muladd(float32_chs(op1), op2, dest, 0, stat);
target/arm/vfp_helper.c:286: return float16_chs(a);
target/arm/vfp_helper.c:291: return float32_chs(a);
target/arm/vfp_helper.c:296: return float64_chs(a);
target/arm/vfp_helper.c:301: return float16_abs(a);
target/arm/vfp_helper.c:306: return float32_abs(a);
target/arm/vfp_helper.c:311: return float64_abs(a);
target/arm/vfp_helper.c:688: } else if (float16_abs(f16) < (1 << 8)) {
target/arm/vfp_helper.c:738: } else if (float32_abs(f32) < (1ULL <<
21)) {
target/arm/vfp_helper.c:1133: if (value == float64_chs(float64_zero)) {
target/i386/tcg/fpu_helper.c:591: ST0 = floatx80_chs(ST0);
target/i386/tcg/fpu_helper.c:596: ST0 = floatx80_abs(ST0);
target/i386/tcg/fpu_helper.c:781: tmp = floatx80_chs(tmp);
target/i386/tcg/fpu_helper.c:1739: ST0 =
floatx80_div(floatx80_chs(floatx80_one), floatx80_zero,
target/i386/tcg/fpu_helper.c:2104: ST1 = floatx80_chs(ST1);
target/i386/tcg/fpu_helper.c:2119: ST1 = floatx80_chs(ST0);
target/i386/tcg/fpu_helper.c:2135: ST1 = floatx80_chs(ST1);
target/i386/tcg/fpu_helper.c:2140: ST1 =
floatx80_chs(floatx80_zero);
target/i386/tcg/fpu_helper.c:2276:
floatx80_chs(floatx80_zero) :
target/i386/tcg/fpu_helper.c:2285:
floatx80_chs(floatx80_infinity) :
target/m68k/fpu_helper.c:212: res->d =
floatx80_round(floatx80_abs(val->d), &env->fp_status);
target/m68k/fpu_helper.c:218: res->d =
floatx80_round(floatx80_abs(val->d), &env->fp_status);
target/m68k/fpu_helper.c:225: res->d =
floatx80_round(floatx80_abs(val->d), &env->fp_status);
target/m68k/fpu_helper.c:231: res->d =
floatx80_round(floatx80_chs(val->d), &env->fp_status);
target/m68k/fpu_helper.c:237: res->d =
floatx80_round(floatx80_chs(val->d), &env->fp_status);
target/m68k/fpu_helper.c:244: res->d =
floatx80_round(floatx80_chs(val->d), &env->fp_status);
target/m68k/fpu_helper.c:557: quotient =
floatx80_to_int32(floatx80_abs(fp_quot.d), &env->fp_status);
target/m68k/softfloat.c:2714: fp0 = floatx80_abs(a); /* Y =
|X| */
target/m68k/softfloat.c:2734: fp0 = floatx80_abs(a); /* Y = |X| */
target/mips/tcg/fpu_helper.c:977: return float64_abs(fdt0);
target/mips/tcg/fpu_helper.c:982: return float32_abs(fst0);
target/mips/tcg/fpu_helper.c:990: wt0 = float32_abs(fdt0 & 0XFFFFFFFF);
target/mips/tcg/fpu_helper.c:991: wth0 = float32_abs(fdt0 >> 32);
target/mips/tcg/fpu_helper.c:997: return float64_chs(fdt0);
target/mips/tcg/fpu_helper.c:1002: return float32_chs(fst0);
target/mips/tcg/fpu_helper.c:1010: wt0 = float32_chs(fdt0 & 0XFFFFFFFF);
target/mips/tcg/fpu_helper.c:1011: wth0 = float32_chs(fdt0 >> 32);
target/mips/tcg/fpu_helper.c:1365: fdt2 =
float64_chs(float64_sub(fdt2, float64_one,
target/mips/tcg/fpu_helper.c:1374: fst2 =
float32_chs(float32_sub(fst2, float32_one,
target/mips/tcg/fpu_helper.c:1389: fstl2 =
float32_chs(float32_sub(fstl2, float32_one,
target/mips/tcg/fpu_helper.c:1391: fsth2 =
float32_chs(float32_sub(fsth2, float32_one,
target/mips/tcg/fpu_helper.c:1401: fdt2 =
float64_chs(float64_div(fdt2, FLOAT_TWO64,
target/mips/tcg/fpu_helper.c:1411: fst2 =
float32_chs(float32_div(fst2, FLOAT_TWO32,
target/mips/tcg/fpu_helper.c:1428: fstl2 =
float32_chs(float32_div(fstl2, FLOAT_TWO32,
target/mips/tcg/fpu_helper.c:1430: fsth2 =
float32_chs(float32_div(fsth2, FLOAT_TWO32,
target/mips/tcg/fpu_helper.c:1633: fst0 = float64_chs(fst0);
target/mips/tcg/fpu_helper.c:1644: fst0 = float32_chs(fst0);
target/mips/tcg/fpu_helper.c:1662: fstl0 = float32_chs(fstl0);
target/mips/tcg/fpu_helper.c:1665: fsth0 = float32_chs(fsth0);
target/mips/tcg/fpu_helper.c:1676: fst0 = float64_chs(fst0);
target/mips/tcg/fpu_helper.c:1687: fst0 = float32_chs(fst0);
target/mips/tcg/fpu_helper.c:1705: fstl0 = float32_chs(fstl0);
target/mips/tcg/fpu_helper.c:1708: fsth0 = float32_chs(fsth0);
target/mips/tcg/fpu_helper.c:1781: fdt0 = float64_abs(fdt0);
\
target/mips/tcg/fpu_helper.c:1782: fdt1 = float64_abs(fdt1);
\
target/mips/tcg/fpu_helper.c:1860: fst0 = float32_abs(fst0);
\
target/mips/tcg/fpu_helper.c:1861: fst1 = float32_abs(fst1);
\
target/mips/tcg/fpu_helper.c:1950: fst0 = float32_abs(fdt0 &
0XFFFFFFFF); \
target/mips/tcg/fpu_helper.c:1951: fsth0 = float32_abs(fdt0 >> 32);
\
target/mips/tcg/fpu_helper.c:1952: fst1 = float32_abs(fdt1 &
0XFFFFFFFF); \
target/mips/tcg/fpu_helper.c:1953: fsth1 = float32_abs(fdt1 >> 32);
\
target/ppc/fpu_helper.c:44: return float32_chs(a);
target/ppc/int_helper.c:694: float32 bneg =
float32_chs(b->f32[i]);
target/s390x/tcg/vec_fpu_helper.c:922: a = float32_abs(a);
target/s390x/tcg/vec_fpu_helper.c:923: b = float32_abs(b);
target/s390x/tcg/vec_fpu_helper.c:984: a = float64_abs(a);
target/s390x/tcg/vec_fpu_helper.c:985: b = float64_abs(b);
target/s390x/tcg/vec_fpu_helper.c:1042: a = float128_abs(a);
target/s390x/tcg/vec_fpu_helper.c:1043: b = float128_abs(b);
target/sparc/fop_helper.c:119: return float32_chs(src);
target/sparc/fop_helper.c:125: return float64_chs(src);
target/sparc/fop_helper.c:130: QT0 = float128_chs(QT1);
target/sparc/fop_helper.c:234: return float32_abs(src);
target/sparc/fop_helper.c:240: return float64_abs(src);
target/sparc/fop_helper.c:245: QT0 = float128_abs(QT1);
target/xtensa/fpu_helper.c:126: return float64_abs(v);
target/xtensa/fpu_helper.c:131: return float32_abs(v);
target/xtensa/fpu_helper.c:136: return float64_chs(v);
target/xtensa/fpu_helper.c:141: return float32_chs(v);
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 16/22] target/split: Split ver from env->fsr
2024-01-30 8:11 ` Philippe Mathieu-Daudé
@ 2024-01-30 12:56 ` BALATON Zoltan
0 siblings, 0 replies; 35+ messages in thread
From: BALATON Zoltan @ 2024-01-30 12:56 UTC (permalink / raw)
To: Richard Henderson
Cc: Philippe Mathieu-Daudé, qemu-devel, mark.cave-ayland
[-- Attachment #1: Type: text/plain, Size: 693 bytes --]
On Tue, 30 Jan 2024, Philippe Mathieu-Daudé wrote:
> On 3/11/23 18:38, Richard Henderson wrote:
>> This field is read-only. It is easier to store it separately
>> and merge it only upon read.
>>
>> While we're at it, use FSR_VER_SHIFT to initialize fpu_version.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> target/sparc/cpu.h | 3 +++
>> target/sparc/cpu.c | 27 +++++++++++++--------------
>> target/sparc/fop_helper.c | 9 +++++++--
>> 3 files changed, 23 insertions(+), 16 deletions(-)
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Typo in subject: should be target/sparc not target/split.
Regards,
BALATON Zoltan
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 00/22] target/sparc: floating-point cleanup
2024-01-28 6:49 ` [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
2024-01-29 21:50 ` Mark Cave-Ayland
@ 2024-01-31 21:49 ` Mark Cave-Ayland
2024-02-02 5:36 ` Richard Henderson
1 sibling, 1 reply; 35+ messages in thread
From: Mark Cave-Ayland @ 2024-01-31 21:49 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 28/01/2024 06:49, Richard Henderson wrote:
> On 11/4/23 03:38, Richard Henderson wrote:
>> Major changes:
>>
>> (1) Get rid of the env->qt[01] temporaries and use TCGv_i128 for float128.
>> (2) Perform ieee exception check within the helpers, before any writeback
>> to the floating point registers.
>> (3) Split env->fsr into pieces to simplify update, especially compares.
>>
>>
>> r~
>>
>>
>> Based-on: 20231101041132.174501-1-richard.henderson@linaro.org
>> ("[PATCH v2 00/21] target/sparc: Cleanup condition codes etc")
>
> Ping.
>
> Prerequisites are upstream, and it rebases cleanly on master.
> For reference,
>
> https://gitlab.com/rth7680/qemu/-/commits/tgt-sparc-fp
>
>
> r~
I've tested the above branch on my SPARC32 and SPARC64 images, and whilst I don't
think they particularly exercise FP instructions, I don't see any regressions so:
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
I'm happy for you to take this via tcg-next if that's easiest for you.
>> Richard Henderson (22):
>> target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for ASI_M_BCOPY
>> target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for ASI_M_BFILL
>> target/sparc: Remove gen_dest_fpr_F
>> target/sparc: Introduce gen_{load,store}_fpr_Q
>> target/sparc: Inline FNEG, FABS
>> target/sparc: Use i128 for FSQRTq
>> target/sparc: Use i128 for FADDq, FSUBq, FMULq, FDIVq
>> target/sparc: Use i128 for FqTOs, FqTOi
>> target/sparc: Use i128 for FqTOd, FqTOx
>> target/sparc: Use i128 for FCMPq, FCMPEq
>> target/sparc: Use i128 for FsTOq, FiTOq
>> target/sparc: Use i128 for FdTOq, FxTOq
>> target/sparc: Use i128 for Fdmulq
>> target/sparc: Remove qt0, qt1 temporaries
>> target/sparc: Introduce cpu_get_fsr, cpu_put_fsr
>> target/split: Split ver from env->fsr
>> target/sparc: Clear cexc and ftt in do_check_ieee_exceptions
>> target/sparc: Merge check_ieee_exceptions with FPop helpers
>> target/sparc: Split cexc and ftt from env->fsr
>> target/sparc: Remove cpu_fsr
>> target/sparc: Split fcc out of env->fsr
>> target/sparc: Remove FSR_FTT_NMASK, FSR_FTT_CEXC_NMASK
>>
>> target/sparc/cpu.h | 39 +-
>> target/sparc/helper.h | 116 ++----
>> linux-user/sparc/cpu_loop.c | 2 +-
>> linux-user/sparc/signal.c | 14 +-
>> target/sparc/cpu.c | 32 +-
>> target/sparc/fop_helper.c | 510 +++++++++++++----------
>> target/sparc/gdbstub.c | 8 +-
>> target/sparc/ldst_helper.c | 3 -
>> target/sparc/machine.c | 38 +-
>> target/sparc/translate.c | 799 ++++++++++++------------------------
>> 10 files changed, 680 insertions(+), 881 deletions(-)
ATB,
Mark.
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 05/22] target/sparc: Inline FNEG, FABS
2024-01-30 8:40 ` Philippe Mathieu-Daudé
@ 2024-02-02 4:32 ` Richard Henderson
0 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2024-02-02 4:32 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel; +Cc: mark.cave-ayland
On 1/30/24 18:40, Philippe Mathieu-Daudé wrote:
> Hi Richard,
>
> On 3/11/23 18:38, Richard Henderson wrote:
>> These are simple bit manipulation insns.
>> Begin using i128 for float128.
>> Implement FMOVq with do_qq.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> target/sparc/helper.h | 6 ----
>> target/sparc/fop_helper.c | 34 ---------------------
>> target/sparc/translate.c | 62 +++++++++++++++++++--------------------
>> 3 files changed, 30 insertions(+), 72 deletions(-)
>
>
>> @@ -1239,13 +1235,13 @@ static void gen_op_fmovs(TCGv_i32 dst, TCGv_i32 src)
>> static void gen_op_fnegs(TCGv_i32 dst, TCGv_i32 src)
>> {
>> gen_op_clear_ieee_excp_and_FTT();
>> - gen_helper_fnegs(dst, src);
>> + tcg_gen_xori_i32(dst, src, 1u << 31);
>> }
>> static void gen_op_fabss(TCGv_i32 dst, TCGv_i32 src)
>> {
>> gen_op_clear_ieee_excp_and_FTT();
>> - gen_helper_fabss(dst, src);
>> + tcg_gen_andi_i32(dst, src, ~(1u << 31));
>> }
>> static void gen_op_fmovd(TCGv_i64 dst, TCGv_i64 src)
>> @@ -1257,13 +1253,33 @@ static void gen_op_fmovd(TCGv_i64 dst, TCGv_i64 src)
>> static void gen_op_fnegd(TCGv_i64 dst, TCGv_i64 src)
>> {
>> gen_op_clear_ieee_excp_and_FTT();
>> - gen_helper_fnegd(dst, src);
>> + tcg_gen_xori_i64(dst, src, 1ull << 63);
>> }
>> static void gen_op_fabsd(TCGv_i64 dst, TCGv_i64 src)
>> {
>> gen_op_clear_ieee_excp_and_FTT();
>> - gen_helper_fabsd(dst, src);
>> + tcg_gen_andi_i64(dst, src, ~(1ull << 63));
>> +}
>> +
>> +static void gen_op_fnegq(TCGv_i128 dst, TCGv_i128 src)
>> +{
>> + TCGv_i64 l = tcg_temp_new_i64();
>> + TCGv_i64 h = tcg_temp_new_i64();
>> +
>> + tcg_gen_extr_i128_i64(l, h, src);
>> + tcg_gen_xori_i64(h, h, 1ull << 63);
>> + tcg_gen_concat_i64_i128(dst, l, h);
>> +}
>> +
>> +static void gen_op_fabsq(TCGv_i128 dst, TCGv_i128 src)
>> +{
>> + TCGv_i64 l = tcg_temp_new_i64();
>> + TCGv_i64 h = tcg_temp_new_i64();
>> +
>> + tcg_gen_extr_i128_i64(l, h, src);
>> + tcg_gen_andi_i64(h, h, ~(1ull << 63));
>> + tcg_gen_concat_i64_i128(dst, l, h);
>> }
>
> Why not extract these as generic TCG FPU helpers?
The representation of floating-point registers varies wildly between targets. Sparc would
be the only one to (a) have float128 and (b) represent them in TCGv_i128.
Even considering float32, is the representation TCGv_i32 or TCGv_i64?
Should the result be nan-boxed (riscv and loongarch)?
We already provide tcg_gen_xori_i{32,64}, so, really that's enough for any target.
> $ git grep -wE 'float...?_(chs|abs)' target/
> target/arm/tcg/helper-a64.c:214: a = float16_chs(a);
> target/arm/tcg/helper-a64.c:229: a = float32_chs(a);
> target/arm/tcg/helper-a64.c:244: a = float64_chs(a);
> target/arm/tcg/helper-a64.c:259: a = float16_chs(a);
> target/arm/tcg/helper-a64.c:274: a = float32_chs(a);
> target/arm/tcg/helper-a64.c:289: a = float64_chs(a);
> target/arm/tcg/helper-a64.c:632: float16 f0 = float16_abs(a);
> target/arm/tcg/helper-a64.c:633: float16 f1 = float16_abs(b);
> target/arm/tcg/helper-a64.c:642: float16 f0 = float16_abs(a);
> target/arm/tcg/helper-a64.c:643: float16 f1 = float16_abs(b);
> target/arm/tcg/mve_helper.c:2840: return float16_abs(float16_sub(a, b, s));
> target/arm/tcg/mve_helper.c:2845: return float32_abs(float32_sub(a, b, s));
> target/arm/tcg/mve_helper.c:2854: return float16_maxnum(float16_abs(a), float16_abs(b),
> s);
> target/arm/tcg/mve_helper.c:2859: return float32_maxnum(float32_abs(a), float32_abs(b),
> s);
> target/arm/tcg/mve_helper.c:2864: return float16_minnum(float16_abs(a), float16_abs(b),
> s);
> target/arm/tcg/mve_helper.c:2869: return float32_minnum(float32_abs(a), float32_abs(b),
> s);
> target/arm/tcg/neon_helper.c:1513: float32 f0 = float32_abs(make_float32(a));
> target/arm/tcg/neon_helper.c:1514: float32 f1 = float32_abs(make_float32(b));
> target/arm/tcg/neon_helper.c:1521: float32 f0 = float32_abs(make_float32(a));
> target/arm/tcg/neon_helper.c:1522: float32 f1 = float32_abs(make_float32(b));
> target/arm/tcg/neon_helper.c:1529: float64 f0 = float64_abs(make_float64(a));
> target/arm/tcg/neon_helper.c:1530: float64 f1 = float64_abs(make_float64(b));
> target/arm/tcg/neon_helper.c:1537: float64 f0 = float64_abs(make_float64(a));
> target/arm/tcg/neon_helper.c:1538: float64 f1 = float64_abs(make_float64(b));
> target/arm/tcg/sve_helper.c:4227:DO_REDUCE(sve_fmaxv_h, float16, H1_2, max,
> float16_chs(float16_infinity))
> target/arm/tcg/sve_helper.c:4228:DO_REDUCE(sve_fmaxv_s, float32, H1_4, max,
> float32_chs(float32_infinity))
> target/arm/tcg/sve_helper.c:4229:DO_REDUCE(sve_fmaxv_d, float64, H1_8, max,
> float64_chs(float64_infinity))
> target/arm/tcg/sve_helper.c:4345: return float16_abs(float16_sub(a, b, s));
> target/arm/tcg/sve_helper.c:4350: return float32_abs(float32_sub(a, b, s));
> target/arm/tcg/sve_helper.c:4355: return float64_abs(float64_sub(a, b, s));
> target/arm/tcg/sve_helper.c:4997: mm = float16_abs(mm);
> target/arm/tcg/sve_helper.c:5019: mm = float32_abs(mm);
> target/arm/tcg/sve_helper.c:5045: mm = float64_abs(mm);
> target/arm/tcg/sve_helper.c:5062: float16 neg_real = float16_chs(neg_imag);
> target/arm/tcg/sve_helper.c:5094: float32 neg_real = float32_chs(neg_imag);
> target/arm/tcg/sve_helper.c:5126: float64 neg_real = float64_chs(neg_imag);
> target/arm/tcg/vec_helper.c:996: return -float16_le(float16_abs(op2), float16_abs(op1),
> stat);
> target/arm/tcg/vec_helper.c:1001: return -float32_le(float32_abs(op2),
> float32_abs(op1), stat);
> target/arm/tcg/vec_helper.c:1006: return -float16_lt(float16_abs(op2),
> float16_abs(op1), stat);
> target/arm/tcg/vec_helper.c:1011: return -float32_lt(float32_abs(op2),
> float32_abs(op1), stat);
> target/arm/tcg/vec_helper.c:1124: return float16_abs(float16_sub(op1, op2, stat));
> target/arm/tcg/vec_helper.c:1129: return float32_abs(float32_sub(op1, op2, stat));
> target/arm/tcg/vec_helper.c:1304: return float16_muladd(float16_chs(op1), op2, dest, 0,
> stat);
> target/arm/tcg/vec_helper.c:1310: return float32_muladd(float32_chs(op1), op2, dest, 0,
> stat);
> target/arm/vfp_helper.c:286: return float16_chs(a);
> target/arm/vfp_helper.c:291: return float32_chs(a);
> target/arm/vfp_helper.c:296: return float64_chs(a);
> target/arm/vfp_helper.c:301: return float16_abs(a);
> target/arm/vfp_helper.c:306: return float32_abs(a);
> target/arm/vfp_helper.c:311: return float64_abs(a);
> target/arm/vfp_helper.c:688: } else if (float16_abs(f16) < (1 << 8)) {
> target/arm/vfp_helper.c:738: } else if (float32_abs(f32) < (1ULL << 21)) {
> target/arm/vfp_helper.c:1133: if (value == float64_chs(float64_zero)) {
> target/i386/tcg/fpu_helper.c:591: ST0 = floatx80_chs(ST0);
> target/i386/tcg/fpu_helper.c:596: ST0 = floatx80_abs(ST0);
> target/i386/tcg/fpu_helper.c:781: tmp = floatx80_chs(tmp);
> target/i386/tcg/fpu_helper.c:1739: ST0 = floatx80_div(floatx80_chs(floatx80_one),
> floatx80_zero,
> target/i386/tcg/fpu_helper.c:2104: ST1 = floatx80_chs(ST1);
> target/i386/tcg/fpu_helper.c:2119: ST1 = floatx80_chs(ST0);
> target/i386/tcg/fpu_helper.c:2135: ST1 = floatx80_chs(ST1);
> target/i386/tcg/fpu_helper.c:2140: ST1 = floatx80_chs(floatx80_zero);
> target/i386/tcg/fpu_helper.c:2276: floatx80_chs(floatx80_zero) :
> target/i386/tcg/fpu_helper.c:2285: floatx80_chs(floatx80_infinity) :
> target/m68k/fpu_helper.c:212: res->d = floatx80_round(floatx80_abs(val->d),
> &env->fp_status);
> target/m68k/fpu_helper.c:218: res->d = floatx80_round(floatx80_abs(val->d),
> &env->fp_status);
> target/m68k/fpu_helper.c:225: res->d = floatx80_round(floatx80_abs(val->d),
> &env->fp_status);
> target/m68k/fpu_helper.c:231: res->d = floatx80_round(floatx80_chs(val->d),
> &env->fp_status);
> target/m68k/fpu_helper.c:237: res->d = floatx80_round(floatx80_chs(val->d),
> &env->fp_status);
> target/m68k/fpu_helper.c:244: res->d = floatx80_round(floatx80_chs(val->d),
> &env->fp_status);
> target/m68k/fpu_helper.c:557: quotient = floatx80_to_int32(floatx80_abs(fp_quot.d),
> &env->fp_status);
> target/m68k/softfloat.c:2714: fp0 = floatx80_abs(a); /* Y = |X| */
> target/m68k/softfloat.c:2734: fp0 = floatx80_abs(a); /* Y = |X| */
> target/mips/tcg/fpu_helper.c:977: return float64_abs(fdt0);
> target/mips/tcg/fpu_helper.c:982: return float32_abs(fst0);
> target/mips/tcg/fpu_helper.c:990: wt0 = float32_abs(fdt0 & 0XFFFFFFFF);
> target/mips/tcg/fpu_helper.c:991: wth0 = float32_abs(fdt0 >> 32);
> target/mips/tcg/fpu_helper.c:997: return float64_chs(fdt0);
> target/mips/tcg/fpu_helper.c:1002: return float32_chs(fst0);
> target/mips/tcg/fpu_helper.c:1010: wt0 = float32_chs(fdt0 & 0XFFFFFFFF);
> target/mips/tcg/fpu_helper.c:1011: wth0 = float32_chs(fdt0 >> 32);
> target/mips/tcg/fpu_helper.c:1365: fdt2 = float64_chs(float64_sub(fdt2, float64_one,
> target/mips/tcg/fpu_helper.c:1374: fst2 = float32_chs(float32_sub(fst2, float32_one,
> target/mips/tcg/fpu_helper.c:1389: fstl2 = float32_chs(float32_sub(fstl2, float32_one,
> target/mips/tcg/fpu_helper.c:1391: fsth2 = float32_chs(float32_sub(fsth2, float32_one,
> target/mips/tcg/fpu_helper.c:1401: fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64,
> target/mips/tcg/fpu_helper.c:1411: fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
> target/mips/tcg/fpu_helper.c:1428: fstl2 = float32_chs(float32_div(fstl2, FLOAT_TWO32,
> target/mips/tcg/fpu_helper.c:1430: fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
> target/mips/tcg/fpu_helper.c:1633: fst0 = float64_chs(fst0);
> target/mips/tcg/fpu_helper.c:1644: fst0 = float32_chs(fst0);
> target/mips/tcg/fpu_helper.c:1662: fstl0 = float32_chs(fstl0);
> target/mips/tcg/fpu_helper.c:1665: fsth0 = float32_chs(fsth0);
> target/mips/tcg/fpu_helper.c:1676: fst0 = float64_chs(fst0);
> target/mips/tcg/fpu_helper.c:1687: fst0 = float32_chs(fst0);
> target/mips/tcg/fpu_helper.c:1705: fstl0 = float32_chs(fstl0);
> target/mips/tcg/fpu_helper.c:1708: fsth0 = float32_chs(fsth0);
> target/mips/tcg/fpu_helper.c:1781: fdt0 = float64_abs(fdt0); \
> target/mips/tcg/fpu_helper.c:1782: fdt1 = float64_abs(fdt1); \
> target/mips/tcg/fpu_helper.c:1860: fst0 = float32_abs(fst0); \
> target/mips/tcg/fpu_helper.c:1861: fst1 = float32_abs(fst1); \
> target/mips/tcg/fpu_helper.c:1950: fst0 = float32_abs(fdt0 &
> 0XFFFFFFFF); \
> target/mips/tcg/fpu_helper.c:1951: fsth0 = float32_abs(fdt0 >> 32);
> \
> target/mips/tcg/fpu_helper.c:1952: fst1 = float32_abs(fdt1 &
> 0XFFFFFFFF); \
> target/mips/tcg/fpu_helper.c:1953: fsth1 = float32_abs(fdt1 >> 32);
> \
> target/ppc/fpu_helper.c:44: return float32_chs(a);
> target/ppc/int_helper.c:694: float32 bneg = float32_chs(b->f32[i]);
> target/s390x/tcg/vec_fpu_helper.c:922: a = float32_abs(a);
> target/s390x/tcg/vec_fpu_helper.c:923: b = float32_abs(b);
> target/s390x/tcg/vec_fpu_helper.c:984: a = float64_abs(a);
> target/s390x/tcg/vec_fpu_helper.c:985: b = float64_abs(b);
> target/s390x/tcg/vec_fpu_helper.c:1042: a = float128_abs(a);
> target/s390x/tcg/vec_fpu_helper.c:1043: b = float128_abs(b);
> target/sparc/fop_helper.c:119: return float32_chs(src);
> target/sparc/fop_helper.c:125: return float64_chs(src);
> target/sparc/fop_helper.c:130: QT0 = float128_chs(QT1);
> target/sparc/fop_helper.c:234: return float32_abs(src);
> target/sparc/fop_helper.c:240: return float64_abs(src);
> target/sparc/fop_helper.c:245: QT0 = float128_abs(QT1);
> target/xtensa/fpu_helper.c:126: return float64_abs(v);
> target/xtensa/fpu_helper.c:131: return float32_abs(v);
> target/xtensa/fpu_helper.c:136: return float64_chs(v);
> target/xtensa/fpu_helper.c:141: return float32_chs(v);
With only a few exceptions, most of of these results are part of a larger out-of-line
operation.
r~
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 00/22] target/sparc: floating-point cleanup
2024-01-31 21:49 ` Mark Cave-Ayland
@ 2024-02-02 5:36 ` Richard Henderson
0 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2024-02-02 5:36 UTC (permalink / raw)
To: Mark Cave-Ayland, qemu-devel
On 2/1/24 07:49, Mark Cave-Ayland wrote:
> I'm happy for you to take this via tcg-next if that's easiest for you.
Yes, I can do that.
r~
^ permalink raw reply [flat|nested] 35+ messages in thread
end of thread, other threads:[~2024-02-02 5:37 UTC | newest]
Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-03 17:38 [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
2023-11-03 17:38 ` [PATCH 01/22] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for ASI_M_BCOPY Richard Henderson
2023-11-03 17:38 ` [PATCH 02/22] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for ASI_M_BFILL Richard Henderson
2023-11-03 17:38 ` [PATCH 03/22] target/sparc: Remove gen_dest_fpr_F Richard Henderson
2024-01-30 7:54 ` Philippe Mathieu-Daudé
2023-11-03 17:38 ` [PATCH 04/22] target/sparc: Introduce gen_{load,store}_fpr_Q Richard Henderson
2024-01-30 7:56 ` Philippe Mathieu-Daudé
2023-11-03 17:38 ` [PATCH 05/22] target/sparc: Inline FNEG, FABS Richard Henderson
2024-01-30 8:04 ` Philippe Mathieu-Daudé
2024-01-30 8:40 ` Philippe Mathieu-Daudé
2024-02-02 4:32 ` Richard Henderson
2023-11-03 17:38 ` [PATCH 06/22] target/sparc: Use i128 for FSQRTq Richard Henderson
2023-11-03 17:38 ` [PATCH 07/22] target/sparc: Use i128 for FADDq, FSUBq, FMULq, FDIVq Richard Henderson
2023-11-03 17:38 ` [PATCH 08/22] target/sparc: Use i128 for FqTOs, FqTOi Richard Henderson
2023-11-03 17:38 ` [PATCH 09/22] target/sparc: Use i128 for FqTOd, FqTOx Richard Henderson
2023-11-03 17:38 ` [PATCH 10/22] target/sparc: Use i128 for FCMPq, FCMPEq Richard Henderson
2023-11-03 17:38 ` [PATCH 11/22] target/sparc: Use i128 for FsTOq, FiTOq Richard Henderson
2023-11-03 17:38 ` [PATCH 12/22] target/sparc: Use i128 for FdTOq, FxTOq Richard Henderson
2023-11-03 17:38 ` [PATCH 13/22] target/sparc: Use i128 for Fdmulq Richard Henderson
2023-11-03 17:38 ` [PATCH 14/22] target/sparc: Remove qt0, qt1 temporaries Richard Henderson
2023-11-03 17:38 ` [PATCH 15/22] target/sparc: Introduce cpu_get_fsr, cpu_put_fsr Richard Henderson
2024-01-30 8:10 ` Philippe Mathieu-Daudé
2023-11-03 17:38 ` [PATCH 16/22] target/split: Split ver from env->fsr Richard Henderson
2024-01-30 8:11 ` Philippe Mathieu-Daudé
2024-01-30 12:56 ` BALATON Zoltan
2023-11-03 17:38 ` [PATCH 17/22] target/sparc: Clear cexc and ftt in do_check_ieee_exceptions Richard Henderson
2023-11-03 17:38 ` [PATCH 18/22] target/sparc: Merge check_ieee_exceptions with FPop helpers Richard Henderson
2023-11-03 17:38 ` [PATCH 19/22] target/sparc: Split cexc and ftt from env->fsr Richard Henderson
2023-11-03 17:38 ` [PATCH 20/22] target/sparc: Remove cpu_fsr Richard Henderson
2023-11-03 17:38 ` [PATCH 21/22] target/sparc: Split fcc out of env->fsr Richard Henderson
2023-11-03 17:38 ` [PATCH 22/22] target/sparc: Remove FSR_FTT_NMASK, FSR_FTT_CEXC_NMASK Richard Henderson
2024-01-28 6:49 ` [PATCH 00/22] target/sparc: floating-point cleanup Richard Henderson
2024-01-29 21:50 ` Mark Cave-Ayland
2024-01-31 21:49 ` Mark Cave-Ayland
2024-02-02 5:36 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).