aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-11-03 10:38:34 -0700
committerRichard Henderson <richard.henderson@linaro.org>2024-02-03 16:46:10 +1000
commit1ccd6e13ccc0913bd3750f47c697c3d7c31cd418 (patch)
tree208d0192302aa1529556baf95fb5be8842b65994 /target
parent41535ca6f4d708cf376d731930fd89f44c84c98a (diff)
downloadqemu-1ccd6e13ccc0913bd3750f47c697c3d7c31cd418.zip
qemu-1ccd6e13ccc0913bd3750f47c697c3d7c31cd418.tar.gz
qemu-1ccd6e13ccc0913bd3750f47c697c3d7c31cd418.tar.bz2
target/sparc: Introduce cpu_get_fsr, cpu_put_fsr
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Message-Id: <20231103173841.33651-16-richard.henderson@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/sparc/cpu.c5
-rw-r--r--target/sparc/cpu.h4
-rw-r--r--target/sparc/fop_helper.c21
-rw-r--r--target/sparc/gdbstub.c8
-rw-r--r--target/sparc/helper.h1
-rw-r--r--target/sparc/machine.c36
-rw-r--r--target/sparc/translate.c7
7 files changed, 70 insertions, 12 deletions
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index afa6272..1897ab2 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");
}
@@ -798,6 +798,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/cpu.h b/target/sparc/cpu.h
index 75c46e2..3cf8cc2 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -617,7 +617,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/fop_helper.c b/target/sparc/fop_helper.c
index 7353a61..70b3801 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 a1c8fdc..d1586b2 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/helper.h b/target/sparc/helper.h
index f7aeb31..cc8db50 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/target/sparc/machine.c b/target/sparc/machine.c
index 2b5686c..48e0cf2 100644
--- a/target/sparc/machine.c
+++ b/target/sparc/machine.c
@@ -83,6 +83,32 @@ 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;
+ target_ulong val = qemu_get_betl(f);
+
+ cpu_put_fsr(&cpu->env, val);
+ return 0;
+}
+
+static int put_fsr(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field, JSONWriter *vmdesc)
+{
+ SPARCCPU *cpu = opaque;
+ target_ulong val = cpu_get_fsr(&cpu->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 +183,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 +190,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 d12de5a..da4f167 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);
}