* [PATCH v2 00/90] target/sparc: Convert to decodetree
@ 2023-10-17 6:11 Richard Henderson
2023-10-17 6:11 ` [PATCH v2 01/90] target/sparc: Clear may_lookup for npc == DYNAMIC_PC Richard Henderson
` (90 more replies)
0 siblings, 91 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
While doing some other testing the other day, I noticed my sparc64
chroot running particularly slowly. I think I know what the problem
is there, but fixing that was going to be particularly ugly with the
existing sparc translator.
So I've converted the translator to something more managable. :-)
Changes for v2:
* Fixes for JMPL, RETT, SAVE and RESTORE.
* Fixes for FMOV etc, which had lost gen_op_clear_ieee_excp_and_FTT.
* Allow conditional exceptions to be raised out of line
Use this for gen_check_align and conditional trap.
* Keep properties and feature bits in sync.
r~
Richard Henderson (90):
target/sparc: Clear may_lookup for npc == DYNAMIC_PC
target/sparc: Implement check_align inline
target/sparc: Avoid helper_raise_exception in helper_st_asi
target/sparc: Set TCG_GUEST_DEFAULT_MO
configs: Enable MTTCG for sparc, sparc64
target/sparc: Define features via cpu-feature.h.inc
target/sparc: Use CPU_FEATURE_BIT_* for cpu properties
target/sparc: Remove sparcv7 cpu features
target/sparc: Add decodetree infrastructure
target/sparc: Define AM_CHECK for sparc32
target/sparc: Move CALL to decodetree
target/sparc: Move BPcc and Bicc to decodetree
target/sparc: Move BPr to decodetree
target/sparc: Move FBPfcc and FBfcc to decodetree
target/sparc: Merge gen_cond with only caller
target/sparc: Merge gen_fcond with only caller
target/sparc: Merge gen_branch_[an] with only caller
target/sparc: Pass DisasCompare to advance_jump_cond
target/sparc: Move SETHI to decodetree
target/sparc: Move Tcc to decodetree
target/sparc: Move RDASR, STBAR, MEMBAR to decodetree
target/sparc: Move RDPSR, RDHPR to decodetree
target/sparc: Move RDWIM, RDPR to decodetree
target/sparc: Move RDTBR, FLUSHW to decodetree
target/sparc: Move WRASR to decodetree
target/sparc: Move WRPSR, SAVED, RESTORED to decodetree
target/sparc: Move WRWIM, WRPR to decodetree
target/sparc: Move WRTBR, WRHPR to decodetree
target/sparc: Move basic arithmetic to decodetree
target/sparc: Move ADDC to decodetree
target/sparc: Move MULX to decodetree
target/sparc: Move UMUL, SMUL to decodetree
target/sparc: Move SUBC to decodetree
target/sparc: Move UDIVX, SDIVX to decodetree
target/sparc: Move UDIV, SDIV to decodetree
target/sparc: Move TADD, TSUB, MULS to decodetree
target/sparc: Move SLL, SRL, SRA to decodetree
target/sparc: Move MOVcc, MOVR to decodetree
target/sparc: Move POPC to decodetree
target/sparc: Convert remaining v8 coproc insns to decodetree
target/sparc: Move JMPL, RETT, RETURN to decodetree
target/sparc: Move FLUSH, SAVE, RESTORE to decodetree
target/sparc: Move DONE, RETRY to decodetree
target/sparc: Split out resolve_asi
target/sparc: Drop ifdef around get_asi and friends
target/sparc: Split out ldst functions with asi pre-computed
target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for GET_ASI_DTWINX
target/sparc: Move simple integer load/store to decodetree
target/sparc: Move asi integer load/store to decodetree
target/sparc: Move LDSTUB, LDSTUBA to decodetree
target/sparc: Move SWAP, SWAPA to decodetree
target/sparc: Move CASA, CASXA to decodetree
target/sparc: Move PREFETCH, PREFETCHA to decodetree
target/sparc: Split out fp ldst functions with asi precomputed
target/sparc: Move simple fp load/store to decodetree
target/sparc: Move asi fp load/store to decodetree
target/sparc: Move LDFSR, STFSR to decodetree
target/sparc: Merge LDFSR, LDXFSR implementations
target/sparc: Move EDGE* to decodetree
target/sparc: Move ARRAY* to decodetree
target/sparc: Move ADDRALIGN* to decodetree
target/sparc: Move BMASK to decodetree
target/sparc: Move FMOVS, FNEGS, FABSS, FSRC*S, FNOT*S to decodetree
target/sparc: Move FMOVD, FNEGD, FABSD, FSRC*D, FNOT*D to decodetree
target/sparc: Use tcg_gen_vec_{add,sub}*
target/sparc: Move gen_ne_fop_FFF insns to decodetree
target/sparc: Move gen_ne_fop_DDD insns to decodetree
target/sparc: Move PDIST to decodetree
target/sparc: Move gen_gsr_fop_DDD insns to decodetree
target/sparc: Move gen_fop_FF insns to decodetree
target/sparc: Move gen_fop_DD insns to decodetree
target/sparc: Move FSQRTq to decodetree
target/sparc: Move gen_fop_FFF insns to decodetree
target/sparc: Move gen_fop_DDD insns to decodetree
target/sparc: Move gen_fop_QQQ insns to decodetree
target/sparc: Move FSMULD to decodetree
target/sparc: Move FDMULQ to decodetree
target/sparc: Move gen_fop_FD insns to decodetree
target/sparc: Move FiTOd, FsTOd, FsTOx to decodetree
target/sparc: Move FqTOs, FqTOi to decodetree
target/sparc: Move FqTOd, FqTOx to decodetree
target/sparc: Move FiTOq, FsTOq to decodetree
target/sparc: Move FdTOq, FxTOq to decodetree
target/sparc: Move FMOVq, FNEGq, FABSq to decodetree
target/sparc: Move FMOVR, FMOVcc, FMOVfcc to decodetree
target/sparc: Convert FCMP, FCMPE to decodetree
target/sparc: Move FPCMP* to decodetree
target/sparc: Move FPACK16, FPACKFIX to decodetree
target/sparc: Convert FZERO, FONE to decodetree
target/sparc: Remove disas_sparc_legacy
configs/targets/sparc-softmmu.mak | 1 +
configs/targets/sparc64-softmmu.mak | 1 +
linux-user/sparc/target_syscall.h | 6 +-
target/sparc/cpu.h | 76 +-
target/sparc/helper.h | 16 +-
target/sparc/cpu-feature.h.inc | 14 +
target/sparc/insns.decode | 540 +++
target/sparc/cpu.c | 41 +-
target/sparc/fop_helper.c | 17 +-
target/sparc/ldst_helper.c | 17 +-
target/sparc/translate.c | 6833 +++++++++++++--------------
target/sparc/vis_helper.c | 59 -
target/sparc/meson.build | 3 +
13 files changed, 3985 insertions(+), 3639 deletions(-)
create mode 100644 target/sparc/cpu-feature.h.inc
create mode 100644 target/sparc/insns.decode
--
2.34.1
^ permalink raw reply [flat|nested] 92+ messages in thread
* [PATCH v2 01/90] target/sparc: Clear may_lookup for npc == DYNAMIC_PC
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 02/90] target/sparc: Implement check_align inline Richard Henderson
` (89 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland, qemu-stable
With pairs of jmp+rett, pc == DYNAMIC_PC_LOOKUP and
npc == DYNAMIC_PC. Make sure that we exit for interrupts.
Cc: qemu-stable@nongnu.org
Fixes: 633c42834c7 ("target/sparc: Introduce DYNAMIC_PC_LOOKUP")
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index f92ff80ac8..8fabed28fd 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -5654,10 +5654,10 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
break;
}
+ may_lookup = true;
if (dc->pc & 3) {
switch (dc->pc) {
case DYNAMIC_PC_LOOKUP:
- may_lookup = true;
break;
case DYNAMIC_PC:
may_lookup = false;
@@ -5667,10 +5667,24 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
}
} else {
tcg_gen_movi_tl(cpu_pc, dc->pc);
- may_lookup = true;
}
- save_npc(dc);
+ if (dc->npc & 3) {
+ switch (dc->npc) {
+ case JUMP_PC:
+ gen_generic_branch(dc);
+ break;
+ case DYNAMIC_PC:
+ may_lookup = false;
+ break;
+ case DYNAMIC_PC_LOOKUP:
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ } else {
+ tcg_gen_movi_tl(cpu_npc, dc->npc);
+ }
if (may_lookup) {
tcg_gen_lookup_and_goto_ptr();
} else {
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 02/90] target/sparc: Implement check_align inline
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
2023-10-17 6:11 ` [PATCH v2 01/90] target/sparc: Clear may_lookup for npc == DYNAMIC_PC Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 03/90] target/sparc: Avoid helper_raise_exception in helper_st_asi Richard Henderson
` (88 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Emit the exception at the end of the translation block,
so that the non-exception case can fall through.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 1 -
target/sparc/ldst_helper.c | 7 ++--
target/sparc/translate.c | 68 +++++++++++++++++++++++++++++++++-----
3 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index b8f1e78c75..b116ddcb29 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -24,7 +24,6 @@ DEF_HELPER_FLAGS_2(tick_set_count, TCG_CALL_NO_RWG, void, ptr, i64)
DEF_HELPER_FLAGS_3(tick_get_count, TCG_CALL_NO_WG, i64, env, ptr, int)
DEF_HELPER_FLAGS_2(tick_set_limit, TCG_CALL_NO_RWG, void, ptr, i64)
#endif
-DEF_HELPER_FLAGS_3(check_align, TCG_CALL_NO_WG, void, env, tl, i32)
DEF_HELPER_1(debug, void, env)
DEF_HELPER_1(save, void, env)
DEF_HELPER_1(restore, void, env)
diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index 78b03308ae..246de86c98 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -360,6 +360,7 @@ static inline void do_check_asi(CPUSPARCState *env, int asi, uintptr_t ra)
#endif /* !CONFIG_USER_ONLY */
#endif
+#if defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)
static void do_check_align(CPUSPARCState *env, target_ulong addr,
uint32_t align, uintptr_t ra)
{
@@ -367,11 +368,7 @@ static void do_check_align(CPUSPARCState *env, target_ulong addr,
cpu_raise_exception_ra(env, TT_UNALIGNED, ra);
}
}
-
-void helper_check_align(CPUSPARCState *env, target_ulong addr, uint32_t align)
-{
- do_check_align(env, addr, align, GETPC());
-}
+#endif
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \
defined(DEBUG_MXCC)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 8fabed28fd..8f6fd453e7 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -68,6 +68,15 @@ static TCGv cpu_wim;
/* Floating point registers */
static TCGv_i64 cpu_fpr[TARGET_DPREGS];
+typedef struct DisasDelayException {
+ struct DisasDelayException *next;
+ TCGLabel *lab;
+ TCGv_i32 excp;
+ /* Saved state at parent insn. */
+ target_ulong pc;
+ target_ulong npc;
+} DisasDelayException;
+
typedef struct DisasContext {
DisasContextBase base;
target_ulong pc; /* current Program Counter: integer or DYNAMIC_PC */
@@ -89,6 +98,7 @@ typedef struct DisasContext {
int fprs_dirty;
int asi;
#endif
+ DisasDelayException *delay_excp_list;
} DisasContext;
typedef struct {
@@ -984,9 +994,38 @@ static void gen_exception(DisasContext *dc, int which)
dc->base.is_jmp = DISAS_NORETURN;
}
-static void gen_check_align(TCGv addr, int mask)
+static TCGLabel *delay_exceptionv(DisasContext *dc, TCGv_i32 excp)
{
- gen_helper_check_align(tcg_env, addr, tcg_constant_i32(mask));
+ DisasDelayException *e = g_new0(DisasDelayException, 1);
+
+ e->next = dc->delay_excp_list;
+ dc->delay_excp_list = e;
+
+ e->lab = gen_new_label();
+ e->excp = excp;
+ e->pc = dc->pc;
+ /* Caller must have used flush_cond before branch. */
+ assert(e->npc != JUMP_PC);
+ e->npc = dc->npc;
+
+ return e->lab;
+}
+
+static TCGLabel *delay_exception(DisasContext *dc, int excp)
+{
+ return delay_exceptionv(dc, tcg_constant_i32(excp));
+}
+
+static void gen_check_align(DisasContext *dc, TCGv addr, int mask)
+{
+ TCGv t = tcg_temp_new();
+ TCGLabel *lab;
+
+ tcg_gen_andi_tl(t, addr, mask);
+
+ flush_cond(dc);
+ lab = delay_exception(dc, TT_UNALIGNED);
+ tcg_gen_brcondi_tl(TCG_COND_NE, t, 0, lab);
}
static void gen_mov_pc_npc(DisasContext *dc)
@@ -5019,9 +5058,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
}
}
+ gen_check_align(dc, cpu_tmp0, 3);
gen_helper_restore(tcg_env);
gen_mov_pc_npc(dc);
- gen_check_align(cpu_tmp0, 3);
tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
dc->npc = DYNAMIC_PC_LOOKUP;
goto jmp_insn;
@@ -5044,12 +5083,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
switch (xop) {
case 0x38: /* jmpl */
{
- TCGv t = gen_dest_gpr(dc, rd);
- tcg_gen_movi_tl(t, dc->pc);
- gen_store_gpr(dc, rd, t);
-
+ gen_check_align(dc, cpu_tmp0, 3);
+ gen_store_gpr(dc, rd, tcg_constant_tl(dc->pc));
gen_mov_pc_npc(dc);
- gen_check_align(cpu_tmp0, 3);
gen_address_mask(dc, cpu_tmp0);
tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
dc->npc = DYNAMIC_PC_LOOKUP;
@@ -5060,8 +5096,8 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
{
if (!supervisor(dc))
goto priv_insn;
+ gen_check_align(dc, cpu_tmp0, 3);
gen_mov_pc_npc(dc);
- gen_check_align(cpu_tmp0, 3);
tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
dc->npc = DYNAMIC_PC;
gen_helper_rett(tcg_env);
@@ -5643,6 +5679,7 @@ static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
+ DisasDelayException *e, *e_next;
bool may_lookup;
switch (dc->base.is_jmp) {
@@ -5704,6 +5741,19 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
default:
g_assert_not_reached();
}
+
+ for (e = dc->delay_excp_list; e ; e = e_next) {
+ gen_set_label(e->lab);
+
+ tcg_gen_movi_tl(cpu_pc, e->pc);
+ if (e->npc % 4 == 0) {
+ tcg_gen_movi_tl(cpu_npc, e->npc);
+ }
+ gen_helper_raise_exception(tcg_env, e->excp);
+
+ e_next = e->next;
+ g_free(e);
+ }
}
static void sparc_tr_disas_log(const DisasContextBase *dcbase,
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 03/90] target/sparc: Avoid helper_raise_exception in helper_st_asi
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
2023-10-17 6:11 ` [PATCH v2 01/90] target/sparc: Clear may_lookup for npc == DYNAMIC_PC Richard Henderson
2023-10-17 6:11 ` [PATCH v2 02/90] target/sparc: Implement check_align inline Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 04/90] target/sparc: Set TCG_GUEST_DEFAULT_MO Richard Henderson
` (87 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Always use cpu_raise_exception_ra with GETPC for unwind.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/ldst_helper.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index 246de86c98..09066d5487 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -1650,7 +1650,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
int idx = ((asi & 2) >> 1) | ((asi & 8) >> 2);
env->dmmu.sun4v_tsb_pointers[idx] = val;
} else {
- helper_raise_exception(env, TT_ILL_INSN);
+ goto illegal_insn;
}
break;
case 0x33:
@@ -1662,7 +1662,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
*/
env->dmmu.sun4v_ctx_config[(asi & 8) >> 3] = val;
} else {
- helper_raise_exception(env, TT_ILL_INSN);
+ goto illegal_insn;
}
break;
case 0x35:
@@ -1679,7 +1679,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
int idx = ((asi & 2) >> 1) | ((asi & 8) >> 2);
env->immu.sun4v_tsb_pointers[idx] = val;
} else {
- helper_raise_exception(env, TT_ILL_INSN);
+ goto illegal_insn;
}
break;
case 0x37:
@@ -1691,7 +1691,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
*/
env->immu.sun4v_ctx_config[(asi & 8) >> 3] = val;
} else {
- helper_raise_exception(env, TT_ILL_INSN);
+ goto illegal_insn;
}
break;
case ASI_UPA_CONFIG: /* UPA config */
@@ -1920,6 +1920,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
default:
sparc_raise_mmu_fault(cs, addr, true, false, 1, size, GETPC());
return;
+ illegal_insn:
+ cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC());
}
}
#endif /* CONFIG_USER_ONLY */
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 04/90] target/sparc: Set TCG_GUEST_DEFAULT_MO
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (2 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 03/90] target/sparc: Avoid helper_raise_exception in helper_st_asi Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 05/90] configs: Enable MTTCG for sparc, sparc64 Richard Henderson
` (86 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland, Philippe Mathieu-Daudé
Always use TSO, per the Oracle 2015 manual.
This is slightly less restrictive than the TCG_MO_ALL default,
and happens to match the i386 model, which will eliminate a few
extra barriers on that host.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/cpu.h | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index b3a98f1d74..9fc5c401d2 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -6,6 +6,29 @@
#include "exec/cpu-defs.h"
#include "qemu/cpu-float.h"
+/*
+ * From Oracle SPARC Architecture 2015:
+ *
+ * Compatibility notes: The PSO memory model described in SPARC V8 and
+ * SPARC V9 compatibility architecture specifications was never implemented
+ * in a SPARC V9 implementation and is not included in the Oracle SPARC
+ * Architecture specification.
+ *
+ * The RMO memory model described in the SPARC V9 specification was
+ * implemented in some non-Sun SPARC V9 implementations, but is not
+ * directly supported in Oracle SPARC Architecture 2015 implementations.
+ *
+ * Therefore always use TSO in QEMU.
+ *
+ * D.5 Specification of Partial Store Order (PSO)
+ * ... [loads] are followed by an implied MEMBAR #LoadLoad | #LoadStore.
+ *
+ * D.6 Specification of Total Store Order (TSO)
+ * ... PSO with the additional requirement that all [stores] are followed
+ * by an implied MEMBAR #StoreStore.
+ */
+#define TCG_GUEST_DEFAULT_MO (TCG_MO_LD_LD | TCG_MO_LD_ST | TCG_MO_ST_ST)
+
#if !defined(TARGET_SPARC64)
#define TARGET_DPREGS 16
#else
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 05/90] configs: Enable MTTCG for sparc, sparc64
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (3 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 04/90] target/sparc: Set TCG_GUEST_DEFAULT_MO Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 06/90] target/sparc: Define features via cpu-feature.h.inc Richard Henderson
` (85 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
This will be of small comfort to sparc64, because both
sun4u and sun4v board models force max_cpus = 1.
But it does enable actual smp for sparc32 sun4m.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
configs/targets/sparc-softmmu.mak | 1 +
configs/targets/sparc64-softmmu.mak | 1 +
2 files changed, 2 insertions(+)
diff --git a/configs/targets/sparc-softmmu.mak b/configs/targets/sparc-softmmu.mak
index 454eb35499..a5d9200382 100644
--- a/configs/targets/sparc-softmmu.mak
+++ b/configs/targets/sparc-softmmu.mak
@@ -1,2 +1,3 @@
TARGET_ARCH=sparc
TARGET_BIG_ENDIAN=y
+TARGET_SUPPORTS_MTTCG=y
diff --git a/configs/targets/sparc64-softmmu.mak b/configs/targets/sparc64-softmmu.mak
index d3f8a3b710..36ca64ec41 100644
--- a/configs/targets/sparc64-softmmu.mak
+++ b/configs/targets/sparc64-softmmu.mak
@@ -1,3 +1,4 @@
TARGET_ARCH=sparc64
TARGET_BASE_ARCH=sparc
TARGET_BIG_ENDIAN=y
+TARGET_SUPPORTS_MTTCG=y
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 06/90] target/sparc: Define features via cpu-feature.h.inc
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (4 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 05/90] configs: Enable MTTCG for sparc, sparc64 Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 07/90] target/sparc: Use CPU_FEATURE_BIT_* for cpu properties Richard Henderson
` (84 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Manage feature bits automatically.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/cpu.h | 32 +++++++++++++-------------------
target/sparc/cpu-feature.h.inc | 19 +++++++++++++++++++
2 files changed, 32 insertions(+), 19 deletions(-)
create mode 100644 target/sparc/cpu-feature.h.inc
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 9fc5c401d2..aaecbf0876 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -291,25 +291,19 @@ struct sparc_def_t {
uint32_t maxtl;
};
-#define CPU_FEATURE_FLOAT (1 << 0)
-#define CPU_FEATURE_FLOAT128 (1 << 1)
-#define CPU_FEATURE_SWAP (1 << 2)
-#define CPU_FEATURE_MUL (1 << 3)
-#define CPU_FEATURE_DIV (1 << 4)
-#define CPU_FEATURE_FLUSH (1 << 5)
-#define CPU_FEATURE_FSQRT (1 << 6)
-#define CPU_FEATURE_FMUL (1 << 7)
-#define CPU_FEATURE_VIS1 (1 << 8)
-#define CPU_FEATURE_VIS2 (1 << 9)
-#define CPU_FEATURE_FSMULD (1 << 10)
-#define CPU_FEATURE_HYPV (1 << 11)
-#define CPU_FEATURE_CMT (1 << 12)
-#define CPU_FEATURE_GL (1 << 13)
-#define CPU_FEATURE_TA0_SHUTDOWN (1 << 14) /* Shutdown on "ta 0x0" */
-#define CPU_FEATURE_ASR17 (1 << 15)
-#define CPU_FEATURE_CACHE_CTRL (1 << 16)
-#define CPU_FEATURE_POWERDOWN (1 << 17)
-#define CPU_FEATURE_CASA (1 << 18)
+#define FEATURE(X) CPU_FEATURE_BIT_##X,
+enum {
+#include "cpu-feature.h.inc"
+};
+
+#undef FEATURE
+#define FEATURE(X) CPU_FEATURE_##X = 1u << CPU_FEATURE_BIT_##X,
+
+enum {
+#include "cpu-feature.h.inc"
+};
+
+#undef FEATURE
#ifndef TARGET_SPARC64
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
diff --git a/target/sparc/cpu-feature.h.inc b/target/sparc/cpu-feature.h.inc
new file mode 100644
index 0000000000..d35fe90c92
--- /dev/null
+++ b/target/sparc/cpu-feature.h.inc
@@ -0,0 +1,19 @@
+FEATURE(FLOAT)
+FEATURE(FLOAT128)
+FEATURE(SWAP)
+FEATURE(MUL)
+FEATURE(DIV)
+FEATURE(FLUSH)
+FEATURE(FSQRT)
+FEATURE(FMUL)
+FEATURE(VIS1)
+FEATURE(VIS2)
+FEATURE(FSMULD)
+FEATURE(HYPV)
+FEATURE(CMT)
+FEATURE(GL)
+FEATURE(TA0_SHUTDOWN) /* Shutdown on "ta 0x0" */
+FEATURE(ASR17)
+FEATURE(CACHE_CTRL)
+FEATURE(POWERDOWN)
+FEATURE(CASA)
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 07/90] target/sparc: Use CPU_FEATURE_BIT_* for cpu properties
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (5 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 06/90] target/sparc: Define features via cpu-feature.h.inc Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 08/90] target/sparc: Remove sparcv7 cpu features Richard Henderson
` (83 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Use symbols not integer constants for the bit positions.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/cpu.c | 42 ++++++++++++++++++++++++++++--------------
1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 8ba96ae225..e4d1c552e5 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -836,20 +836,34 @@ static PropertyInfo qdev_prop_nwindows = {
};
static Property sparc_cpu_properties[] = {
- DEFINE_PROP_BIT("float", SPARCCPU, env.def.features, 0, false),
- DEFINE_PROP_BIT("float128", SPARCCPU, env.def.features, 1, false),
- DEFINE_PROP_BIT("swap", SPARCCPU, env.def.features, 2, false),
- DEFINE_PROP_BIT("mul", SPARCCPU, env.def.features, 3, false),
- DEFINE_PROP_BIT("div", SPARCCPU, env.def.features, 4, false),
- DEFINE_PROP_BIT("flush", SPARCCPU, env.def.features, 5, false),
- DEFINE_PROP_BIT("fsqrt", SPARCCPU, env.def.features, 6, false),
- DEFINE_PROP_BIT("fmul", SPARCCPU, env.def.features, 7, false),
- DEFINE_PROP_BIT("vis1", SPARCCPU, env.def.features, 8, false),
- DEFINE_PROP_BIT("vis2", SPARCCPU, env.def.features, 9, false),
- DEFINE_PROP_BIT("fsmuld", SPARCCPU, env.def.features, 10, false),
- DEFINE_PROP_BIT("hypv", SPARCCPU, env.def.features, 11, false),
- DEFINE_PROP_BIT("cmt", SPARCCPU, env.def.features, 12, false),
- DEFINE_PROP_BIT("gl", SPARCCPU, env.def.features, 13, false),
+ DEFINE_PROP_BIT("float", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_FLOAT, false),
+ DEFINE_PROP_BIT("float128", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_FLOAT128, false),
+ DEFINE_PROP_BIT("swap", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_SWAP, false),
+ DEFINE_PROP_BIT("mul", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_MUL, false),
+ DEFINE_PROP_BIT("div", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_DIV, false),
+ DEFINE_PROP_BIT("flush", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_FLUSH, false),
+ DEFINE_PROP_BIT("fsqrt", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_FSQRT, false),
+ DEFINE_PROP_BIT("fmul", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_FMUL, false),
+ DEFINE_PROP_BIT("vis1", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_VIS1, false),
+ DEFINE_PROP_BIT("vis2", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_VIS2, false),
+ DEFINE_PROP_BIT("fsmuld", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_FSMULD, false),
+ DEFINE_PROP_BIT("hypv", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_HYPV, false),
+ DEFINE_PROP_BIT("cmt", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_CMT, false),
+ DEFINE_PROP_BIT("gl", SPARCCPU, env.def.features,
+ CPU_FEATURE_BIT_GL, false),
DEFINE_PROP_UNSIGNED("iu-version", SPARCCPU, env.def.iu_version, 0,
qdev_prop_uint64, target_ulong),
DEFINE_PROP_UINT32("fpu-version", SPARCCPU, env.def.fpu_version, 0),
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 08/90] target/sparc: Remove sparcv7 cpu features
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (6 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 07/90] target/sparc: Use CPU_FEATURE_BIT_* for cpu properties Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 09/90] target/sparc: Add decodetree infrastructure Richard Henderson
` (82 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
The oldest supported cpu is the microsparc 1; all other cpus
use CPU_DEFAULT_FEATURES. Remove the features that must always
be present for sparcv7: FLOAT, SWAP, FLUSH, FSQRT, FMUL.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/sparc/target_syscall.h | 6 +-----
target/sparc/cpu.h | 21 +++++++--------------
target/sparc/cpu-feature.h.inc | 5 -----
target/sparc/cpu.c | 19 +++----------------
target/sparc/translate.c | 12 ------------
5 files changed, 11 insertions(+), 52 deletions(-)
diff --git a/linux-user/sparc/target_syscall.h b/linux-user/sparc/target_syscall.h
index be77e44eb8..e421165357 100644
--- a/linux-user/sparc/target_syscall.h
+++ b/linux-user/sparc/target_syscall.h
@@ -50,11 +50,7 @@ static inline abi_ulong target_shmlba(CPUSPARCState *env)
#ifdef TARGET_SPARC64
return MAX(TARGET_PAGE_SIZE, 16 * 1024);
#else
- if (!(env->def.features & CPU_FEATURE_FLUSH)) {
- return 64 * 1024;
- } else {
- return 256 * 1024;
- }
+ return 256 * 1024;
#endif
}
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index aaecbf0876..758a4e8aaa 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -306,17 +306,12 @@ enum {
#undef FEATURE
#ifndef TARGET_SPARC64
-#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
- CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
- CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
- CPU_FEATURE_FMUL | CPU_FEATURE_FSMULD)
+#define CPU_DEFAULT_FEATURES (CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
+ CPU_FEATURE_FSMULD)
#else
-#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
- CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
- CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
- CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \
- CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD | \
- CPU_FEATURE_CASA)
+#define CPU_DEFAULT_FEATURES (CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
+ CPU_FEATURE_FSMULD | CPU_FEATURE_CASA | \
+ CPU_FEATURE_VIS1 | CPU_FEATURE_VIS2)
enum {
mmu_us_12, // Ultrasparc < III (64 entry TLB)
mmu_us_3, // Ultrasparc III (512 entry TLB)
@@ -799,14 +794,12 @@ static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, vaddr *pc,
if (env->pstate & PS_AM) {
flags |= TB_FLAG_AM_ENABLED;
}
- if ((env->def.features & CPU_FEATURE_FLOAT)
- && (env->pstate & PS_PEF)
- && (env->fprs & FPRS_FEF)) {
+ if ((env->pstate & PS_PEF) && (env->fprs & FPRS_FEF)) {
flags |= TB_FLAG_FPU_ENABLED;
}
flags |= env->asi << TB_FLAG_ASI_SHIFT;
#else
- if ((env->def.features & CPU_FEATURE_FLOAT) && env->psref) {
+ if (env->psref) {
flags |= TB_FLAG_FPU_ENABLED;
}
#endif
diff --git a/target/sparc/cpu-feature.h.inc b/target/sparc/cpu-feature.h.inc
index d35fe90c92..d800f18c4e 100644
--- a/target/sparc/cpu-feature.h.inc
+++ b/target/sparc/cpu-feature.h.inc
@@ -1,11 +1,6 @@
-FEATURE(FLOAT)
FEATURE(FLOAT128)
-FEATURE(SWAP)
FEATURE(MUL)
FEATURE(DIV)
-FEATURE(FLUSH)
-FEATURE(FSQRT)
-FEATURE(FMUL)
FEATURE(VIS1)
FEATURE(VIS2)
FEATURE(FSMULD)
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index e4d1c552e5..0a3882653c 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -403,9 +403,7 @@ static const sparc_def_t sparc_defs[] = {
.mmu_sfsr_mask = 0x00016fff,
.mmu_trcr_mask = 0x0000003f,
.nwindows = 7,
- .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
- CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
- CPU_FEATURE_FMUL,
+ .features = CPU_FEATURE_MUL | CPU_FEATURE_DIV,
},
{
.name = "TI MicroSparc II",
@@ -757,9 +755,8 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
CPUSPARCState *env = &cpu->env;
#if defined(CONFIG_USER_ONLY)
- if ((env->def.features & CPU_FEATURE_FLOAT)) {
- env->def.features |= CPU_FEATURE_FLOAT128;
- }
+ /* We are emulating the kernel, which will trap and emulate float128. */
+ env->def.features |= CPU_FEATURE_FLOAT128;
#endif
env->version = env->def.iu_version;
@@ -836,22 +833,12 @@ static PropertyInfo qdev_prop_nwindows = {
};
static Property sparc_cpu_properties[] = {
- DEFINE_PROP_BIT("float", SPARCCPU, env.def.features,
- CPU_FEATURE_BIT_FLOAT, false),
DEFINE_PROP_BIT("float128", SPARCCPU, env.def.features,
CPU_FEATURE_BIT_FLOAT128, false),
- DEFINE_PROP_BIT("swap", SPARCCPU, env.def.features,
- CPU_FEATURE_BIT_SWAP, false),
DEFINE_PROP_BIT("mul", SPARCCPU, env.def.features,
CPU_FEATURE_BIT_MUL, false),
DEFINE_PROP_BIT("div", SPARCCPU, env.def.features,
CPU_FEATURE_BIT_DIV, false),
- DEFINE_PROP_BIT("flush", SPARCCPU, env.def.features,
- CPU_FEATURE_BIT_FLUSH, false),
- DEFINE_PROP_BIT("fsqrt", SPARCCPU, env.def.features,
- CPU_FEATURE_BIT_FSQRT, false),
- DEFINE_PROP_BIT("fmul", SPARCCPU, env.def.features,
- CPU_FEATURE_BIT_FMUL, false),
DEFINE_PROP_BIT("vis1", SPARCCPU, env.def.features,
CPU_FEATURE_BIT_VIS1, false),
DEFINE_PROP_BIT("vis2", SPARCCPU, env.def.features,
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 8f6fd453e7..cab9f13421 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -3527,11 +3527,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
gen_ne_fop_FF(dc, rd, rs2, gen_helper_fabss);
break;
case 0x29: /* fsqrts */
- CHECK_FPU_FEATURE(dc, FSQRT);
gen_fop_FF(dc, rd, rs2, gen_helper_fsqrts);
break;
case 0x2a: /* fsqrtd */
- CHECK_FPU_FEATURE(dc, FSQRT);
gen_fop_DD(dc, rd, rs2, gen_helper_fsqrtd);
break;
case 0x2b: /* fsqrtq */
@@ -3559,16 +3557,13 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fsubq);
break;
case 0x49: /* fmuls */
- CHECK_FPU_FEATURE(dc, FMUL);
gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fmuls);
break;
case 0x4a: /* fmuld */
- CHECK_FPU_FEATURE(dc, FMUL);
gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld);
break;
case 0x4b: /* fmulq */
CHECK_FPU_FEATURE(dc, FLOAT128);
- CHECK_FPU_FEATURE(dc, FMUL);
gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fmulq);
break;
case 0x4d: /* fdivs */
@@ -5105,8 +5100,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
goto jmp_insn;
#endif
case 0x3b: /* flush */
- if (!((dc)->def->features & CPU_FEATURE_FLUSH))
- goto unimp_flush;
/* nop */
break;
case 0x3c: /* save */
@@ -5224,7 +5217,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
break;
case 0x0f:
/* swap, swap register with memory. Also atomically */
- CHECK_IU_FEATURE(dc, SWAP);
cpu_src1 = gen_load_gpr(dc, rd);
gen_swap(dc, cpu_val, cpu_src1, cpu_addr,
dc->mem_idx, MO_TEUL);
@@ -5256,7 +5248,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
break;
case 0x1f: /* swapa, swap reg with alt. memory. Also
atomically */
- CHECK_IU_FEATURE(dc, SWAP);
cpu_src1 = gen_load_gpr(dc, rd);
gen_swap_asi(dc, cpu_val, cpu_src1, cpu_addr, insn);
break;
@@ -5578,9 +5569,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
illegal_insn:
gen_exception(dc, TT_ILL_INSN);
return;
- unimp_flush:
- gen_exception(dc, TT_UNIMP_FLUSH);
- return;
#if !defined(CONFIG_USER_ONLY)
priv_insn:
gen_exception(dc, TT_PRIV_INSN);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 09/90] target/sparc: Add decodetree infrastructure
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (7 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 08/90] target/sparc: Remove sparcv7 cpu features Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 10/90] target/sparc: Define AM_CHECK for sparc32 Richard Henderson
` (81 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 5 +++
target/sparc/translate.c | 69 ++++++++++++++++++++++++++-------------
target/sparc/meson.build | 3 ++
3 files changed, 55 insertions(+), 22 deletions(-)
create mode 100644 target/sparc/insns.decode
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
new file mode 100644
index 0000000000..5811a679db
--- /dev/null
+++ b/target/sparc/insns.decode
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.0+
+#
+# Sparc instruction decode definitions.
+# Copyright (c) 2023 Richard Henderson <rth@twiddle.net>
+
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index cab9f13421..080bc5f8a2 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -3003,6 +3003,47 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
}
#endif
+/* Include the auto-generated decoder. */
+#include "decode-insns.c.inc"
+
+#define TRANS(NAME, AVAIL, FUNC, ...) \
+ static bool trans_##NAME(DisasContext *dc, arg_##NAME *a) \
+ { return avail_##AVAIL(dc) && FUNC(dc, __VA_ARGS__); }
+
+#define avail_ALL(C) true
+#ifdef TARGET_SPARC64
+# define avail_32(C) false
+# define avail_64(C) true
+#else
+# define avail_32(C) true
+# define avail_64(C) false
+#endif
+
+/* Default case for non jump instructions. */
+static bool advance_pc(DisasContext *dc)
+{
+ if (dc->npc & 3) {
+ switch (dc->npc) {
+ case DYNAMIC_PC:
+ case DYNAMIC_PC_LOOKUP:
+ dc->pc = dc->npc;
+ gen_op_next_insn();
+ break;
+ case JUMP_PC:
+ /* we can do a static jump */
+ gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
+ dc->base.is_jmp = DISAS_NORETURN;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ } else {
+ dc->pc = dc->npc;
+ dc->npc = dc->npc + 4;
+ }
+ return true;
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -3011,7 +3052,7 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
goto nfpu_insn;
/* before an instruction, dc->pc must be static */
-static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
+static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
{
unsigned int opc, rs1, rs2, rd;
TCGv cpu_src1, cpu_src2;
@@ -5544,26 +5585,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
}
break;
}
- /* default case for non jump instructions */
- if (dc->npc & 3) {
- switch (dc->npc) {
- case DYNAMIC_PC:
- case DYNAMIC_PC_LOOKUP:
- dc->pc = dc->npc;
- gen_op_next_insn();
- break;
- case JUMP_PC:
- /* we can do a static jump */
- gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
- dc->base.is_jmp = DISAS_NORETURN;
- break;
- default:
- g_assert_not_reached();
- }
- } else {
- dc->pc = dc->npc;
- dc->npc = dc->npc + 4;
- }
+ advance_pc(dc);
jmp_insn:
return;
illegal_insn:
@@ -5654,7 +5676,10 @@ static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
insn = translator_ldl(env, &dc->base, dc->pc);
dc->base.pc_next += 4;
- disas_sparc_insn(dc, insn);
+
+ if (!decode(dc, insn)) {
+ disas_sparc_legacy(dc, insn);
+ }
if (dc->base.is_jmp == DISAS_NORETURN) {
return;
diff --git a/target/sparc/meson.build b/target/sparc/meson.build
index 48025cce76..c316773db6 100644
--- a/target/sparc/meson.build
+++ b/target/sparc/meson.build
@@ -1,4 +1,7 @@
+gen = decodetree.process('insns.decode')
+
sparc_ss = ss.source_set()
+sparc_ss.add(gen)
sparc_ss.add(files(
'cc_helper.c',
'cpu.c',
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 10/90] target/sparc: Define AM_CHECK for sparc32
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (8 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 09/90] target/sparc: Add decodetree infrastructure Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 11/90] target/sparc: Move CALL to decodetree Richard Henderson
` (80 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Define as false, which allows some ifdef removal.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 080bc5f8a2..9eb2b7e52f 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -268,20 +268,21 @@ static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
#endif
#endif
-#ifdef TARGET_SPARC64
-#ifndef TARGET_ABI32
-#define AM_CHECK(dc) ((dc)->address_mask_32bit)
+#if !defined(TARGET_SPARC64)
+# define AM_CHECK(dc) false
+#elif defined(TARGET_ABI32)
+# define AM_CHECK(dc) true
+#elif defined(CONFIG_USER_ONLY)
+# define AM_CHECK(dc) false
#else
-#define AM_CHECK(dc) (1)
-#endif
+# define AM_CHECK(dc) ((dc)->address_mask_32bit)
#endif
static void gen_address_mask(DisasContext *dc, TCGv addr)
{
-#ifdef TARGET_SPARC64
- if (AM_CHECK(dc))
+ if (AM_CHECK(dc)) {
tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
-#endif
+ }
}
static TCGv gen_load_gpr(DisasContext *dc, int reg)
@@ -1366,11 +1367,9 @@ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
target_ulong target = dc->pc + offset;
-#ifdef TARGET_SPARC64
if (unlikely(AM_CHECK(dc))) {
target &= 0xffffffffULL;
}
-#endif
if (cond == 0x0) {
/* unconditional not taken */
if (a) {
@@ -1406,11 +1405,9 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
target_ulong target = dc->pc + offset;
-#ifdef TARGET_SPARC64
if (unlikely(AM_CHECK(dc))) {
target &= 0xffffffffULL;
}
-#endif
if (cond == 0x0) {
/* unconditional not taken */
if (a) {
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 11/90] target/sparc: Move CALL to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (9 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 10/90] target/sparc: Define AM_CHECK for sparc32 Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 12/90] target/sparc: Move BPcc and Bicc " Richard Henderson
` (79 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 1 +
target/sparc/translate.c | 33 ++++++++++++++++-----------------
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 5811a679db..a5f5d2681e 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -3,3 +3,4 @@
# Sparc instruction decode definitions.
# Copyright (c) 2023 Richard Henderson <rth@twiddle.net>
+CALL 01 i:s30
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 9eb2b7e52f..377f133595 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -3041,6 +3041,20 @@ static bool advance_pc(DisasContext *dc)
return true;
}
+static bool trans_CALL(DisasContext *dc, arg_CALL *a)
+{
+ target_long target = dc->pc + a->i * 4;
+
+ gen_store_gpr(dc, 15, tcg_constant_tl(dc->pc));
+ gen_mov_pc_npc(dc);
+
+ if (unlikely(AM_CHECK(dc))) {
+ target &= 0xffffffffULL;
+ }
+ dc->npc = target;
+ return true;
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -3146,23 +3160,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
break;
}
break;
- case 1: /*CALL*/
- {
- target_long target = GET_FIELDs(insn, 2, 31) << 2;
- TCGv o7 = gen_dest_gpr(dc, 15);
-
- tcg_gen_movi_tl(o7, dc->pc);
- gen_store_gpr(dc, 15, o7);
- target += dc->pc;
- gen_mov_pc_npc(dc);
-#ifdef TARGET_SPARC64
- if (unlikely(AM_CHECK(dc))) {
- target &= 0xffffffffULL;
- }
-#endif
- dc->npc = target;
- }
- goto jmp_insn;
+ case 1:
+ g_assert_not_reached(); /* in decodetree */
case 2: /* FPU & Logical Operations */
{
unsigned int xop = GET_FIELD(insn, 7, 12);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 12/90] target/sparc: Move BPcc and Bicc to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (10 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 11/90] target/sparc: Move CALL to decodetree Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 13/90] target/sparc: Move BPr " Richard Henderson
` (78 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 ++
target/sparc/translate.c | 120 +++++++++++++++++++-------------------
2 files changed, 64 insertions(+), 60 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index a5f5d2681e..15cd975f4e 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -3,4 +3,8 @@
# Sparc instruction decode definitions.
# Copyright (c) 2023 Richard Henderson <rth@twiddle.net>
+&bcc i a cond cc
+BPcc 00 a:1 cond:4 001 cc:1 0 - i:s19 &bcc
+Bicc 00 a:1 cond:4 010 i:s22 &bcc cc=0
+
CALL 01 i:s30
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 377f133595..7e14070322 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1362,44 +1362,6 @@ static void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
}
#endif
-static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
-{
- unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
- target_ulong target = dc->pc + offset;
-
- if (unlikely(AM_CHECK(dc))) {
- target &= 0xffffffffULL;
- }
- if (cond == 0x0) {
- /* unconditional not taken */
- if (a) {
- dc->pc = dc->npc + 4;
- dc->npc = dc->pc + 4;
- } else {
- dc->pc = dc->npc;
- dc->npc = dc->pc + 4;
- }
- } else if (cond == 0x8) {
- /* unconditional taken */
- if (a) {
- dc->pc = target;
- dc->npc = dc->pc + 4;
- } else {
- dc->pc = dc->npc;
- dc->npc = target;
- tcg_gen_mov_tl(cpu_pc, cpu_npc);
- }
- } else {
- flush_cond(dc);
- gen_cond(cpu_cond, cc, cond, dc);
- if (a) {
- gen_branch_a(dc, target);
- } else {
- gen_branch_n(dc, target);
- }
- }
-}
-
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
{
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
@@ -3041,6 +3003,64 @@ static bool advance_pc(DisasContext *dc)
return true;
}
+static bool advance_jump_uncond_never(DisasContext *dc, bool annul)
+{
+ if (annul) {
+ dc->pc = dc->npc + 4;
+ dc->npc = dc->pc + 4;
+ } else {
+ dc->pc = dc->npc;
+ dc->npc = dc->pc + 4;
+ }
+ return true;
+}
+
+static bool advance_jump_uncond_always(DisasContext *dc, bool annul,
+ target_ulong dest)
+{
+ if (annul) {
+ dc->pc = dest;
+ dc->npc = dest + 4;
+ } else {
+ dc->pc = dc->npc;
+ dc->npc = dest;
+ tcg_gen_mov_tl(cpu_pc, cpu_npc);
+ }
+ return true;
+}
+
+static bool advance_jump_cond(DisasContext *dc, bool annul, target_ulong dest)
+{
+ if (annul) {
+ gen_branch_a(dc, dest);
+ } else {
+ gen_branch_n(dc, dest);
+ }
+ return true;
+}
+
+static bool do_bpcc(DisasContext *dc, arg_bcc *a)
+{
+ target_long target = dc->pc + a->i * 4;
+
+ if (unlikely(AM_CHECK(dc))) {
+ target &= 0xffffffffULL;
+ }
+ switch (a->cond) {
+ case 0x0:
+ return advance_jump_uncond_never(dc, a->a);
+ case 0x8:
+ return advance_jump_uncond_always(dc, a->a, target);
+ default:
+ flush_cond(dc);
+ gen_cond(cpu_cond, a->cc, a->cond, dc);
+ return advance_jump_cond(dc, a->a, target);
+ }
+}
+
+TRANS(BPcc, 64, do_bpcc, a)
+TRANS(Bicc, ALL, do_bpcc, a)
+
static bool trans_CALL(DisasContext *dc, arg_CALL *a)
{
target_long target = dc->pc + a->i * 4;
@@ -3082,21 +3102,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
switch (xop) {
#ifdef TARGET_SPARC64
case 0x1: /* V9 BPcc */
- {
- int cc;
-
- target = GET_FIELD_SP(insn, 0, 18);
- target = sign_extend(target, 19);
- target <<= 2;
- cc = GET_FIELD_SP(insn, 20, 21);
- if (cc == 0)
- do_branch(dc, target, insn, 0);
- else if (cc == 2)
- do_branch(dc, target, insn, 1);
- else
- goto illegal_insn;
- goto jmp_insn;
- }
+ g_assert_not_reached(); /* in decodetree */
case 0x3: /* V9 BPr */
{
target = GET_FIELD_SP(insn, 0, 13) |
@@ -3126,13 +3132,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
}
#endif
case 0x2: /* BN+x */
- {
- target = GET_FIELD(insn, 10, 31);
- target = sign_extend(target, 22);
- target <<= 2;
- do_branch(dc, target, insn, 0);
- goto jmp_insn;
- }
+ g_assert_not_reached(); /* in decodetree */
case 0x6: /* FBN+x */
{
if (gen_trap_ifnofpu(dc)) {
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 13/90] target/sparc: Move BPr to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (11 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 12/90] target/sparc: Move BPcc and Bicc " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 14/90] target/sparc: Move FBPfcc and FBfcc " Richard Henderson
` (77 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 3 ++
target/sparc/translate.c | 70 ++++++++++++++++-----------------------
2 files changed, 32 insertions(+), 41 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 15cd975f4e..838f4cdb1d 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -7,4 +7,7 @@
BPcc 00 a:1 cond:4 001 cc:1 0 - i:s19 &bcc
Bicc 00 a:1 cond:4 010 i:s22 &bcc cc=0
+%d16 20:s2 0:14
+BPr 00 a:1 0 cond:3 011 .. - rs1:5 .............. i=%d16
+
CALL 01 i:s30
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 7e14070322..a3c86b22d1 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1331,14 +1331,13 @@ static void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
}
}
-#ifdef TARGET_SPARC64
// Inverted logic
-static const int gen_tcg_cond_reg[8] = {
- -1,
+static const TCGCond gen_tcg_cond_reg[8] = {
+ TCG_COND_NEVER, /* reserved */
TCG_COND_NE,
TCG_COND_GT,
TCG_COND_GE,
- -1,
+ TCG_COND_NEVER, /* reserved */
TCG_COND_EQ,
TCG_COND_LE,
TCG_COND_LT,
@@ -1352,16 +1351,6 @@ static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
cmp->c2 = tcg_constant_tl(0);
}
-static void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
-{
- DisasCompare cmp;
- gen_compare_reg(&cmp, cond, r_src);
-
- /* The interface is to return a boolean in r_dst. */
- tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
-}
-#endif
-
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
{
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
@@ -1401,24 +1390,6 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
}
#ifdef TARGET_SPARC64
-static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
- TCGv r_reg)
-{
- unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
- target_ulong target = dc->pc + offset;
-
- if (unlikely(AM_CHECK(dc))) {
- target &= 0xffffffffULL;
- }
- flush_cond(dc);
- gen_cond_reg(cpu_cond, cond, r_reg);
- if (a) {
- gen_branch_a(dc, target);
- } else {
- gen_branch_n(dc, target);
- }
-}
-
static void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
{
switch (fccno) {
@@ -3061,6 +3032,31 @@ static bool do_bpcc(DisasContext *dc, arg_bcc *a)
TRANS(BPcc, 64, do_bpcc, a)
TRANS(Bicc, ALL, do_bpcc, a)
+static bool trans_BPr(DisasContext *dc, arg_BPr *a)
+{
+ target_long target;
+ DisasCompare cmp;
+
+ if (!avail_64(dc)) {
+ return false;
+ }
+ if (gen_tcg_cond_reg[a->cond] == TCG_COND_NEVER) {
+ return false;
+ }
+
+ target = dc->pc + a->i * 4;
+ if (unlikely(AM_CHECK(dc))) {
+ target &= 0xffffffffULL;
+ }
+
+ flush_cond(dc);
+
+ gen_compare_reg(&cmp, a->cond, gen_load_gpr(dc, a->rs1));
+ tcg_gen_setcond_tl(cmp.cond, cpu_cond, cmp.c1, cmp.c2);
+
+ return advance_jump_cond(dc, a->a, target);
+}
+
static bool trans_CALL(DisasContext *dc, arg_CALL *a)
{
target_long target = dc->pc + a->i * 4;
@@ -3104,15 +3100,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x1: /* V9 BPcc */
g_assert_not_reached(); /* in decodetree */
case 0x3: /* V9 BPr */
- {
- target = GET_FIELD_SP(insn, 0, 13) |
- (GET_FIELD_SP(insn, 20, 21) << 14);
- target = sign_extend(target, 16);
- target <<= 2;
- cpu_src1 = get_src1(dc, insn);
- do_branch_reg(dc, target, insn, cpu_src1);
- goto jmp_insn;
- }
+ g_assert_not_reached(); /* in decodetree */
case 0x5: /* V9 FBPcc */
{
int cc = GET_FIELD_SP(insn, 20, 21);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 14/90] target/sparc: Move FBPfcc and FBfcc to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (12 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 13/90] target/sparc: Move BPr " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 15/90] target/sparc: Merge gen_cond with only caller Richard Henderson
` (76 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 ++
target/sparc/translate.c | 105 +++++++++++++++-----------------------
2 files changed, 46 insertions(+), 63 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 838f4cdb1d..9ab3f2eb82 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -6,8 +6,12 @@
&bcc i a cond cc
BPcc 00 a:1 cond:4 001 cc:1 0 - i:s19 &bcc
Bicc 00 a:1 cond:4 010 i:s22 &bcc cc=0
+FBPfcc 00 a:1 cond:4 101 cc:2 - i:s19 &bcc
+FBfcc 00 a:1 cond:4 110 i:s22 &bcc cc=0
%d16 20:s2 0:14
BPr 00 a:1 0 cond:3 011 .. - rs1:5 .............. i=%d16
+NCP 00 - ---- 111 ---------------------- # CBcc
+
CALL 01 i:s30
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index a3c86b22d1..a05cb59cd6 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1351,44 +1351,6 @@ static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
cmp->c2 = tcg_constant_tl(0);
}
-static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
-{
- unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
- target_ulong target = dc->pc + offset;
-
- if (unlikely(AM_CHECK(dc))) {
- target &= 0xffffffffULL;
- }
- if (cond == 0x0) {
- /* unconditional not taken */
- if (a) {
- dc->pc = dc->npc + 4;
- dc->npc = dc->pc + 4;
- } else {
- dc->pc = dc->npc;
- dc->npc = dc->pc + 4;
- }
- } else if (cond == 0x8) {
- /* unconditional taken */
- if (a) {
- dc->pc = target;
- dc->npc = dc->pc + 4;
- } else {
- dc->pc = dc->npc;
- dc->npc = target;
- tcg_gen_mov_tl(cpu_pc, cpu_npc);
- }
- } else {
- flush_cond(dc);
- gen_fcond(cpu_cond, cc, cond);
- if (a) {
- gen_branch_a(dc, target);
- } else {
- gen_branch_n(dc, target);
- }
- }
-}
-
#ifdef TARGET_SPARC64
static void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
{
@@ -3032,6 +2994,31 @@ static bool do_bpcc(DisasContext *dc, arg_bcc *a)
TRANS(BPcc, 64, do_bpcc, a)
TRANS(Bicc, ALL, do_bpcc, a)
+static bool do_fbpfcc(DisasContext *dc, arg_bcc *a)
+{
+ target_long target = dc->pc + a->i * 4;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if (unlikely(AM_CHECK(dc))) {
+ target &= 0xffffffffULL;
+ }
+ switch (a->cond) {
+ case 0x0:
+ return advance_jump_uncond_never(dc, a->a);
+ case 0x8:
+ return advance_jump_uncond_always(dc, a->a, target);
+ default:
+ flush_cond(dc);
+ gen_fcond(cpu_cond, a->cc, a->cond);
+ return advance_jump_cond(dc, a->a, target);
+ }
+}
+
+TRANS(FBPfcc, 64, do_fbpfcc, a)
+TRANS(FBfcc, ALL, do_fbpfcc, a)
+
static bool trans_BPr(DisasContext *dc, arg_BPr *a)
{
target_long target;
@@ -3071,6 +3058,20 @@ static bool trans_CALL(DisasContext *dc, arg_CALL *a)
return true;
}
+static bool trans_NCP(DisasContext *dc, arg_NCP *a)
+{
+ /*
+ * For sparc32, always generate the no-coprocessor exception.
+ * For sparc64, always generate illegal instruction.
+ */
+#ifdef TARGET_SPARC64
+ return false;
+#else
+ gen_exception(dc, TT_NCP_INSN);
+ return true;
+#endif
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -3094,7 +3095,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0: /* branches/sethi */
{
unsigned int xop = GET_FIELD(insn, 7, 9);
- int32_t target;
switch (xop) {
#ifdef TARGET_SPARC64
case 0x1: /* V9 BPcc */
@@ -3102,36 +3102,15 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x3: /* V9 BPr */
g_assert_not_reached(); /* in decodetree */
case 0x5: /* V9 FBPcc */
- {
- int cc = GET_FIELD_SP(insn, 20, 21);
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- target = GET_FIELD_SP(insn, 0, 18);
- target = sign_extend(target, 19);
- target <<= 2;
- do_fbranch(dc, target, insn, cc);
- goto jmp_insn;
- }
+ g_assert_not_reached(); /* in decodetree */
#else
case 0x7: /* CBN+x */
- {
- goto ncp_insn;
- }
+ g_assert_not_reached(); /* in decodetree */
#endif
case 0x2: /* BN+x */
g_assert_not_reached(); /* in decodetree */
case 0x6: /* FBN+x */
- {
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- target = GET_FIELD(insn, 10, 31);
- target = sign_extend(target, 22);
- target <<= 2;
- do_fbranch(dc, target, insn, 0);
- goto jmp_insn;
- }
+ g_assert_not_reached(); /* in decodetree */
case 0x4: /* SETHI */
/* Special-case %g0 because that's the canonical nop. */
if (rd) {
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 15/90] target/sparc: Merge gen_cond with only caller
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (13 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 14/90] target/sparc: Move FBPfcc and FBfcc " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 16/90] target/sparc: Merge gen_fcond " Richard Henderson
` (75 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland, Philippe Mathieu-Daudé
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index a05cb59cd6..61a75b5fab 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1304,20 +1304,6 @@ static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
}
}
-static void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
- DisasContext *dc)
-{
- DisasCompare cmp;
- gen_compare(&cmp, cc, cond, dc);
-
- /* The interface is to return a boolean in r_dst. */
- if (cmp.is_bool) {
- tcg_gen_mov_tl(r_dst, cmp.c1);
- } else {
- tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
- }
-}
-
static void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
{
DisasCompare cmp;
@@ -2975,6 +2961,7 @@ static bool advance_jump_cond(DisasContext *dc, bool annul, target_ulong dest)
static bool do_bpcc(DisasContext *dc, arg_bcc *a)
{
target_long target = dc->pc + a->i * 4;
+ DisasCompare cmp;
if (unlikely(AM_CHECK(dc))) {
target &= 0xffffffffULL;
@@ -2986,7 +2973,13 @@ static bool do_bpcc(DisasContext *dc, arg_bcc *a)
return advance_jump_uncond_always(dc, a->a, target);
default:
flush_cond(dc);
- gen_cond(cpu_cond, a->cc, a->cond, dc);
+
+ gen_compare(&cmp, a->cc, a->cond, dc);
+ if (cmp.is_bool) {
+ tcg_gen_mov_tl(cpu_cond, cmp.c1);
+ } else {
+ tcg_gen_setcond_tl(cmp.cond, cpu_cond, cmp.c1, cmp.c2);
+ }
return advance_jump_cond(dc, a->a, target);
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 16/90] target/sparc: Merge gen_fcond with only caller
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (14 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 15/90] target/sparc: Merge gen_cond with only caller Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 17/90] target/sparc: Merge gen_branch_[an] " Richard Henderson
` (74 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland, Philippe Mathieu-Daudé
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 61a75b5fab..cc19f0606e 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1304,19 +1304,6 @@ static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
}
}
-static void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
-{
- DisasCompare cmp;
- gen_fcompare(&cmp, cc, cond);
-
- /* The interface is to return a boolean in r_dst. */
- if (cmp.is_bool) {
- tcg_gen_mov_tl(r_dst, cmp.c1);
- } else {
- tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
- }
-}
-
// Inverted logic
static const TCGCond gen_tcg_cond_reg[8] = {
TCG_COND_NEVER, /* reserved */
@@ -2990,6 +2977,7 @@ TRANS(Bicc, ALL, do_bpcc, a)
static bool do_fbpfcc(DisasContext *dc, arg_bcc *a)
{
target_long target = dc->pc + a->i * 4;
+ DisasCompare cmp;
if (gen_trap_ifnofpu(dc)) {
return true;
@@ -3004,7 +2992,13 @@ static bool do_fbpfcc(DisasContext *dc, arg_bcc *a)
return advance_jump_uncond_always(dc, a->a, target);
default:
flush_cond(dc);
- gen_fcond(cpu_cond, a->cc, a->cond);
+
+ gen_fcompare(&cmp, a->cc, a->cond);
+ if (cmp.is_bool) {
+ tcg_gen_mov_tl(cpu_cond, cmp.c1);
+ } else {
+ tcg_gen_setcond_tl(cmp.cond, cpu_cond, cmp.c1, cmp.c2);
+ }
return advance_jump_cond(dc, a->a, target);
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 17/90] target/sparc: Merge gen_branch_[an] with only caller
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (15 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 16/90] target/sparc: Merge gen_fcond " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 18/90] target/sparc: Pass DisasCompare to advance_jump_cond Richard Henderson
` (73 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 73 +++++++++++++++++-----------------------
1 file changed, 30 insertions(+), 43 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index cc19f0606e..9188196657 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -895,47 +895,6 @@ static void gen_branch2(DisasContext *dc, target_ulong pc1,
gen_goto_tb(dc, 1, pc2, pc2 + 4);
}
-static void gen_branch_a(DisasContext *dc, target_ulong pc1)
-{
- TCGLabel *l1 = gen_new_label();
- target_ulong npc = dc->npc;
-
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cond, 0, l1);
-
- gen_goto_tb(dc, 0, npc, pc1);
-
- gen_set_label(l1);
- gen_goto_tb(dc, 1, npc + 4, npc + 8);
-
- dc->base.is_jmp = DISAS_NORETURN;
-}
-
-static void gen_branch_n(DisasContext *dc, target_ulong pc1)
-{
- target_ulong npc = dc->npc;
-
- if (npc & 3) {
- switch (npc) {
- case DYNAMIC_PC:
- case DYNAMIC_PC_LOOKUP:
- tcg_gen_mov_tl(cpu_pc, cpu_npc);
- tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
- tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc,
- cpu_cond, tcg_constant_tl(0),
- tcg_constant_tl(pc1), cpu_npc);
- dc->pc = npc;
- break;
- default:
- g_assert_not_reached();
- }
- } else {
- dc->pc = npc;
- dc->jump_pc[0] = pc1;
- dc->jump_pc[1] = npc + 4;
- dc->npc = JUMP_PC;
- }
-}
-
static void gen_generic_branch(DisasContext *dc)
{
TCGv npc0 = tcg_constant_tl(dc->jump_pc[0]);
@@ -2937,10 +2896,38 @@ static bool advance_jump_uncond_always(DisasContext *dc, bool annul,
static bool advance_jump_cond(DisasContext *dc, bool annul, target_ulong dest)
{
+ target_ulong npc = dc->npc;
+
if (annul) {
- gen_branch_a(dc, dest);
+ TCGLabel *l1 = gen_new_label();
+
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cond, 0, l1);
+ gen_goto_tb(dc, 0, npc, dest);
+ gen_set_label(l1);
+ gen_goto_tb(dc, 1, npc + 4, npc + 8);
+
+ dc->base.is_jmp = DISAS_NORETURN;
} else {
- gen_branch_n(dc, dest);
+ if (npc & 3) {
+ switch (npc) {
+ case DYNAMIC_PC:
+ case DYNAMIC_PC_LOOKUP:
+ tcg_gen_mov_tl(cpu_pc, cpu_npc);
+ tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
+ tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc,
+ cpu_cond, tcg_constant_tl(0),
+ tcg_constant_tl(dest), cpu_npc);
+ dc->pc = npc;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ } else {
+ dc->pc = npc;
+ dc->jump_pc[0] = dest;
+ dc->jump_pc[1] = npc + 4;
+ dc->npc = JUMP_PC;
+ }
}
return true;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 18/90] target/sparc: Pass DisasCompare to advance_jump_cond
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (16 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 17/90] target/sparc: Merge gen_branch_[an] " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 19/90] target/sparc: Move SETHI to decodetree Richard Henderson
` (72 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Fold the condition into the branch or movcond when possible.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 32 +++++++++++++-------------------
1 file changed, 13 insertions(+), 19 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 9188196657..70bfbb41e9 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2894,14 +2894,15 @@ static bool advance_jump_uncond_always(DisasContext *dc, bool annul,
return true;
}
-static bool advance_jump_cond(DisasContext *dc, bool annul, target_ulong dest)
+static bool advance_jump_cond(DisasContext *dc, DisasCompare *cmp,
+ bool annul, target_ulong dest)
{
target_ulong npc = dc->npc;
if (annul) {
TCGLabel *l1 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cond, 0, l1);
+ tcg_gen_brcond_tl(tcg_invert_cond(cmp->cond), cmp->c1, cmp->c2, l1);
gen_goto_tb(dc, 0, npc, dest);
gen_set_label(l1);
gen_goto_tb(dc, 1, npc + 4, npc + 8);
@@ -2914,8 +2915,8 @@ static bool advance_jump_cond(DisasContext *dc, bool annul, target_ulong dest)
case DYNAMIC_PC_LOOKUP:
tcg_gen_mov_tl(cpu_pc, cpu_npc);
tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
- tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc,
- cpu_cond, tcg_constant_tl(0),
+ tcg_gen_movcond_tl(cmp->cond, cpu_npc,
+ cmp->c1, cmp->c2,
tcg_constant_tl(dest), cpu_npc);
dc->pc = npc;
break;
@@ -2927,6 +2928,11 @@ static bool advance_jump_cond(DisasContext *dc, bool annul, target_ulong dest)
dc->jump_pc[0] = dest;
dc->jump_pc[1] = npc + 4;
dc->npc = JUMP_PC;
+ if (cmp->is_bool) {
+ tcg_gen_mov_tl(cpu_cond, cmp->c1);
+ } else {
+ tcg_gen_setcond_tl(cmp->cond, cpu_cond, cmp->c1, cmp->c2);
+ }
}
}
return true;
@@ -2949,12 +2955,7 @@ static bool do_bpcc(DisasContext *dc, arg_bcc *a)
flush_cond(dc);
gen_compare(&cmp, a->cc, a->cond, dc);
- if (cmp.is_bool) {
- tcg_gen_mov_tl(cpu_cond, cmp.c1);
- } else {
- tcg_gen_setcond_tl(cmp.cond, cpu_cond, cmp.c1, cmp.c2);
- }
- return advance_jump_cond(dc, a->a, target);
+ return advance_jump_cond(dc, &cmp, a->a, target);
}
}
@@ -2981,12 +2982,7 @@ static bool do_fbpfcc(DisasContext *dc, arg_bcc *a)
flush_cond(dc);
gen_fcompare(&cmp, a->cc, a->cond);
- if (cmp.is_bool) {
- tcg_gen_mov_tl(cpu_cond, cmp.c1);
- } else {
- tcg_gen_setcond_tl(cmp.cond, cpu_cond, cmp.c1, cmp.c2);
- }
- return advance_jump_cond(dc, a->a, target);
+ return advance_jump_cond(dc, &cmp, a->a, target);
}
}
@@ -3013,9 +3009,7 @@ static bool trans_BPr(DisasContext *dc, arg_BPr *a)
flush_cond(dc);
gen_compare_reg(&cmp, a->cond, gen_load_gpr(dc, a->rs1));
- tcg_gen_setcond_tl(cmp.cond, cpu_cond, cmp.c1, cmp.c2);
-
- return advance_jump_cond(dc, a->a, target);
+ return advance_jump_cond(dc, &cmp, a->a, target);
}
static bool trans_CALL(DisasContext *dc, arg_CALL *a)
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 19/90] target/sparc: Move SETHI to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (17 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 18/90] target/sparc: Pass DisasCompare to advance_jump_cond Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 20/90] target/sparc: Move Tcc " Richard Henderson
` (71 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 6 +++++
target/sparc/translate.c | 50 ++++++++++++---------------------------
2 files changed, 21 insertions(+), 35 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 9ab3f2eb82..f6f5401b10 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -3,6 +3,10 @@
# Sparc instruction decode definitions.
# Copyright (c) 2023 Richard Henderson <rth@twiddle.net>
+##
+## Major Opcodes 00 and 01 -- branches, call, and sethi.
+##
+
&bcc i a cond cc
BPcc 00 a:1 cond:4 001 cc:1 0 - i:s19 &bcc
Bicc 00 a:1 cond:4 010 i:s22 &bcc cc=0
@@ -14,4 +18,6 @@ BPr 00 a:1 0 cond:3 011 .. - rs1:5 .............. i=%d16
NCP 00 - ---- 111 ---------------------- # CBcc
+SETHI 00 rd:5 100 i:22
+
CALL 01 i:s30
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 70bfbb41e9..b53127ecb7 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2868,6 +2868,10 @@ static bool advance_pc(DisasContext *dc)
return true;
}
+/*
+ * Major opcodes 00 and 01 -- branches, call, and sethi
+ */
+
static bool advance_jump_uncond_never(DisasContext *dc, bool annul)
{
if (annul) {
@@ -3040,6 +3044,15 @@ static bool trans_NCP(DisasContext *dc, arg_NCP *a)
#endif
}
+static bool trans_SETHI(DisasContext *dc, arg_SETHI *a)
+{
+ /* Special-case %g0 because that's the canonical nop. */
+ if (a->rd) {
+ gen_store_gpr(dc, a->rd, tcg_constant_tl((uint32_t)a->i << 10));
+ }
+ return advance_pc(dc);
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -3060,41 +3073,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
rd = GET_FIELD(insn, 2, 6);
switch (opc) {
- case 0: /* branches/sethi */
- {
- unsigned int xop = GET_FIELD(insn, 7, 9);
- switch (xop) {
-#ifdef TARGET_SPARC64
- case 0x1: /* V9 BPcc */
- g_assert_not_reached(); /* in decodetree */
- case 0x3: /* V9 BPr */
- g_assert_not_reached(); /* in decodetree */
- case 0x5: /* V9 FBPcc */
- g_assert_not_reached(); /* in decodetree */
-#else
- case 0x7: /* CBN+x */
- g_assert_not_reached(); /* in decodetree */
-#endif
- case 0x2: /* BN+x */
- g_assert_not_reached(); /* in decodetree */
- case 0x6: /* FBN+x */
- g_assert_not_reached(); /* in decodetree */
- case 0x4: /* SETHI */
- /* Special-case %g0 because that's the canonical nop. */
- if (rd) {
- uint32_t value = GET_FIELD(insn, 10, 31);
- TCGv t = gen_dest_gpr(dc, rd);
- tcg_gen_movi_tl(t, value << 10);
- gen_store_gpr(dc, rd, t);
- }
- break;
- case 0x0: /* UNIMPL */
- default:
- goto illegal_insn;
- }
- break;
- }
- break;
+ case 0:
+ goto illegal_insn; /* in decodetree */
case 1:
g_assert_not_reached(); /* in decodetree */
case 2: /* FPU & Logical Operations */
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 20/90] target/sparc: Move Tcc to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (18 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 19/90] target/sparc: Move SETHI to decodetree Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 21/90] target/sparc: Move RDASR, STBAR, MEMBAR " Richard Henderson
` (70 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Use the new delay_exceptionv function in the implementation.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 2 +
target/sparc/translate.c | 143 +++++++++++++++++---------------------
2 files changed, 66 insertions(+), 79 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index f6f5401b10..4d09c102f1 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -21,3 +21,5 @@ NCP 00 - ---- 111 ---------------------- # CBcc
SETHI 00 rd:5 100 i:22
CALL 01 i:s30
+
+Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index b53127ecb7..4a4aab81cd 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -3053,6 +3053,69 @@ static bool trans_SETHI(DisasContext *dc, arg_SETHI *a)
return advance_pc(dc);
}
+static bool trans_Tcc(DisasContext *dc, arg_Tcc *a)
+{
+ DisasCompare cmp;
+ TCGLabel *lab;
+ TCGv_i32 trap;
+ int mask;
+
+ /* Reject %xcc for sparc32. */
+ if (avail_32(dc) && a->cc) {
+ return false;
+ }
+
+ /* For simplicity, we underdecoded the rs2/imm7 field. */
+ if (!a->imm && (a->rs2_or_imm & ~0x1f)) {
+ return false;
+ }
+
+ /* Trap never. */
+ if (a->cond == 0) {
+ return advance_pc(dc);
+ }
+
+ mask = ((dc->def->features & CPU_FEATURE_HYPV) && supervisor(dc)
+ ? UA2005_HTRAP_MASK : V8_TRAP_MASK);
+
+ if (a->rs2_or_imm == 0) {
+ a->imm = true;
+ }
+ if (a->rs1 == 0 && a->imm) {
+ trap = tcg_constant_i32((a->rs2_or_imm & mask) + TT_TRAP);
+ } else {
+ TCGv src1 = gen_load_gpr(dc, a->rs1);
+ TCGv sum = tcg_temp_new();
+
+ if (a->imm) {
+ tcg_gen_addi_tl(sum, src1, a->rs2_or_imm);
+ } else {
+ tcg_gen_add_tl(sum, src1, gen_load_gpr(dc, a->rs2_or_imm));
+ }
+
+ trap = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(trap, sum);
+ tcg_gen_andi_i32(trap, trap, mask);
+ tcg_gen_addi_i32(trap, trap, TT_TRAP);
+ }
+
+ /* Trap always. */
+ if (a->cond == 8) {
+ save_state(dc);
+ gen_helper_raise_exception(tcg_env, trap);
+ dc->base.is_jmp = DISAS_NORETURN;
+ return true;
+ }
+
+ /* Conditional trap. */
+ flush_cond(dc);
+ lab = delay_exceptionv(dc, trap);
+ gen_compare(&cmp, a->cc, a->cond, dc);
+ tcg_gen_brcond_tl(cmp.cond, cmp.c1, cmp.c2, lab);
+
+ return advance_pc(dc);
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -3083,85 +3146,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv cpu_dst = tcg_temp_new();
TCGv cpu_tmp0;
- if (xop == 0x3a) { /* generate trap */
- int cond = GET_FIELD(insn, 3, 6);
- TCGv_i32 trap;
- TCGLabel *l1 = NULL;
- int mask;
-
- if (cond == 0) {
- /* Trap never. */
- break;
- }
-
- save_state(dc);
-
- if (cond != 8) {
- /* Conditional trap. */
- DisasCompare cmp;
-#ifdef TARGET_SPARC64
- /* V9 icc/xcc */
- int cc = GET_FIELD_SP(insn, 11, 12);
- if (cc == 0) {
- gen_compare(&cmp, 0, cond, dc);
- } else if (cc == 2) {
- gen_compare(&cmp, 1, cond, dc);
- } else {
- goto illegal_insn;
- }
-#else
- gen_compare(&cmp, 0, cond, dc);
-#endif
- l1 = gen_new_label();
- tcg_gen_brcond_tl(tcg_invert_cond(cmp.cond),
- cmp.c1, cmp.c2, l1);
- }
-
- mask = ((dc->def->features & CPU_FEATURE_HYPV) && supervisor(dc)
- ? UA2005_HTRAP_MASK : V8_TRAP_MASK);
-
- /* Don't use the normal temporaries, as they may well have
- gone out of scope with the branch above. While we're
- doing that we might as well pre-truncate to 32-bit. */
- trap = tcg_temp_new_i32();
-
- rs1 = GET_FIELD_SP(insn, 14, 18);
- if (IS_IMM) {
- rs2 = GET_FIELD_SP(insn, 0, 7);
- if (rs1 == 0) {
- tcg_gen_movi_i32(trap, (rs2 & mask) + TT_TRAP);
- /* Signal that the trap value is fully constant. */
- mask = 0;
- } else {
- TCGv t1 = gen_load_gpr(dc, rs1);
- tcg_gen_trunc_tl_i32(trap, t1);
- tcg_gen_addi_i32(trap, trap, rs2);
- }
- } else {
- TCGv t1, t2;
- rs2 = GET_FIELD_SP(insn, 0, 4);
- t1 = gen_load_gpr(dc, rs1);
- t2 = gen_load_gpr(dc, rs2);
- tcg_gen_add_tl(t1, t1, t2);
- tcg_gen_trunc_tl_i32(trap, t1);
- }
- if (mask != 0) {
- tcg_gen_andi_i32(trap, trap, mask);
- tcg_gen_addi_i32(trap, trap, TT_TRAP);
- }
-
- gen_helper_raise_exception(tcg_env, trap);
-
- if (cond == 8) {
- /* An unconditional trap ends the TB. */
- dc->base.is_jmp = DISAS_NORETURN;
- goto jmp_insn;
- } else {
- /* A conditional trap falls through to the next insn. */
- gen_set_label(l1);
- break;
- }
- } else if (xop == 0x28) {
+ if (xop == 0x28) {
rs1 = GET_FIELD(insn, 13, 17);
switch(rs1) {
case 0: /* rdy */
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 21/90] target/sparc: Move RDASR, STBAR, MEMBAR to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (19 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 20/90] target/sparc: Move Tcc " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 22/90] target/sparc: Move RDPSR, RDHPR " Richard Henderson
` (69 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 22 +++
target/sparc/translate.c | 360 ++++++++++++++++++++++++--------------
2 files changed, 253 insertions(+), 129 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 4d09c102f1..b3291ea771 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -23,3 +23,25 @@ SETHI 00 rd:5 100 i:22
CALL 01 i:s30
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
+
+{
+ [
+ STBAR 10 00000 101000 01111 0 0000000000000
+ MEMBAR 10 00000 101000 01111 1 000000 cmask:3 mmask:4
+
+ RDCCR 10 rd:5 101000 00010 0 0000000000000
+ RDASI 10 rd:5 101000 00011 0 0000000000000
+ RDTICK 10 rd:5 101000 00100 0 0000000000000
+ RDPC 10 rd:5 101000 00101 0 0000000000000
+ RDFPRS 10 rd:5 101000 00110 0 0000000000000
+ RDASR17 10 rd:5 101000 10001 0 0000000000000
+ RDGSR 10 rd:5 101000 10011 0 0000000000000
+ RDSOFTINT 10 rd:5 101000 10110 0 0000000000000
+ RDTICK_CMPR 10 rd:5 101000 10111 0 0000000000000
+ RDSTICK 10 rd:5 101000 11000 0 0000000000000
+ RDSTICK_CMPR 10 rd:5 101000 11001 0 0000000000000
+ RDSTRAND_STATUS 10 rd:5 101000 11010 0 0000000000000
+ ]
+ # Before v8, all rs1 accepted; otherwise rs1==0.
+ RDY 10 rd:5 101000 rs1:5 0 0000000000000
+}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 4a4aab81cd..0fd454c635 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -36,6 +36,10 @@
#include "exec/helper-info.c.inc"
#undef HELPER_H
+#ifndef TARGET_SPARC64
+#define gen_helper_rdccr(D, E) qemu_build_not_reached()
+#endif
+
/* Dynamic PC, must exit to main loop. */
#define DYNAMIC_PC 1
/* Dynamic PC, one of two values according to jump_pc[T2]. */
@@ -2842,6 +2846,8 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
# define avail_32(C) true
# define avail_64(C) false
#endif
+#define avail_ASR17(C) ((C)->def->features & CPU_FEATURE_ASR17)
+#define avail_HYPV(C) ((C)->def->features & CPU_FEATURE_HYPV)
/* Default case for non jump instructions. */
static bool advance_pc(DisasContext *dc)
@@ -2942,6 +2948,12 @@ static bool advance_jump_cond(DisasContext *dc, DisasCompare *cmp,
return true;
}
+static bool raise_priv(DisasContext *dc)
+{
+ gen_exception(dc, TT_PRIV_INSN);
+ return true;
+}
+
static bool do_bpcc(DisasContext *dc, arg_bcc *a)
{
target_long target = dc->pc + a->i * 4;
@@ -3116,6 +3128,215 @@ static bool trans_Tcc(DisasContext *dc, arg_Tcc *a)
return advance_pc(dc);
}
+static bool trans_STBAR(DisasContext *dc, arg_STBAR *a)
+{
+ tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
+ return advance_pc(dc);
+}
+
+static bool trans_MEMBAR(DisasContext *dc, arg_MEMBAR *a)
+{
+ if (avail_32(dc)) {
+ return false;
+ }
+ if (a->mmask) {
+ /* Note TCG_MO_* was modeled on sparc64, so mmask matches. */
+ tcg_gen_mb(a->mmask | TCG_BAR_SC);
+ }
+ if (a->cmask) {
+ /* For #Sync, etc, end the TB to recognize interrupts. */
+ dc->base.is_jmp = DISAS_EXIT;
+ }
+ return advance_pc(dc);
+}
+
+static bool do_rd_special(DisasContext *dc, bool priv, int rd,
+ TCGv (*func)(DisasContext *, TCGv))
+{
+ if (!priv) {
+ return raise_priv(dc);
+ }
+ gen_store_gpr(dc, rd, func(dc, gen_dest_gpr(dc, rd)));
+ return advance_pc(dc);
+}
+
+static TCGv do_rdy(DisasContext *dc, TCGv dst)
+{
+ return cpu_y;
+}
+
+static bool trans_RDY(DisasContext *dc, arg_RDY *a)
+{
+ /*
+ * TODO: Need a feature bit for sparcv8. In the meantime, treat all
+ * 32-bit cpus like sparcv7, which ignores the rs1 field.
+ * This matches after all other ASR, so Leon3 Asr17 is handled first.
+ */
+ if (avail_64(dc) && a->rs1 != 0) {
+ return false;
+ }
+ return do_rd_special(dc, true, a->rd, do_rdy);
+}
+
+static TCGv do_rd_leon3_config(DisasContext *dc, TCGv dst)
+{
+ uint32_t val;
+
+ /*
+ * TODO: There are many more fields to be filled,
+ * some of which are writable.
+ */
+ val = dc->def->nwindows - 1; /* [4:0] NWIN */
+ val |= 1 << 8; /* [8] V8 */
+
+ return tcg_constant_tl(val);
+}
+
+TRANS(RDASR17, ASR17, do_rd_special, true, a->rd, do_rd_leon3_config)
+
+static TCGv do_rdccr(DisasContext *dc, TCGv dst)
+{
+ update_psr(dc);
+ gen_helper_rdccr(dst, tcg_env);
+ return dst;
+}
+
+TRANS(RDCCR, 64, do_rd_special, true, a->rd, do_rdccr)
+
+static TCGv do_rdasi(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return tcg_constant_tl(dc->asi);
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDASI, 64, do_rd_special, true, a->rd, do_rdasi)
+
+static TCGv do_rdtick(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tickptr = tcg_temp_new_ptr();
+ TCGv_i32 r_const = tcg_constant_i32(dc->mem_idx);
+
+ tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, tick));
+ if (translator_io_start(&dc->base)) {
+ dc->base.is_jmp = DISAS_EXIT;
+ }
+ gen_helper_tick_get_count(dst, tcg_env, r_tickptr, r_const);
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+/* TODO: non-priv access only allowed when enabled. */
+TRANS(RDTICK, 64, do_rd_special, true, a->rd, do_rdtick)
+
+static TCGv do_rdpc(DisasContext *dc, TCGv dst)
+{
+ target_ulong val = dc->pc;
+ if (AM_CHECK(dc)) {
+ val &= 0xffffffffULL;
+ }
+ return tcg_constant_tl(val);
+}
+
+TRANS(RDPC, 64, do_rd_special, true, a->rd, do_rdpc)
+
+static TCGv do_rdfprs(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ext_i32_tl(dst, cpu_fprs);
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDFPRS, 64, do_rd_special, true, a->rd, do_rdfprs)
+
+static TCGv do_rdgsr(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ gen_trap_ifnofpu(dc);
+ return cpu_gsr;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDGSR, 64, do_rd_special, true, a->rd, do_rdgsr)
+
+static TCGv do_rdsoftint(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld32s_tl(dst, tcg_env, offsetof(CPUSPARCState, softint));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDSOFTINT, 64, do_rd_special, supervisor(dc), a->rd, do_rdsoftint)
+
+static TCGv do_rdtick_cmpr(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_tick_cmpr;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+/* TODO: non-priv access only allowed when enabled. */
+TRANS(RDTICK_CMPR, 64, do_rd_special, true, a->rd, do_rdtick_cmpr)
+
+static TCGv do_rdstick(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tickptr = tcg_temp_new_ptr();
+ TCGv_i32 r_const = tcg_constant_i32(dc->mem_idx);
+
+ tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, stick));
+ if (translator_io_start(&dc->base)) {
+ dc->base.is_jmp = DISAS_EXIT;
+ }
+ gen_helper_tick_get_count(dst, tcg_env, r_tickptr, r_const);
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+/* TODO: non-priv access only allowed when enabled. */
+TRANS(RDSTICK, 64, do_rd_special, true, a->rd, do_rdstick)
+
+static TCGv do_rdstick_cmpr(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_stick_cmpr;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+/* TODO: supervisor access only allowed when enabled by hypervisor. */
+TRANS(RDSTICK_CMPR, 64, do_rd_special, supervisor(dc), a->rd, do_rdstick_cmpr)
+
+/*
+ * UltraSPARC-T1 Strand status.
+ * HYPV check maybe not enough, UA2005 & UA2007 describe
+ * this ASR as impl. dep
+ */
+static TCGv do_rdstrand_status(DisasContext *dc, TCGv dst)
+{
+ return tcg_constant_tl(1);
+}
+
+TRANS(RDSTRAND_STATUS, HYPV, do_rd_special, true, a->rd, do_rdstrand_status)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -3142,134 +3363,12 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
g_assert_not_reached(); /* in decodetree */
case 2: /* FPU & Logical Operations */
{
- unsigned int xop = GET_FIELD(insn, 7, 12);
- TCGv cpu_dst = tcg_temp_new();
- TCGv cpu_tmp0;
+ unsigned int xop __attribute__((unused)) = GET_FIELD(insn, 7, 12);
+ TCGv cpu_dst __attribute__((unused)) = tcg_temp_new();
+ TCGv cpu_tmp0 __attribute__((unused));
- if (xop == 0x28) {
- rs1 = GET_FIELD(insn, 13, 17);
- switch(rs1) {
- case 0: /* rdy */
-#ifndef TARGET_SPARC64
- case 0x01 ... 0x0e: /* undefined in the SPARCv8
- manual, rdy on the microSPARC
- II */
- case 0x0f: /* stbar in the SPARCv8 manual,
- rdy on the microSPARC II */
- case 0x10 ... 0x1f: /* implementation-dependent in the
- SPARCv8 manual, rdy on the
- microSPARC II */
- /* Read Asr17 */
- if (rs1 == 0x11 && dc->def->features & CPU_FEATURE_ASR17) {
- TCGv t = gen_dest_gpr(dc, rd);
- /* Read Asr17 for a Leon3 monoprocessor */
- tcg_gen_movi_tl(t, (1 << 8) | (dc->def->nwindows - 1));
- gen_store_gpr(dc, rd, t);
- break;
- }
-#endif
- gen_store_gpr(dc, rd, cpu_y);
- break;
-#ifdef TARGET_SPARC64
- case 0x2: /* V9 rdccr */
- update_psr(dc);
- gen_helper_rdccr(cpu_dst, tcg_env);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
- case 0x3: /* V9 rdasi */
- tcg_gen_movi_tl(cpu_dst, dc->asi);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
- case 0x4: /* V9 rdtick */
- {
- TCGv_ptr r_tickptr;
- TCGv_i32 r_const;
-
- r_tickptr = tcg_temp_new_ptr();
- r_const = tcg_constant_i32(dc->mem_idx);
- tcg_gen_ld_ptr(r_tickptr, tcg_env,
- offsetof(CPUSPARCState, tick));
- if (translator_io_start(&dc->base)) {
- dc->base.is_jmp = DISAS_EXIT;
- }
- gen_helper_tick_get_count(cpu_dst, tcg_env, r_tickptr,
- r_const);
- gen_store_gpr(dc, rd, cpu_dst);
- }
- break;
- case 0x5: /* V9 rdpc */
- {
- TCGv t = gen_dest_gpr(dc, rd);
- if (unlikely(AM_CHECK(dc))) {
- tcg_gen_movi_tl(t, dc->pc & 0xffffffffULL);
- } else {
- tcg_gen_movi_tl(t, dc->pc);
- }
- gen_store_gpr(dc, rd, t);
- }
- break;
- case 0x6: /* V9 rdfprs */
- tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
- case 0xf: /* V9 membar */
- break; /* no effect */
- case 0x13: /* Graphics Status */
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- gen_store_gpr(dc, rd, cpu_gsr);
- break;
- case 0x16: /* Softint */
- tcg_gen_ld32s_tl(cpu_dst, tcg_env,
- offsetof(CPUSPARCState, softint));
- gen_store_gpr(dc, rd, cpu_dst);
- break;
- case 0x17: /* Tick compare */
- gen_store_gpr(dc, rd, cpu_tick_cmpr);
- break;
- case 0x18: /* System tick */
- {
- TCGv_ptr r_tickptr;
- TCGv_i32 r_const;
-
- r_tickptr = tcg_temp_new_ptr();
- r_const = tcg_constant_i32(dc->mem_idx);
- tcg_gen_ld_ptr(r_tickptr, tcg_env,
- offsetof(CPUSPARCState, stick));
- if (translator_io_start(&dc->base)) {
- dc->base.is_jmp = DISAS_EXIT;
- }
- gen_helper_tick_get_count(cpu_dst, tcg_env, r_tickptr,
- r_const);
- gen_store_gpr(dc, rd, cpu_dst);
- }
- break;
- case 0x19: /* System tick compare */
- gen_store_gpr(dc, rd, cpu_stick_cmpr);
- break;
- case 0x1a: /* UltraSPARC-T1 Strand status */
- /* XXX HYPV check maybe not enough, UA2005 & UA2007 describe
- * this ASR as impl. dep
- */
- CHECK_IU_FEATURE(dc, HYPV);
- {
- TCGv t = gen_dest_gpr(dc, rd);
- tcg_gen_movi_tl(t, 1UL);
- gen_store_gpr(dc, rd, t);
- }
- break;
- case 0x10: /* Performance Control */
- case 0x11: /* Performance Instrumentation Counter */
- case 0x12: /* Dispatch Control */
- case 0x14: /* Softint set, WO */
- case 0x15: /* Softint clear, WO */
-#endif
- default:
- goto illegal_insn;
- }
#if !defined(CONFIG_USER_ONLY)
- } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
+ if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
#ifndef TARGET_SPARC64
if (!supervisor(dc)) {
goto priv_insn;
@@ -3307,7 +3406,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
#endif
gen_store_gpr(dc, rd, cpu_dst);
break;
- } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
+ }
+ if (xop == 0x2a) { /* rdwim / V9 rdpr */
if (!supervisor(dc)) {
goto priv_insn;
}
@@ -3431,9 +3531,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
#endif
gen_store_gpr(dc, rd, cpu_tmp0);
break;
+ }
#endif
#if defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)
- } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
+ if (xop == 0x2b) { /* rdtbr / V9 flushw */
#ifdef TARGET_SPARC64
gen_helper_flushw(tcg_env);
#else
@@ -3442,8 +3543,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
gen_store_gpr(dc, rd, cpu_tbr);
#endif
break;
+ }
#endif
- } else if (xop == 0x34) { /* FPU Operations */
+ if (xop == 0x34) { /* FPU Operations */
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 22/90] target/sparc: Move RDPSR, RDHPR to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (20 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 21/90] target/sparc: Move RDASR, STBAR, MEMBAR " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 23/90] target/sparc: Move RDWIM, RDPR " Richard Henderson
` (68 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 10 ++++
target/sparc/translate.c | 112 ++++++++++++++++++++++++--------------
2 files changed, 80 insertions(+), 42 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index b3291ea771..8b05b9d8f1 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -45,3 +45,13 @@ Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
# Before v8, all rs1 accepted; otherwise rs1==0.
RDY 10 rd:5 101000 rs1:5 0 0000000000000
}
+
+{
+ RDPSR 10 rd:5 101001 00000 0 0000000000000
+ RDHPR_hpstate 10 rd:5 101001 00000 0 0000000000000
+}
+# RDHPR_tstate
+RDHPR_hintp 10 rd:5 101001 00011 0 0000000000000
+RDHPR_htba 10 rd:5 101001 00101 0 0000000000000
+RDHPR_hver 10 rd:5 101001 00110 0 0000000000000
+RDHPR_hstick_cmpr 10 rd:5 101001 11111 0 0000000000000
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 0fd454c635..cdfe353596 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -36,7 +36,9 @@
#include "exec/helper-info.c.inc"
#undef HELPER_H
-#ifndef TARGET_SPARC64
+#ifdef TARGET_SPARC64
+#define gen_helper_rdpsr(D, E) qemu_build_not_reached()
+#else
#define gen_helper_rdccr(D, E) qemu_build_not_reached()
#endif
@@ -260,15 +262,14 @@ static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
/* moves */
#ifdef CONFIG_USER_ONLY
#define supervisor(dc) 0
-#ifdef TARGET_SPARC64
#define hypervisor(dc) 0
-#endif
#else
#ifdef TARGET_SPARC64
#define hypervisor(dc) (dc->hypervisor)
#define supervisor(dc) (dc->supervisor | dc->hypervisor)
#else
#define supervisor(dc) (dc->supervisor)
+#define hypervisor(dc) 0
#endif
#endif
@@ -3337,6 +3338,72 @@ static TCGv do_rdstrand_status(DisasContext *dc, TCGv dst)
TRANS(RDSTRAND_STATUS, HYPV, do_rd_special, true, a->rd, do_rdstrand_status)
+static TCGv do_rdpsr(DisasContext *dc, TCGv dst)
+{
+ update_psr(dc);
+ gen_helper_rdpsr(dst, tcg_env);
+ return dst;
+}
+
+TRANS(RDPSR, 32, do_rd_special, supervisor(dc), a->rd, do_rdpsr)
+
+static TCGv do_rdhpstate(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld_i64(dst, tcg_env, offsetof(CPUSPARCState, hpstate));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_hpstate, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhpstate)
+
+static TCGv do_rdhintp(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_hintp;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_hintp, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhintp)
+
+static TCGv do_rdhtba(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_htba;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_htba, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhtba)
+
+static TCGv do_rdhver(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_hver;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_hver, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhver)
+
+static TCGv do_rdhstick_cmpr(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_hstick_cmpr;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_hstick_cmpr, HYPV, do_rd_special, hypervisor(dc), a->rd,
+ do_rdhstick_cmpr)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -3368,45 +3435,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv cpu_tmp0 __attribute__((unused));
#if !defined(CONFIG_USER_ONLY)
- if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
-#ifndef TARGET_SPARC64
- if (!supervisor(dc)) {
- goto priv_insn;
- }
- update_psr(dc);
- gen_helper_rdpsr(cpu_dst, tcg_env);
-#else
- CHECK_IU_FEATURE(dc, HYPV);
- if (!hypervisor(dc))
- goto priv_insn;
- rs1 = GET_FIELD(insn, 13, 17);
- switch (rs1) {
- case 0: // hpstate
- tcg_gen_ld_i64(cpu_dst, tcg_env,
- offsetof(CPUSPARCState, hpstate));
- break;
- case 1: // htstate
- // gen_op_rdhtstate();
- break;
- case 3: // hintp
- tcg_gen_mov_tl(cpu_dst, cpu_hintp);
- break;
- case 5: // htba
- tcg_gen_mov_tl(cpu_dst, cpu_htba);
- break;
- case 6: // hver
- tcg_gen_mov_tl(cpu_dst, cpu_hver);
- break;
- case 31: // hstick_cmpr
- tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
- break;
- default:
- goto illegal_insn;
- }
-#endif
- gen_store_gpr(dc, rd, cpu_dst);
- break;
- }
if (xop == 0x2a) { /* rdwim / V9 rdpr */
if (!supervisor(dc)) {
goto priv_insn;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 23/90] target/sparc: Move RDWIM, RDPR to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (21 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 22/90] target/sparc: Move RDPSR, RDHPR " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 24/90] target/sparc: Move RDTBR, FLUSHW " Richard Henderson
` (67 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 22 +++
target/sparc/translate.c | 360 +++++++++++++++++++++++---------------
2 files changed, 244 insertions(+), 138 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 8b05b9d8f1..bab80514ba 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -55,3 +55,25 @@ RDHPR_hintp 10 rd:5 101001 00011 0 0000000000000
RDHPR_htba 10 rd:5 101001 00101 0 0000000000000
RDHPR_hver 10 rd:5 101001 00110 0 0000000000000
RDHPR_hstick_cmpr 10 rd:5 101001 11111 0 0000000000000
+
+{
+ RDWIM 10 rd:5 101010 00000 0 0000000000000
+ RDPR_tpc 10 rd:5 101010 00000 0 0000000000000
+}
+RDPR_tnpc 10 rd:5 101010 00001 0 0000000000000
+RDPR_tstate 10 rd:5 101010 00010 0 0000000000000
+RDPR_tt 10 rd:5 101010 00011 0 0000000000000
+RDPR_tick 10 rd:5 101010 00100 0 0000000000000
+RDPR_tba 10 rd:5 101010 00101 0 0000000000000
+RDPR_pstate 10 rd:5 101010 00110 0 0000000000000
+RDPR_tl 10 rd:5 101010 00111 0 0000000000000
+RDPR_pil 10 rd:5 101010 01000 0 0000000000000
+RDPR_cwp 10 rd:5 101010 01001 0 0000000000000
+RDPR_cansave 10 rd:5 101010 01010 0 0000000000000
+RDPR_canrestore 10 rd:5 101010 01011 0 0000000000000
+RDPR_cleanwin 10 rd:5 101010 01100 0 0000000000000
+RDPR_otherwin 10 rd:5 101010 01101 0 0000000000000
+RDPR_wstate 10 rd:5 101010 01110 0 0000000000000
+RDPR_gl 10 rd:5 101010 10000 0 0000000000000
+RDPR_strand_status 10 rd:5 101010 11010 0 0000000000000
+RDPR_ver 10 rd:5 101010 11111 0 0000000000000
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index cdfe353596..9d01c53791 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -40,6 +40,7 @@
#define gen_helper_rdpsr(D, E) qemu_build_not_reached()
#else
#define gen_helper_rdccr(D, E) qemu_build_not_reached()
+#define gen_helper_rdcwp(D, E) qemu_build_not_reached()
#endif
/* Dynamic PC, must exit to main loop. */
@@ -59,9 +60,7 @@ static TCGv_i32 cpu_psr;
static TCGv cpu_fsr, cpu_pc, cpu_npc;
static TCGv cpu_regs[32];
static TCGv cpu_y;
-#ifndef CONFIG_USER_ONLY
static TCGv cpu_tbr;
-#endif
static TCGv cpu_cond;
#ifdef TARGET_SPARC64
static TCGv_i32 cpu_xcc, cpu_fprs;
@@ -2687,8 +2686,7 @@ static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
gen_update_fprs_dirty(dc, qd);
}
-#ifndef CONFIG_USER_ONLY
-static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env tcg_env)
+static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr)
{
TCGv_i32 r_tl = tcg_temp_new_i32();
@@ -2709,7 +2707,6 @@ static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env tcg_env)
tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
}
}
-#endif
static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2,
int width, bool cc, bool left)
@@ -2848,6 +2845,7 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
# define avail_64(C) false
#endif
#define avail_ASR17(C) ((C)->def->features & CPU_FEATURE_ASR17)
+#define avail_GL(C) ((C)->def->features & CPU_FEATURE_GL)
#define avail_HYPV(C) ((C)->def->features & CPU_FEATURE_HYPV)
/* Default case for non jump instructions. */
@@ -3404,6 +3402,221 @@ static TCGv do_rdhstick_cmpr(DisasContext *dc, TCGv dst)
TRANS(RDHPR_hstick_cmpr, HYPV, do_rd_special, hypervisor(dc), a->rd,
do_rdhstick_cmpr)
+static TCGv do_rdwim(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ qemu_build_not_reached();
+#else
+ return cpu_wim;
+#endif
+}
+
+TRANS(RDWIM, 32, do_rd_special, supervisor(dc), a->rd, do_rdwim)
+
+static TCGv do_rdtpc(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tsptr = tcg_temp_new_ptr();
+
+ gen_load_trap_state_at_tl(r_tsptr);
+ tcg_gen_ld_tl(dst, r_tsptr, offsetof(trap_state, tpc));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_tpc, 64, do_rd_special, supervisor(dc), a->rd, do_rdtpc)
+
+static TCGv do_rdtnpc(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tsptr = tcg_temp_new_ptr();
+
+ gen_load_trap_state_at_tl(r_tsptr);
+ tcg_gen_ld_tl(dst, r_tsptr, offsetof(trap_state, tnpc));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_tnpc, 64, do_rd_special, supervisor(dc), a->rd, do_rdtnpc)
+
+static TCGv do_rdtstate(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tsptr = tcg_temp_new_ptr();
+
+ gen_load_trap_state_at_tl(r_tsptr);
+ tcg_gen_ld_tl(dst, r_tsptr, offsetof(trap_state, tstate));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_tstate, 64, do_rd_special, supervisor(dc), a->rd, do_rdtstate)
+
+static TCGv do_rdtt(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tsptr = tcg_temp_new_ptr();
+
+ gen_load_trap_state_at_tl(r_tsptr);
+ tcg_gen_ld32s_tl(dst, r_tsptr, offsetof(trap_state, tt));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_tt, 64, do_rd_special, supervisor(dc), a->rd, do_rdtt)
+TRANS(RDPR_tick, 64, do_rd_special, supervisor(dc), a->rd, do_rdtick)
+
+static TCGv do_rdtba(DisasContext *dc, TCGv dst)
+{
+ return cpu_tbr;
+}
+
+TRANS(RDPR_tba, 64, do_rd_special, supervisor(dc), a->rd, do_rdtba)
+
+static TCGv do_rdpstate(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld32s_tl(dst, tcg_env, offsetof(CPUSPARCState, pstate));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_pstate, 64, do_rd_special, supervisor(dc), a->rd, do_rdpstate)
+
+static TCGv do_rdtl(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld32s_tl(dst, tcg_env, offsetof(CPUSPARCState, tl));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_tl, 64, do_rd_special, supervisor(dc), a->rd, do_rdtl)
+
+static TCGv do_rdpil(DisasContext *dc, TCGv dst)
+{
+ tcg_gen_ld32s_tl(dst, tcg_env, offsetof(CPUSPARCState, psrpil));
+ return dst;
+}
+
+TRANS(RDPR_pil, 64, do_rd_special, supervisor(dc), a->rd, do_rdpil)
+
+static TCGv do_rdcwp(DisasContext *dc, TCGv dst)
+{
+ gen_helper_rdcwp(dst, tcg_env);
+ return dst;
+}
+
+TRANS(RDPR_cwp, 64, do_rd_special, supervisor(dc), a->rd, do_rdcwp)
+
+static TCGv do_rdcansave(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld32s_tl(dst, tcg_env, offsetof(CPUSPARCState, cansave));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_cansave, 64, do_rd_special, supervisor(dc), a->rd, do_rdcansave)
+
+static TCGv do_rdcanrestore(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld32s_tl(dst, tcg_env, offsetof(CPUSPARCState, canrestore));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_canrestore, 64, do_rd_special, supervisor(dc), a->rd,
+ do_rdcanrestore)
+
+static TCGv do_rdcleanwin(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld32s_tl(dst, tcg_env, offsetof(CPUSPARCState, cleanwin));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_cleanwin, 64, do_rd_special, supervisor(dc), a->rd, do_rdcleanwin)
+
+static TCGv do_rdotherwin(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld32s_tl(dst, tcg_env, offsetof(CPUSPARCState, otherwin));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_otherwin, 64, do_rd_special, supervisor(dc), a->rd, do_rdotherwin)
+
+static TCGv do_rdwstate(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld32s_tl(dst, tcg_env, offsetof(CPUSPARCState, wstate));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_wstate, 64, do_rd_special, supervisor(dc), a->rd, do_rdwstate)
+
+static TCGv do_rdgl(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld32s_tl(dst, tcg_env, offsetof(CPUSPARCState, gl));
+ return dst;
+#else
+ g_assert_not_reached();
+#endif
+}
+
+TRANS(RDPR_gl, GL, do_rd_special, supervisor(dc), a->rd, do_rdgl)
+
+/* UA2005 strand status */
+static TCGv do_rdssr(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_ssr;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_strand_status, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdssr)
+
+static TCGv do_rdver(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_ver;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDPR_ver, 64, do_rd_special, supervisor(dc), a->rd, do_rdver)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -3434,133 +3647,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv cpu_dst __attribute__((unused)) = tcg_temp_new();
TCGv cpu_tmp0 __attribute__((unused));
-#if !defined(CONFIG_USER_ONLY)
- if (xop == 0x2a) { /* rdwim / V9 rdpr */
- if (!supervisor(dc)) {
- goto priv_insn;
- }
- cpu_tmp0 = tcg_temp_new();
-#ifdef TARGET_SPARC64
- rs1 = GET_FIELD(insn, 13, 17);
- switch (rs1) {
- case 0: // tpc
- {
- TCGv_ptr r_tsptr;
-
- r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr, tcg_env);
- tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
- offsetof(trap_state, tpc));
- }
- break;
- case 1: // tnpc
- {
- TCGv_ptr r_tsptr;
-
- r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr, tcg_env);
- tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
- offsetof(trap_state, tnpc));
- }
- break;
- case 2: // tstate
- {
- TCGv_ptr r_tsptr;
-
- r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr, tcg_env);
- tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
- offsetof(trap_state, tstate));
- }
- break;
- case 3: // tt
- {
- TCGv_ptr r_tsptr = tcg_temp_new_ptr();
-
- gen_load_trap_state_at_tl(r_tsptr, tcg_env);
- tcg_gen_ld32s_tl(cpu_tmp0, r_tsptr,
- offsetof(trap_state, tt));
- }
- break;
- case 4: // tick
- {
- TCGv_ptr r_tickptr;
- TCGv_i32 r_const;
-
- r_tickptr = tcg_temp_new_ptr();
- r_const = tcg_constant_i32(dc->mem_idx);
- tcg_gen_ld_ptr(r_tickptr, tcg_env,
- offsetof(CPUSPARCState, tick));
- if (translator_io_start(&dc->base)) {
- dc->base.is_jmp = DISAS_EXIT;
- }
- gen_helper_tick_get_count(cpu_tmp0, tcg_env,
- r_tickptr, r_const);
- }
- break;
- case 5: // tba
- tcg_gen_mov_tl(cpu_tmp0, cpu_tbr);
- break;
- case 6: // pstate
- tcg_gen_ld32s_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, pstate));
- break;
- case 7: // tl
- tcg_gen_ld32s_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, tl));
- break;
- case 8: // pil
- tcg_gen_ld32s_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, psrpil));
- break;
- case 9: // cwp
- gen_helper_rdcwp(cpu_tmp0, tcg_env);
- break;
- case 10: // cansave
- tcg_gen_ld32s_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, cansave));
- break;
- case 11: // canrestore
- tcg_gen_ld32s_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, canrestore));
- break;
- case 12: // cleanwin
- tcg_gen_ld32s_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, cleanwin));
- break;
- case 13: // otherwin
- tcg_gen_ld32s_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, otherwin));
- break;
- case 14: // wstate
- tcg_gen_ld32s_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, wstate));
- break;
- case 16: // UA2005 gl
- CHECK_IU_FEATURE(dc, GL);
- tcg_gen_ld32s_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, gl));
- break;
- case 26: // UA2005 strand status
- CHECK_IU_FEATURE(dc, HYPV);
- if (!hypervisor(dc))
- goto priv_insn;
- tcg_gen_mov_tl(cpu_tmp0, cpu_ssr);
- break;
- case 31: // ver
- tcg_gen_mov_tl(cpu_tmp0, cpu_ver);
- break;
- case 15: // fq
- default:
- goto illegal_insn;
- }
-#else
- tcg_gen_ext_i32_tl(cpu_tmp0, cpu_wim);
-#endif
- gen_store_gpr(dc, rd, cpu_tmp0);
- break;
- }
-#endif
#if defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)
if (xop == 0x2b) { /* rdtbr / V9 flushw */
#ifdef TARGET_SPARC64
@@ -4406,7 +4492,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr, tcg_env);
+ gen_load_trap_state_at_tl(r_tsptr);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tpc));
}
@@ -4416,7 +4502,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr, tcg_env);
+ gen_load_trap_state_at_tl(r_tsptr);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tnpc));
}
@@ -4426,7 +4512,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr, tcg_env);
+ gen_load_trap_state_at_tl(r_tsptr);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state,
tstate));
@@ -4437,7 +4523,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr, tcg_env);
+ gen_load_trap_state_at_tl(r_tsptr);
tcg_gen_st32_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tt));
}
@@ -5866,9 +5952,7 @@ void sparc_tcg_init(void)
{ &cpu_pc, offsetof(CPUSPARCState, pc), "pc" },
{ &cpu_npc, offsetof(CPUSPARCState, npc), "npc" },
{ &cpu_y, offsetof(CPUSPARCState, y), "y" },
-#ifndef CONFIG_USER_ONLY
{ &cpu_tbr, offsetof(CPUSPARCState, tbr), "tbr" },
-#endif
};
unsigned int i;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 24/90] target/sparc: Move RDTBR, FLUSHW to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (22 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 23/90] target/sparc: Move RDWIM, RDPR " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 25/90] target/sparc: Move WRASR " Richard Henderson
` (66 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 5 +++++
target/sparc/translate.c | 23 +++++++++++------------
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index bab80514ba..c2d8b0dbbe 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -77,3 +77,8 @@ RDPR_wstate 10 rd:5 101010 01110 0 0000000000000
RDPR_gl 10 rd:5 101010 10000 0 0000000000000
RDPR_strand_status 10 rd:5 101010 11010 0 0000000000000
RDPR_ver 10 rd:5 101010 11111 0 0000000000000
+
+{
+ FLUSHW 10 00000 101011 00000 0 0000000000000
+ RDTBR 10 rd:5 101011 00000 0 0000000000000
+}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 9d01c53791..c6f64e7fbb 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -3479,6 +3479,7 @@ static TCGv do_rdtba(DisasContext *dc, TCGv dst)
return cpu_tbr;
}
+TRANS(RDTBR, 32, do_rd_special, supervisor(dc), a->rd, do_rdtba)
TRANS(RDPR_tba, 64, do_rd_special, supervisor(dc), a->rd, do_rdtba)
static TCGv do_rdpstate(DisasContext *dc, TCGv dst)
@@ -3617,6 +3618,16 @@ static TCGv do_rdver(DisasContext *dc, TCGv dst)
TRANS(RDPR_ver, 64, do_rd_special, supervisor(dc), a->rd, do_rdver)
+static bool trans_FLUSHW(DisasContext *dc, arg_FLUSHW *a)
+{
+#ifdef TARGET_SPARC64
+ gen_helper_flushw(tcg_env);
+ return advance_pc(dc);
+#else
+ return false;
+#endif
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -3647,18 +3658,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv cpu_dst __attribute__((unused)) = tcg_temp_new();
TCGv cpu_tmp0 __attribute__((unused));
-#if defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)
- if (xop == 0x2b) { /* rdtbr / V9 flushw */
-#ifdef TARGET_SPARC64
- gen_helper_flushw(tcg_env);
-#else
- if (!supervisor(dc))
- goto priv_insn;
- gen_store_gpr(dc, rd, cpu_tbr);
-#endif
- break;
- }
-#endif
if (xop == 0x34) { /* FPU Operations */
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 25/90] target/sparc: Move WRASR to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (23 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 24/90] target/sparc: Move RDTBR, FLUSHW " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 26/90] target/sparc: Move WRPSR, SAVED, RESTORED " Richard Henderson
` (65 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 33 +++-
target/sparc/translate.c | 353 +++++++++++++++++++++-----------------
2 files changed, 226 insertions(+), 160 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index c2d8b0dbbe..6acf0f9403 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -22,7 +22,12 @@ SETHI 00 rd:5 100 i:22
CALL 01 i:s30
-Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
+##
+## Major Opcode 10 -- integer, floating-point, vis, and system insns.
+##
+
+&r_r_ri rd rs1 rs2_or_imm imm:bool
+@n_r_ri .. ..... ...... rs1:5 imm:1 rs2_or_imm:s13 &r_r_ri rd=0
{
[
@@ -46,6 +51,30 @@ Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
RDY 10 rd:5 101000 rs1:5 0 0000000000000
}
+{
+ [
+ WRY 10 00000 110000 ..... . ............. @n_r_ri
+ WRCCR 10 00010 110000 ..... . ............. @n_r_ri
+ WRASI 10 00011 110000 ..... . ............. @n_r_ri
+ WRFPRS 10 00110 110000 ..... . ............. @n_r_ri
+ {
+ WRGSR 10 10011 110000 ..... . ............. @n_r_ri
+ WRPOWERDOWN 10 10011 110000 ..... . ............. @n_r_ri
+ }
+ WRSOFTINT_SET 10 10100 110000 ..... . ............. @n_r_ri
+ WRSOFTINT_CLR 10 10101 110000 ..... . ............. @n_r_ri
+ WRSOFTINT 10 10110 110000 ..... . ............. @n_r_ri
+ WRTICK_CMPR 10 10111 110000 ..... . ............. @n_r_ri
+ WRSTICK 10 11000 110000 ..... . ............. @n_r_ri
+ WRSTICK_CMPR 10 11001 110000 ..... . ............. @n_r_ri
+ ]
+ # Before v8, rs1==0 was WRY, and the rest executed as nop.
+ [
+ NOP_v7 10 ----- 110000 ----- 0 00000000 -----
+ NOP_v7 10 ----- 110000 ----- 1 -------- -----
+ ]
+}
+
{
RDPSR 10 rd:5 101001 00000 0 0000000000000
RDHPR_hpstate 10 rd:5 101001 00000 0 0000000000000
@@ -82,3 +111,5 @@ RDPR_ver 10 rd:5 101010 11111 0 0000000000000
FLUSHW 10 00000 101011 00000 0 0000000000000
RDTBR 10 rd:5 101011 00000 0 0000000000000
}
+
+Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index c6f64e7fbb..59931c053f 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -37,10 +37,15 @@
#undef HELPER_H
#ifdef TARGET_SPARC64
-#define gen_helper_rdpsr(D, E) qemu_build_not_reached()
+#define gen_helper_rdpsr(D, E) qemu_build_not_reached()
+#define gen_helper_power_down(E) g_assert_not_reached()
#else
-#define gen_helper_rdccr(D, E) qemu_build_not_reached()
-#define gen_helper_rdcwp(D, E) 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_wrccr(E, S) qemu_build_not_reached()
+#define gen_helper_set_softint(E, S) qemu_build_not_reached()
+#define gen_helper_clear_softint(E, S) qemu_build_not_reached()
+#define gen_helper_write_softint(E, S) qemu_build_not_reached()
#endif
/* Dynamic PC, must exit to main loop. */
@@ -2847,6 +2852,7 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
#define avail_ASR17(C) ((C)->def->features & CPU_FEATURE_ASR17)
#define avail_GL(C) ((C)->def->features & CPU_FEATURE_GL)
#define avail_HYPV(C) ((C)->def->features & CPU_FEATURE_HYPV)
+#define avail_POWERDOWN(C) ((C)->def->features & CPU_FEATURE_POWERDOWN)
/* Default case for non jump instructions. */
static bool advance_pc(DisasContext *dc)
@@ -3064,6 +3070,10 @@ static bool trans_SETHI(DisasContext *dc, arg_SETHI *a)
return advance_pc(dc);
}
+/*
+ * Major Opcode 10 -- integer, floating-point, vis, and system insns.
+ */
+
static bool trans_Tcc(DisasContext *dc, arg_Tcc *a)
{
DisasCompare cmp;
@@ -3628,6 +3638,186 @@ static bool trans_FLUSHW(DisasContext *dc, arg_FLUSHW *a)
#endif
}
+static bool do_wr_special(DisasContext *dc, arg_r_r_ri *a, bool priv,
+ void (*func)(DisasContext *, TCGv))
+{
+ TCGv src;
+
+ /* For simplicity, we under-decoded the rs2 form. */
+ if (!a->imm && (a->rs2_or_imm & ~0x1f)) {
+ return false;
+ }
+ if (!priv) {
+ return raise_priv(dc);
+ }
+
+ if (a->rs1 == 0 && (a->imm || a->rs2_or_imm == 0)) {
+ src = tcg_constant_tl(a->rs2_or_imm);
+ } else {
+ TCGv src1 = gen_load_gpr(dc, a->rs1);
+ if (a->rs2_or_imm == 0) {
+ src = src1;
+ } else {
+ src = tcg_temp_new();
+ if (a->imm) {
+ tcg_gen_xori_tl(src, src1, a->rs2_or_imm);
+ } else {
+ tcg_gen_xor_tl(src, src1, gen_load_gpr(dc, a->rs2_or_imm));
+ }
+ }
+ }
+ func(dc, src);
+ return advance_pc(dc);
+}
+
+static void do_wry(DisasContext *dc, TCGv src)
+{
+ tcg_gen_ext32u_tl(cpu_y, src);
+}
+
+TRANS(WRY, ALL, do_wr_special, a, true, do_wry)
+
+static void do_wrccr(DisasContext *dc, TCGv src)
+{
+ gen_helper_wrccr(tcg_env, src);
+}
+
+TRANS(WRCCR, 64, do_wr_special, a, true, do_wrccr)
+
+static void do_wrasi(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ TCGv tmp = tcg_temp_new();
+ tcg_gen_andi_tl(tmp, src, 0xff);
+ tcg_gen_st32_tl(tmp, tcg_env, offsetof(CPUSPARCState, asi));
+ /* End TB to notice changed ASI. */
+ dc->base.is_jmp = DISAS_EXIT;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRASI, 64, do_wr_special, a, true, do_wrasi)
+
+static void do_wrfprs(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_trunc_tl_i32(cpu_fprs, src);
+ dc->fprs_dirty = 0;
+ dc->base.is_jmp = DISAS_EXIT;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRFPRS, 64, do_wr_special, a, true, do_wrfprs)
+
+static void do_wrgsr(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ gen_trap_ifnofpu(dc);
+ tcg_gen_mov_tl(cpu_gsr, src);
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRGSR, 64, do_wr_special, a, true, do_wrgsr)
+
+static void do_wrsoftint_set(DisasContext *dc, TCGv src)
+{
+ gen_helper_set_softint(tcg_env, src);
+}
+
+TRANS(WRSOFTINT_SET, 64, do_wr_special, a, supervisor(dc), do_wrsoftint_set)
+
+static void do_wrsoftint_clr(DisasContext *dc, TCGv src)
+{
+ gen_helper_clear_softint(tcg_env, src);
+}
+
+TRANS(WRSOFTINT_CLR, 64, do_wr_special, a, supervisor(dc), do_wrsoftint_clr)
+
+static void do_wrsoftint(DisasContext *dc, TCGv src)
+{
+ gen_helper_write_softint(tcg_env, src);
+}
+
+TRANS(WRSOFTINT, 64, do_wr_special, a, supervisor(dc), do_wrsoftint)
+
+static void do_wrtick_cmpr(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tickptr = tcg_temp_new_ptr();
+
+ tcg_gen_mov_tl(cpu_tick_cmpr, src);
+ tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, tick));
+ translator_io_start(&dc->base);
+ gen_helper_tick_set_limit(r_tickptr, cpu_tick_cmpr);
+ /* End TB to handle timer interrupt */
+ dc->base.is_jmp = DISAS_EXIT;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRTICK_CMPR, 64, do_wr_special, a, supervisor(dc), do_wrtick_cmpr)
+
+static void do_wrstick(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tickptr = tcg_temp_new_ptr();
+
+ tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, stick));
+ translator_io_start(&dc->base);
+ gen_helper_tick_set_count(r_tickptr, src);
+ /* End TB to handle timer interrupt */
+ dc->base.is_jmp = DISAS_EXIT;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRSTICK, 64, do_wr_special, a, supervisor(dc), do_wrstick)
+
+static void do_wrstick_cmpr(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tickptr = tcg_temp_new_ptr();
+
+ tcg_gen_mov_tl(cpu_stick_cmpr, src);
+ tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, stick));
+ translator_io_start(&dc->base);
+ gen_helper_tick_set_limit(r_tickptr, cpu_stick_cmpr);
+ /* End TB to handle timer interrupt */
+ dc->base.is_jmp = DISAS_EXIT;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRSTICK_CMPR, 64, do_wr_special, a, supervisor(dc), do_wrstick_cmpr)
+
+static void do_wrpowerdown(DisasContext *dc, TCGv src)
+{
+ save_state(dc);
+ gen_helper_power_down(tcg_env);
+}
+
+TRANS(WRPOWERDOWN, POWERDOWN, do_wr_special, a, supervisor(dc), do_wrpowerdown)
+
+static bool trans_NOP_v7(DisasContext *dc, arg_NOP_v7 *a)
+{
+ /*
+ * TODO: Need a feature bit for sparcv8.
+ * In the meantime, treat all 32-bit cpus like sparcv7.
+ */
+ if (avail_32(dc)) {
+ return advance_pc(dc);
+ }
+ return false;
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4288,162 +4478,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
break;
#endif
case 0x30:
- {
- cpu_tmp0 = tcg_temp_new();
- switch(rd) {
- case 0: /* wry */
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
- tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
- break;
-#ifndef TARGET_SPARC64
- case 0x01 ... 0x0f: /* undefined in the
- SPARCv8 manual, nop
- on the microSPARC
- II */
- case 0x10 ... 0x1f: /* implementation-dependent
- in the SPARCv8
- manual, nop on the
- microSPARC II */
- if ((rd == 0x13) && (dc->def->features &
- CPU_FEATURE_POWERDOWN)) {
- /* LEON3 power-down */
- save_state(dc);
- gen_helper_power_down(tcg_env);
- }
- break;
-#else
- case 0x2: /* V9 wrccr */
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
- gen_helper_wrccr(tcg_env, cpu_tmp0);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
- dc->cc_op = CC_OP_FLAGS;
- break;
- case 0x3: /* V9 wrasi */
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
- tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xff);
- tcg_gen_st32_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, asi));
- /*
- * End TB to notice changed ASI.
- * TODO: Could notice src1 = %g0 and IS_IMM,
- * update DisasContext and not exit the TB.
- */
- save_state(dc);
- gen_op_next_insn();
- tcg_gen_lookup_and_goto_ptr();
- dc->base.is_jmp = DISAS_NORETURN;
- break;
- case 0x6: /* V9 wrfprs */
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
- tcg_gen_trunc_tl_i32(cpu_fprs, cpu_tmp0);
- dc->fprs_dirty = 0;
- save_state(dc);
- gen_op_next_insn();
- tcg_gen_exit_tb(NULL, 0);
- dc->base.is_jmp = DISAS_NORETURN;
- break;
- case 0xf: /* V9 sir, nop if user */
-#if !defined(CONFIG_USER_ONLY)
- if (supervisor(dc)) {
- ; // XXX
- }
-#endif
- break;
- case 0x13: /* Graphics Status */
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
- break;
- case 0x14: /* Softint set */
- if (!supervisor(dc))
- goto illegal_insn;
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
- gen_helper_set_softint(tcg_env, cpu_tmp0);
- break;
- case 0x15: /* Softint clear */
- if (!supervisor(dc))
- goto illegal_insn;
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
- gen_helper_clear_softint(tcg_env, cpu_tmp0);
- break;
- case 0x16: /* Softint write */
- if (!supervisor(dc))
- goto illegal_insn;
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
- gen_helper_write_softint(tcg_env, cpu_tmp0);
- break;
- case 0x17: /* Tick compare */
-#if !defined(CONFIG_USER_ONLY)
- if (!supervisor(dc))
- goto illegal_insn;
-#endif
- {
- TCGv_ptr r_tickptr;
-
- tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
- cpu_src2);
- r_tickptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tickptr, tcg_env,
- offsetof(CPUSPARCState, tick));
- translator_io_start(&dc->base);
- gen_helper_tick_set_limit(r_tickptr,
- cpu_tick_cmpr);
- /* End TB to handle timer interrupt */
- dc->base.is_jmp = DISAS_EXIT;
- }
- break;
- case 0x18: /* System tick */
-#if !defined(CONFIG_USER_ONLY)
- if (!supervisor(dc))
- goto illegal_insn;
-#endif
- {
- TCGv_ptr r_tickptr;
-
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1,
- cpu_src2);
- r_tickptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tickptr, tcg_env,
- offsetof(CPUSPARCState, stick));
- translator_io_start(&dc->base);
- gen_helper_tick_set_count(r_tickptr,
- cpu_tmp0);
- /* End TB to handle timer interrupt */
- dc->base.is_jmp = DISAS_EXIT;
- }
- break;
- case 0x19: /* System tick compare */
-#if !defined(CONFIG_USER_ONLY)
- if (!supervisor(dc))
- goto illegal_insn;
-#endif
- {
- TCGv_ptr r_tickptr;
-
- tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
- cpu_src2);
- r_tickptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tickptr, tcg_env,
- offsetof(CPUSPARCState, stick));
- translator_io_start(&dc->base);
- gen_helper_tick_set_limit(r_tickptr,
- cpu_stick_cmpr);
- /* End TB to handle timer interrupt */
- dc->base.is_jmp = DISAS_EXIT;
- }
- break;
-
- case 0x10: /* Performance Control */
- case 0x11: /* Performance Instrumentation
- Counter */
- case 0x12: /* Dispatch Control */
-#endif
- default:
- goto illegal_insn;
- }
- }
- break;
+ goto illegal_insn; /* WRASR in decodetree */
#if !defined(CONFIG_USER_ONLY)
case 0x31: /* wrpsr, V9 saved, restored */
{
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 26/90] target/sparc: Move WRPSR, SAVED, RESTORED to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (24 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 25/90] target/sparc: Move WRASR " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 27/90] target/sparc: Move WRWIM, WRPR " Richard Henderson
` (64 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 10 +++++++
target/sparc/translate.c | 61 ++++++++++++++++++---------------------
2 files changed, 38 insertions(+), 33 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 6acf0f9403..850b5d58d0 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -85,6 +85,16 @@ RDHPR_htba 10 rd:5 101001 00101 0 0000000000000
RDHPR_hver 10 rd:5 101001 00110 0 0000000000000
RDHPR_hstick_cmpr 10 rd:5 101001 11111 0 0000000000000
+{
+ WRPSR 10 00000 110001 ..... . ............. @n_r_ri
+ SAVED 10 00000 110001 00000 0 0000000000000
+}
+RESTORED 10 00001 110001 00000 0 0000000000000
+# UA2005 ALLCLEAN
+# UA2005 OTHERW
+# UA2005 NORMALW
+# UA2005 INVALW
+
{
RDWIM 10 rd:5 101010 00000 0 0000000000000
RDPR_tpc 10 rd:5 101010 00000 0 0000000000000
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 59931c053f..a5058b5931 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -38,6 +38,7 @@
#ifdef TARGET_SPARC64
#define gen_helper_rdpsr(D, E) qemu_build_not_reached()
+#define gen_helper_wrpsr(E, S) qemu_build_not_reached()
#define gen_helper_power_down(E) g_assert_not_reached()
#else
#define gen_helper_rdccr(D, E) qemu_build_not_reached()
@@ -46,6 +47,8 @@
#define gen_helper_set_softint(E, S) qemu_build_not_reached()
#define gen_helper_clear_softint(E, S) qemu_build_not_reached()
#define gen_helper_write_softint(E, S) qemu_build_not_reached()
+#define gen_helper_saved ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_restored ({ qemu_build_not_reached(); NULL; })
#endif
/* Dynamic PC, must exit to main loop. */
@@ -3806,6 +3809,31 @@ static void do_wrpowerdown(DisasContext *dc, TCGv src)
TRANS(WRPOWERDOWN, POWERDOWN, do_wr_special, a, supervisor(dc), do_wrpowerdown)
+static void do_wrpsr(DisasContext *dc, TCGv src)
+{
+ gen_helper_wrpsr(tcg_env, src);
+ tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
+ dc->cc_op = CC_OP_FLAGS;
+ save_state(dc);
+ gen_op_next_insn();
+ tcg_gen_exit_tb(NULL, 0);
+ dc->base.is_jmp = DISAS_NORETURN;
+}
+
+TRANS(WRPSR, 32, do_wr_special, a, supervisor(dc), do_wrpsr)
+
+static bool do_saved_restored(DisasContext *dc, void (*func)(TCGv_env))
+{
+ if (!supervisor(dc)) {
+ return raise_priv(dc);
+ }
+ func(tcg_env);
+ return advance_pc(dc);
+}
+
+TRANS(SAVED, 64, do_saved_restored, gen_helper_saved)
+TRANS(RESTORED, 64, do_saved_restored, gen_helper_restored)
+
static bool trans_NOP_v7(DisasContext *dc, arg_NOP_v7 *a)
{
/*
@@ -4480,39 +4508,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x30:
goto illegal_insn; /* WRASR in decodetree */
#if !defined(CONFIG_USER_ONLY)
- case 0x31: /* wrpsr, V9 saved, restored */
- {
- if (!supervisor(dc))
- goto priv_insn;
-#ifdef TARGET_SPARC64
- switch (rd) {
- case 0:
- gen_helper_saved(tcg_env);
- break;
- case 1:
- gen_helper_restored(tcg_env);
- break;
- case 2: /* UA2005 allclean */
- case 3: /* UA2005 otherw */
- case 4: /* UA2005 normalw */
- case 5: /* UA2005 invalw */
- // XXX
- default:
- goto illegal_insn;
- }
-#else
- cpu_tmp0 = tcg_temp_new();
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
- gen_helper_wrpsr(tcg_env, cpu_tmp0);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
- dc->cc_op = CC_OP_FLAGS;
- save_state(dc);
- gen_op_next_insn();
- tcg_gen_exit_tb(NULL, 0);
- dc->base.is_jmp = DISAS_NORETURN;
-#endif
- }
- break;
case 0x32: /* wrwim, V9 wrpr */
{
if (!supervisor(dc))
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 27/90] target/sparc: Move WRWIM, WRPR to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (25 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 26/90] target/sparc: Move WRPSR, SAVED, RESTORED " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 28/90] target/sparc: Move WRTBR, WRHPR " Richard Henderson
` (63 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 21 +++
target/sparc/translate.c | 350 +++++++++++++++++++++++---------------
2 files changed, 235 insertions(+), 136 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 850b5d58d0..56c04f01a5 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -117,6 +117,27 @@ RDPR_gl 10 rd:5 101010 10000 0 0000000000000
RDPR_strand_status 10 rd:5 101010 11010 0 0000000000000
RDPR_ver 10 rd:5 101010 11111 0 0000000000000
+{
+ WRWIM 10 00000 110010 ..... . ............. @n_r_ri
+ WRPR_tpc 10 00000 110010 ..... . ............. @n_r_ri
+}
+WRPR_tnpc 10 00001 110010 ..... . ............. @n_r_ri
+WRPR_tstate 10 00010 110010 ..... . ............. @n_r_ri
+WRPR_tt 10 00011 110010 ..... . ............. @n_r_ri
+WRPR_tick 10 00100 110010 ..... . ............. @n_r_ri
+WRPR_tba 10 00101 110010 ..... . ............. @n_r_ri
+WRPR_pstate 10 00110 110010 ..... . ............. @n_r_ri
+WRPR_tl 10 00111 110010 ..... . ............. @n_r_ri
+WRPR_pil 10 01000 110010 ..... . ............. @n_r_ri
+WRPR_cwp 10 01001 110010 ..... . ............. @n_r_ri
+WRPR_cansave 10 01010 110010 ..... . ............. @n_r_ri
+WRPR_canrestore 10 01011 110010 ..... . ............. @n_r_ri
+WRPR_cleanwin 10 01100 110010 ..... . ............. @n_r_ri
+WRPR_otherwin 10 01101 110010 ..... . ............. @n_r_ri
+WRPR_wstate 10 01110 110010 ..... . ............. @n_r_ri
+WRPR_gl 10 10000 110010 ..... . ............. @n_r_ri
+WRPR_strand_status 10 11010 110010 ..... . ............. @n_r_ri
+
{
FLUSHW 10 00000 101011 00000 0 0000000000000
RDTBR 10 rd:5 101011 00000 0 0000000000000
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index a5058b5931..6b8dfa7830 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -44,6 +44,10 @@
#define gen_helper_rdccr(D, E) qemu_build_not_reached()
#define gen_helper_rdcwp(D, E) qemu_build_not_reached()
#define gen_helper_wrccr(E, S) qemu_build_not_reached()
+#define gen_helper_wrcwp(E, S) qemu_build_not_reached()
+#define gen_helper_wrgl(E, S) g_assert_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_set_softint(E, S) qemu_build_not_reached()
#define gen_helper_clear_softint(E, S) qemu_build_not_reached()
#define gen_helper_write_softint(E, S) qemu_build_not_reached()
@@ -3822,6 +3826,214 @@ static void do_wrpsr(DisasContext *dc, TCGv src)
TRANS(WRPSR, 32, do_wr_special, a, supervisor(dc), do_wrpsr)
+static void do_wrwim(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ qemu_build_not_reached();
+#else
+ target_ulong mask = MAKE_64BIT_MASK(0, dc->def->nwindows);
+ tcg_gen_andi_tl(cpu_wim, src, mask);
+#endif
+}
+
+TRANS(WRWIM, 32, do_wr_special, a, supervisor(dc), do_wrwim)
+
+static void do_wrtpc(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tsptr = tcg_temp_new_ptr();
+
+ gen_load_trap_state_at_tl(r_tsptr);
+ tcg_gen_st_tl(src, r_tsptr, offsetof(trap_state, tpc));
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_tpc, 64, do_wr_special, a, supervisor(dc), do_wrtpc)
+
+static void do_wrtnpc(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tsptr = tcg_temp_new_ptr();
+
+ gen_load_trap_state_at_tl(r_tsptr);
+ tcg_gen_st_tl(src, r_tsptr, offsetof(trap_state, tnpc));
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_tnpc, 64, do_wr_special, a, supervisor(dc), do_wrtnpc)
+
+static void do_wrtstate(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tsptr = tcg_temp_new_ptr();
+
+ gen_load_trap_state_at_tl(r_tsptr);
+ tcg_gen_st_tl(src, r_tsptr, offsetof(trap_state, tstate));
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_tstate, 64, do_wr_special, a, supervisor(dc), do_wrtstate)
+
+static void do_wrtt(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tsptr = tcg_temp_new_ptr();
+
+ gen_load_trap_state_at_tl(r_tsptr);
+ tcg_gen_st32_tl(src, r_tsptr, offsetof(trap_state, tt));
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_tt, 64, do_wr_special, a, supervisor(dc), do_wrtt)
+
+static void do_wrtick(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tickptr = tcg_temp_new_ptr();
+
+ tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, tick));
+ translator_io_start(&dc->base);
+ gen_helper_tick_set_count(r_tickptr, src);
+ /* End TB to handle timer interrupt */
+ dc->base.is_jmp = DISAS_EXIT;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_tick, 64, do_wr_special, a, supervisor(dc), do_wrtick)
+
+static void do_wrtba(DisasContext *dc, TCGv src)
+{
+ tcg_gen_mov_tl(cpu_tbr, src);
+}
+
+TRANS(WRPR_tba, 64, do_wr_special, a, supervisor(dc), do_wrtba)
+
+static void do_wrpstate(DisasContext *dc, TCGv src)
+{
+ save_state(dc);
+ if (translator_io_start(&dc->base)) {
+ dc->base.is_jmp = DISAS_EXIT;
+ }
+ gen_helper_wrpstate(tcg_env, src);
+ dc->npc = DYNAMIC_PC;
+}
+
+TRANS(WRPR_pstate, 64, do_wr_special, a, supervisor(dc), do_wrpstate)
+
+static void do_wrtl(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ save_state(dc);
+ tcg_gen_st32_tl(src, tcg_env, offsetof(CPUSPARCState, tl));
+ dc->npc = DYNAMIC_PC;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_tl, 64, do_wr_special, a, supervisor(dc), do_wrtl)
+
+static void do_wrpil(DisasContext *dc, TCGv src)
+{
+ if (translator_io_start(&dc->base)) {
+ dc->base.is_jmp = DISAS_EXIT;
+ }
+ gen_helper_wrpil(tcg_env, src);
+}
+
+TRANS(WRPR_pil, 64, do_wr_special, a, supervisor(dc), do_wrpil)
+
+static void do_wrcwp(DisasContext *dc, TCGv src)
+{
+ gen_helper_wrcwp(tcg_env, src);
+}
+
+TRANS(WRPR_cwp, 64, do_wr_special, a, supervisor(dc), do_wrcwp)
+
+static void do_wrcansave(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_st32_tl(src, tcg_env, offsetof(CPUSPARCState, cansave));
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_cansave, 64, do_wr_special, a, supervisor(dc), do_wrcansave)
+
+static void do_wrcanrestore(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_st32_tl(src, tcg_env, offsetof(CPUSPARCState, canrestore));
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_canrestore, 64, do_wr_special, a, supervisor(dc), do_wrcanrestore)
+
+static void do_wrcleanwin(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_st32_tl(src, tcg_env, offsetof(CPUSPARCState, cleanwin));
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_cleanwin, 64, do_wr_special, a, supervisor(dc), do_wrcleanwin)
+
+static void do_wrotherwin(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_st32_tl(src, tcg_env, offsetof(CPUSPARCState, otherwin));
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_otherwin, 64, do_wr_special, a, supervisor(dc), do_wrotherwin)
+
+static void do_wrwstate(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_st32_tl(src, tcg_env, offsetof(CPUSPARCState, wstate));
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(WRPR_wstate, 64, do_wr_special, a, supervisor(dc), do_wrwstate)
+
+static void do_wrgl(DisasContext *dc, TCGv src)
+{
+ gen_helper_wrgl(tcg_env, src);
+}
+
+TRANS(WRPR_gl, GL, do_wr_special, a, supervisor(dc), do_wrgl)
+
+/* UA2005 strand status */
+static void do_wrssr(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_mov_tl(cpu_ssr, src);
+#else
+ g_assert_not_reached();
+#endif
+}
+
+TRANS(WRPR_strand_status, HYPV, do_wr_special, a, hypervisor(dc), do_wrssr)
+
static bool do_saved_restored(DisasContext *dc, void (*func)(TCGv_env))
{
if (!supervisor(dc)) {
@@ -4508,142 +4720,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x30:
goto illegal_insn; /* WRASR in decodetree */
#if !defined(CONFIG_USER_ONLY)
- case 0x32: /* wrwim, V9 wrpr */
- {
- if (!supervisor(dc))
- goto priv_insn;
- cpu_tmp0 = tcg_temp_new();
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
-#ifdef TARGET_SPARC64
- switch (rd) {
- case 0: // tpc
- {
- TCGv_ptr r_tsptr;
-
- r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr);
- tcg_gen_st_tl(cpu_tmp0, r_tsptr,
- offsetof(trap_state, tpc));
- }
- break;
- case 1: // tnpc
- {
- TCGv_ptr r_tsptr;
-
- r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr);
- tcg_gen_st_tl(cpu_tmp0, r_tsptr,
- offsetof(trap_state, tnpc));
- }
- break;
- case 2: // tstate
- {
- TCGv_ptr r_tsptr;
-
- r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr);
- tcg_gen_st_tl(cpu_tmp0, r_tsptr,
- offsetof(trap_state,
- tstate));
- }
- break;
- case 3: // tt
- {
- TCGv_ptr r_tsptr;
-
- r_tsptr = tcg_temp_new_ptr();
- gen_load_trap_state_at_tl(r_tsptr);
- tcg_gen_st32_tl(cpu_tmp0, r_tsptr,
- offsetof(trap_state, tt));
- }
- break;
- case 4: // tick
- {
- TCGv_ptr r_tickptr;
-
- r_tickptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tickptr, tcg_env,
- offsetof(CPUSPARCState, tick));
- translator_io_start(&dc->base);
- gen_helper_tick_set_count(r_tickptr,
- cpu_tmp0);
- /* End TB to handle timer interrupt */
- dc->base.is_jmp = DISAS_EXIT;
- }
- break;
- case 5: // tba
- tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
- break;
- case 6: // pstate
- save_state(dc);
- if (translator_io_start(&dc->base)) {
- dc->base.is_jmp = DISAS_EXIT;
- }
- gen_helper_wrpstate(tcg_env, cpu_tmp0);
- dc->npc = DYNAMIC_PC;
- break;
- case 7: // tl
- save_state(dc);
- tcg_gen_st32_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState, tl));
- dc->npc = DYNAMIC_PC;
- break;
- case 8: // pil
- if (translator_io_start(&dc->base)) {
- dc->base.is_jmp = DISAS_EXIT;
- }
- gen_helper_wrpil(tcg_env, cpu_tmp0);
- break;
- case 9: // cwp
- gen_helper_wrcwp(tcg_env, cpu_tmp0);
- break;
- case 10: // cansave
- tcg_gen_st32_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState,
- cansave));
- break;
- case 11: // canrestore
- tcg_gen_st32_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState,
- canrestore));
- break;
- case 12: // cleanwin
- tcg_gen_st32_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState,
- cleanwin));
- break;
- case 13: // otherwin
- tcg_gen_st32_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState,
- otherwin));
- break;
- case 14: // wstate
- tcg_gen_st32_tl(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState,
- wstate));
- break;
- case 16: // UA2005 gl
- CHECK_IU_FEATURE(dc, GL);
- gen_helper_wrgl(tcg_env, cpu_tmp0);
- break;
- case 26: // UA2005 strand status
- CHECK_IU_FEATURE(dc, HYPV);
- if (!hypervisor(dc))
- goto priv_insn;
- tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
- break;
- default:
- goto illegal_insn;
- }
-#else
- tcg_gen_trunc_tl_i32(cpu_wim, cpu_tmp0);
- if (dc->def->nwindows != 32) {
- tcg_gen_andi_tl(cpu_wim, cpu_wim,
- (1 << dc->def->nwindows) - 1);
- }
-#endif
- }
- break;
+ case 0x32:
+ goto illegal_insn; /* WRPR in decodetree */
case 0x33: /* wrtbr, UA2005 wrhpr */
{
#ifndef TARGET_SPARC64
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 28/90] target/sparc: Move WRTBR, WRHPR to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (26 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 27/90] target/sparc: Move WRWIM, WRPR " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 29/90] target/sparc: Move basic arithmetic " Richard Henderson
` (62 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 9 ++++
target/sparc/translate.c | 110 +++++++++++++++++++-------------------
2 files changed, 65 insertions(+), 54 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 56c04f01a5..49270705c7 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -143,4 +143,13 @@ WRPR_strand_status 10 11010 110010 ..... . ............. @n_r_ri
RDTBR 10 rd:5 101011 00000 0 0000000000000
}
+{
+ WRTBR 10 00000 110011 ..... . ............. @n_r_ri
+ WRHPR_hpstate 10 00000 110011 ..... . ............. @n_r_ri
+}
+# WRHPR_htstate
+WRHPR_hintp 10 00011 110011 ..... . ............. @n_r_ri
+WRHPR_htba 10 00101 110011 ..... . ............. @n_r_ri
+WRHPR_hstick_cmpr 10 11111 110011 ..... . ............. @n_r_ri
+
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 6b8dfa7830..428fbb49bd 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4034,6 +4034,61 @@ static void do_wrssr(DisasContext *dc, TCGv src)
TRANS(WRPR_strand_status, HYPV, do_wr_special, a, hypervisor(dc), do_wrssr)
+TRANS(WRTBR, 32, do_wr_special, a, supervisor(dc), do_wrtba)
+
+static void do_wrhpstate(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_st_i64(src, tcg_env, offsetof(CPUSPARCState, hpstate));
+ dc->base.is_jmp = DISAS_EXIT;
+#else
+ g_assert_not_reached();
+#endif
+}
+
+TRANS(WRHPR_hpstate, HYPV, do_wr_special, a, hypervisor(dc), do_wrhpstate)
+
+static void do_wrhintp(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_mov_tl(cpu_hintp, src);
+#else
+ g_assert_not_reached();
+#endif
+}
+
+TRANS(WRHPR_hintp, HYPV, do_wr_special, a, hypervisor(dc), do_wrhintp)
+
+static void do_wrhtba(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_mov_tl(cpu_htba, src);
+#else
+ g_assert_not_reached();
+#endif
+}
+
+TRANS(WRHPR_htba, HYPV, do_wr_special, a, hypervisor(dc), do_wrhtba)
+
+static void do_wrhstick_cmpr(DisasContext *dc, TCGv src)
+{
+#ifdef TARGET_SPARC64
+ TCGv_ptr r_tickptr = tcg_temp_new_ptr();
+
+ tcg_gen_mov_tl(cpu_hstick_cmpr, src);
+ tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, hstick));
+ translator_io_start(&dc->base);
+ gen_helper_tick_set_limit(r_tickptr, cpu_hstick_cmpr);
+ /* End TB to handle timer interrupt */
+ dc->base.is_jmp = DISAS_EXIT;
+#else
+ g_assert_not_reached();
+#endif
+}
+
+TRANS(WRHPR_hstick_cmpr, HYPV, do_wr_special, a, hypervisor(dc),
+ do_wrhstick_cmpr)
+
static bool do_saved_restored(DisasContext *dc, void (*func)(TCGv_env))
{
if (!supervisor(dc)) {
@@ -4719,63 +4774,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
#endif
case 0x30:
goto illegal_insn; /* WRASR in decodetree */
-#if !defined(CONFIG_USER_ONLY)
case 0x32:
goto illegal_insn; /* WRPR in decodetree */
case 0x33: /* wrtbr, UA2005 wrhpr */
- {
-#ifndef TARGET_SPARC64
- if (!supervisor(dc))
- goto priv_insn;
- tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
-#else
- CHECK_IU_FEATURE(dc, HYPV);
- if (!hypervisor(dc))
- goto priv_insn;
- cpu_tmp0 = tcg_temp_new();
- tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
- switch (rd) {
- case 0: // hpstate
- tcg_gen_st_i64(cpu_tmp0, tcg_env,
- offsetof(CPUSPARCState,
- hpstate));
- save_state(dc);
- gen_op_next_insn();
- tcg_gen_exit_tb(NULL, 0);
- dc->base.is_jmp = DISAS_NORETURN;
- break;
- case 1: // htstate
- // XXX gen_op_wrhtstate();
- break;
- case 3: // hintp
- tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
- break;
- case 5: // htba
- tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
- break;
- case 31: // hstick_cmpr
- {
- TCGv_ptr r_tickptr;
-
- tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
- r_tickptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tickptr, tcg_env,
- offsetof(CPUSPARCState, hstick));
- translator_io_start(&dc->base);
- gen_helper_tick_set_limit(r_tickptr,
- cpu_hstick_cmpr);
- /* End TB to handle timer interrupt */
- dc->base.is_jmp = DISAS_EXIT;
- }
- break;
- case 6: // hver readonly
- default:
- goto illegal_insn;
- }
-#endif
- }
- break;
-#endif
+ goto illegal_insn; /* WRTBR, WRHPR in decodetree */
#ifdef TARGET_SPARC64
case 0x2c: /* V9 movcc */
{
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 29/90] target/sparc: Move basic arithmetic to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (27 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 28/90] target/sparc: Move WRTBR, WRHPR " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 30/90] target/sparc: Move ADDC " Richard Henderson
` (61 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move ADD, AND, OR, XOR, SUB, ANDN, ORN, XORN.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 20 ++++-
target/sparc/translate.c | 183 +++++++++++++++++---------------------
2 files changed, 99 insertions(+), 104 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 49270705c7..4005ce3df7 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -28,6 +28,7 @@ CALL 01 i:s30
&r_r_ri rd rs1 rs2_or_imm imm:bool
@n_r_ri .. ..... ...... rs1:5 imm:1 rs2_or_imm:s13 &r_r_ri rd=0
+@r_r_ri .. rd:5 ...... rs1:5 imm:1 rs2_or_imm:s13 &r_r_ri
{
[
@@ -152,4 +153,21 @@ WRHPR_hintp 10 00011 110011 ..... . ............. @n_r_ri
WRHPR_htba 10 00101 110011 ..... . ............. @n_r_ri
WRHPR_hstick_cmpr 10 11111 110011 ..... . ............. @n_r_ri
-Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
+ADD 10 ..... 000000 ..... . ............. @r_r_ri
+ADDcc 10 ..... 010000 ..... . ............. @r_r_ri
+AND 10 ..... 000001 ..... . ............. @r_r_ri
+ANDcc 10 ..... 010001 ..... . ............. @r_r_ri
+OR 10 ..... 000010 ..... . ............. @r_r_ri
+ORcc 10 ..... 010010 ..... . ............. @r_r_ri
+XOR 10 ..... 000011 ..... . ............. @r_r_ri
+XORcc 10 ..... 010011 ..... . ............. @r_r_ri
+SUB 10 ..... 000100 ..... . ............. @r_r_ri
+SUBcc 10 ..... 010100 ..... . ............. @r_r_ri
+ANDN 10 ..... 000101 ..... . ............. @r_r_ri
+ANDNcc 10 ..... 010101 ..... . ............. @r_r_ri
+ORN 10 ..... 000110 ..... . ............. @r_r_ri
+ORNcc 10 ..... 010110 ..... . ............. @r_r_ri
+XORN 10 ..... 000111 ..... . ............. @r_r_ri
+XORNcc 10 ..... 010111 ..... . ............. @r_r_ri
+
+Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 428fbb49bd..368bafc99a 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4113,6 +4113,86 @@ static bool trans_NOP_v7(DisasContext *dc, arg_NOP_v7 *a)
return false;
}
+static bool do_cc_arith(DisasContext *dc, arg_r_r_ri *a, int cc_op,
+ void (*func)(TCGv, TCGv, TCGv),
+ void (*funci)(TCGv, TCGv, target_long))
+{
+ TCGv dst, src1;
+
+ /* For simplicity, we under-decoded the rs2 form. */
+ if (!a->imm && a->rs2_or_imm & ~0x1f) {
+ return false;
+ }
+
+ if (cc_op < 0) {
+ dst = gen_dest_gpr(dc, a->rd);
+ } else {
+ dst = cpu_cc_dst;
+ tcg_gen_movi_i32(cpu_cc_op, cc_op);
+ dc->cc_op = cc_op;
+ }
+ src1 = gen_load_gpr(dc, a->rs1);
+
+ if (a->imm || a->rs2_or_imm == 0) {
+ if (funci) {
+ funci(dst, src1, a->rs2_or_imm);
+ } else {
+ func(dst, src1, tcg_constant_tl(a->rs2_or_imm));
+ }
+ } else {
+ func(dst, src1, cpu_regs[a->rs2_or_imm]);
+ }
+ gen_store_gpr(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+static bool do_arith(DisasContext *dc, arg_r_r_ri *a,
+ void (*func)(TCGv, TCGv, TCGv),
+ void (*funci)(TCGv, TCGv, target_long))
+{
+ return do_cc_arith(dc, a, -1, func, funci);
+}
+
+static bool trans_OR(DisasContext *dc, arg_r_r_ri *a)
+{
+ /* For simplicity, we under-decoded the rs2 form. */
+ if (!a->imm && a->rs2_or_imm & ~0x1f) {
+ return false;
+ }
+
+ /* OR with %g0 is the canonical alias for MOV. */
+ if (a->rs1 == 0) {
+ TCGv src2;
+
+ if (a->imm || a->rs2_or_imm == 0) {
+ src2 = tcg_constant_tl(a->rs2_or_imm);
+ } else {
+ src2 = cpu_regs[a->rs2_or_imm];
+ }
+ gen_store_gpr(dc, a->rd, src2);
+ return advance_pc(dc);
+ }
+
+ return do_arith(dc, a, tcg_gen_or_tl, tcg_gen_ori_tl);
+}
+
+TRANS(ADD, ALL, do_arith, a, tcg_gen_add_tl, tcg_gen_addi_tl)
+TRANS(AND, ALL, do_arith, a, tcg_gen_and_tl, tcg_gen_andi_tl)
+TRANS(XOR, ALL, do_arith, a, tcg_gen_xor_tl, tcg_gen_xori_tl)
+TRANS(SUB, ALL, do_arith, a, tcg_gen_sub_tl, tcg_gen_subi_tl)
+TRANS(ANDN, ALL, do_arith, a, tcg_gen_andc_tl, NULL)
+TRANS(ORN, ALL, do_arith, a, tcg_gen_orc_tl, NULL)
+TRANS(XORN, ALL, do_arith, a, tcg_gen_eqv_tl, NULL)
+
+TRANS(ADDcc, ALL, do_cc_arith, a, CC_OP_ADD, gen_op_add_cc, NULL)
+TRANS(ANDcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_and_tl, tcg_gen_andi_tl)
+TRANS(ORcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_or_tl, tcg_gen_ori_tl)
+TRANS(XORcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_xor_tl, tcg_gen_xori_tl)
+TRANS(SUBcc, ALL, do_cc_arith, a, CC_OP_SUB, gen_op_sub_cc, NULL)
+TRANS(ANDNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_andc_tl, NULL)
+TRANS(ORNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_orc_tl, NULL)
+TRANS(XORNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_eqv_tl, NULL)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4461,43 +4541,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
default:
goto illegal_insn;
}
- } else if (xop == 0x2) {
- TCGv dst = gen_dest_gpr(dc, rd);
- rs1 = GET_FIELD(insn, 13, 17);
- if (rs1 == 0) {
- /* clr/mov shortcut : or %g0, x, y -> mov x, y */
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 19, 31);
- tcg_gen_movi_tl(dst, simm);
- gen_store_gpr(dc, rd, dst);
- } else { /* register */
- rs2 = GET_FIELD(insn, 27, 31);
- if (rs2 == 0) {
- tcg_gen_movi_tl(dst, 0);
- gen_store_gpr(dc, rd, dst);
- } else {
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_store_gpr(dc, rd, cpu_src2);
- }
- }
- } else {
- cpu_src1 = get_src1(dc, insn);
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 19, 31);
- tcg_gen_ori_tl(dst, cpu_src1, simm);
- gen_store_gpr(dc, rd, dst);
- } else { /* register */
- rs2 = GET_FIELD(insn, 27, 31);
- if (rs2 == 0) {
- /* mov shortcut: or x, %g0, y -> mov x, y */
- gen_store_gpr(dc, rd, cpu_src1);
- } else {
- cpu_src2 = gen_load_gpr(dc, rs2);
- tcg_gen_or_tl(dst, cpu_src1, cpu_src2);
- gen_store_gpr(dc, rd, dst);
- }
- }
- }
#ifdef TARGET_SPARC64
} else if (xop == 0x25) { /* sll, V9 sllx */
cpu_src1 = get_src1(dc, insn);
@@ -4574,72 +4617,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src1 = get_src1(dc, insn);
cpu_src2 = get_src2(dc, insn);
switch (xop & ~0x10) {
- case 0x0: /* add */
- if (xop & 0x10) {
- gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
- dc->cc_op = CC_OP_ADD;
- } else {
- tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
- }
- break;
- case 0x1: /* and */
- tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
- if (xop & 0x10) {
- tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
- dc->cc_op = CC_OP_LOGIC;
- }
- break;
- case 0x2: /* or */
- tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
- if (xop & 0x10) {
- tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
- dc->cc_op = CC_OP_LOGIC;
- }
- break;
- case 0x3: /* xor */
- tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
- if (xop & 0x10) {
- tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
- dc->cc_op = CC_OP_LOGIC;
- }
- break;
- case 0x4: /* sub */
- if (xop & 0x10) {
- gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
- dc->cc_op = CC_OP_SUB;
- } else {
- tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
- }
- break;
- case 0x5: /* andn */
- tcg_gen_andc_tl(cpu_dst, cpu_src1, cpu_src2);
- if (xop & 0x10) {
- tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
- dc->cc_op = CC_OP_LOGIC;
- }
- break;
- case 0x6: /* orn */
- tcg_gen_orc_tl(cpu_dst, cpu_src1, cpu_src2);
- if (xop & 0x10) {
- tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
- dc->cc_op = CC_OP_LOGIC;
- }
- break;
- case 0x7: /* xorn */
- tcg_gen_eqv_tl(cpu_dst, cpu_src1, cpu_src2);
- if (xop & 0x10) {
- tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
- dc->cc_op = CC_OP_LOGIC;
- }
- break;
case 0x8: /* addx, V9 addc */
gen_op_addx_int(dc, cpu_dst, cpu_src1, cpu_src2,
(xop & 0x10));
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 30/90] target/sparc: Move ADDC to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (28 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 29/90] target/sparc: Move basic arithmetic " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 31/90] target/sparc: Move MULX " Richard Henderson
` (60 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 41 +++++++++++++++++++++++++++++++++++----
2 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 4005ce3df7..abcee27fd4 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -169,5 +169,7 @@ ORN 10 ..... 000110 ..... . ............. @r_r_ri
ORNcc 10 ..... 010110 ..... . ............. @r_r_ri
XORN 10 ..... 000111 ..... . ............. @r_r_ri
XORNcc 10 ..... 010111 ..... . ............. @r_r_ri
+ADDC 10 ..... 001000 ..... . ............. @r_r_ri
+ADDCcc 10 ..... 011000 ..... . ............. @r_r_ri
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 368bafc99a..27375c74ec 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4193,6 +4193,43 @@ TRANS(ANDNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_andc_tl, NULL)
TRANS(ORNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_orc_tl, NULL)
TRANS(XORNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_eqv_tl, NULL)
+static TCGv gen_rs2_or_imm(DisasContext *dc, bool imm, int rs2_or_imm)
+{
+ /* For simplicity, we under-decoded the rs2 form. */
+ if (!imm && rs2_or_imm & ~0x1f) {
+ return NULL;
+ }
+ if (imm || rs2_or_imm == 0) {
+ return tcg_constant_tl(rs2_or_imm);
+ } else {
+ return cpu_regs[rs2_or_imm];
+ }
+}
+
+static bool trans_ADDC(DisasContext *dc, arg_r_r_ri *a)
+{
+ TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
+
+ if (src2 == NULL) {
+ return false;
+ }
+ gen_op_addx_int(dc, gen_dest_gpr(dc, a->rd),
+ gen_load_gpr(dc, a->rs1), src2, false);
+ return advance_pc(dc);
+}
+
+static bool trans_ADDCcc(DisasContext *dc, arg_r_r_ri *a)
+{
+ TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
+
+ if (src2 == NULL) {
+ return false;
+ }
+ gen_op_addx_int(dc, gen_dest_gpr(dc, a->rd),
+ gen_load_gpr(dc, a->rs1), src2, true);
+ return advance_pc(dc);
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4617,10 +4654,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src1 = get_src1(dc, insn);
cpu_src2 = get_src2(dc, insn);
switch (xop & ~0x10) {
- case 0x8: /* addx, V9 addc */
- gen_op_addx_int(dc, cpu_dst, cpu_src1, cpu_src2,
- (xop & 0x10));
- break;
#ifdef TARGET_SPARC64
case 0x9: /* V9 mulx */
tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 31/90] target/sparc: Move MULX to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (29 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 30/90] target/sparc: Move ADDC " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 32/90] target/sparc: Move UMUL, SMUL " Richard Henderson
` (59 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 1 +
target/sparc/translate.c | 6 +-----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index abcee27fd4..d9474d2a20 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -171,5 +171,6 @@ XORN 10 ..... 000111 ..... . ............. @r_r_ri
XORNcc 10 ..... 010111 ..... . ............. @r_r_ri
ADDC 10 ..... 001000 ..... . ............. @r_r_ri
ADDCcc 10 ..... 011000 ..... . ............. @r_r_ri
+MULX 10 ..... 001001 ..... . ............. @r_r_ri
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 27375c74ec..b3ce3947f3 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4183,6 +4183,7 @@ TRANS(SUB, ALL, do_arith, a, tcg_gen_sub_tl, tcg_gen_subi_tl)
TRANS(ANDN, ALL, do_arith, a, tcg_gen_andc_tl, NULL)
TRANS(ORN, ALL, do_arith, a, tcg_gen_orc_tl, NULL)
TRANS(XORN, ALL, do_arith, a, tcg_gen_eqv_tl, NULL)
+TRANS(MULX, 64, do_arith, a, tcg_gen_mul_tl, tcg_gen_muli_tl)
TRANS(ADDcc, ALL, do_cc_arith, a, CC_OP_ADD, gen_op_add_cc, NULL)
TRANS(ANDcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_and_tl, tcg_gen_andi_tl)
@@ -4654,11 +4655,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src1 = get_src1(dc, insn);
cpu_src2 = get_src2(dc, insn);
switch (xop & ~0x10) {
-#ifdef TARGET_SPARC64
- case 0x9: /* V9 mulx */
- tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
- break;
-#endif
case 0xa: /* umul */
CHECK_IU_FEATURE(dc, MUL);
gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 32/90] target/sparc: Move UMUL, SMUL to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (30 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 31/90] target/sparc: Move MULX " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 33/90] target/sparc: Move SUBC " Richard Henderson
` (58 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 ++++
target/sparc/translate.c | 23 +++++------------------
2 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index d9474d2a20..c114a13f1d 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -172,5 +172,9 @@ XORNcc 10 ..... 010111 ..... . ............. @r_r_ri
ADDC 10 ..... 001000 ..... . ............. @r_r_ri
ADDCcc 10 ..... 011000 ..... . ............. @r_r_ri
MULX 10 ..... 001001 ..... . ............. @r_r_ri
+UMUL 10 ..... 001010 ..... . ............. @r_r_ri
+UMULcc 10 ..... 011010 ..... . ............. @r_r_ri
+SMUL 10 ..... 001011 ..... . ............. @r_r_ri
+SMULcc 10 ..... 011011 ..... . ............. @r_r_ri
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index b3ce3947f3..b6ec7d5cfd 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2859,6 +2859,7 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
#define avail_ASR17(C) ((C)->def->features & CPU_FEATURE_ASR17)
#define avail_GL(C) ((C)->def->features & CPU_FEATURE_GL)
#define avail_HYPV(C) ((C)->def->features & CPU_FEATURE_HYPV)
+#define avail_MUL(C) ((C)->def->features & CPU_FEATURE_MUL)
#define avail_POWERDOWN(C) ((C)->def->features & CPU_FEATURE_POWERDOWN)
/* Default case for non jump instructions. */
@@ -4184,6 +4185,8 @@ TRANS(ANDN, ALL, do_arith, a, tcg_gen_andc_tl, NULL)
TRANS(ORN, ALL, do_arith, a, tcg_gen_orc_tl, NULL)
TRANS(XORN, ALL, do_arith, a, tcg_gen_eqv_tl, NULL)
TRANS(MULX, 64, do_arith, a, tcg_gen_mul_tl, tcg_gen_muli_tl)
+TRANS(UMUL, MUL, do_arith, a, gen_op_umul, NULL)
+TRANS(SMUL, MUL, do_arith, a, gen_op_smul, NULL)
TRANS(ADDcc, ALL, do_cc_arith, a, CC_OP_ADD, gen_op_add_cc, NULL)
TRANS(ANDcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_and_tl, tcg_gen_andi_tl)
@@ -4193,6 +4196,8 @@ TRANS(SUBcc, ALL, do_cc_arith, a, CC_OP_SUB, gen_op_sub_cc, NULL)
TRANS(ANDNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_andc_tl, NULL)
TRANS(ORNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_orc_tl, NULL)
TRANS(XORNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_eqv_tl, NULL)
+TRANS(UMULcc, MUL, do_cc_arith, a, CC_OP_LOGIC, gen_op_umul, NULL)
+TRANS(SMULcc, MUL, do_cc_arith, a, CC_OP_LOGIC, gen_op_smul, NULL)
static TCGv gen_rs2_or_imm(DisasContext *dc, bool imm, int rs2_or_imm)
{
@@ -4655,24 +4660,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src1 = get_src1(dc, insn);
cpu_src2 = get_src2(dc, insn);
switch (xop & ~0x10) {
- case 0xa: /* umul */
- CHECK_IU_FEATURE(dc, MUL);
- gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
- if (xop & 0x10) {
- tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
- dc->cc_op = CC_OP_LOGIC;
- }
- break;
- case 0xb: /* smul */
- CHECK_IU_FEATURE(dc, MUL);
- gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
- if (xop & 0x10) {
- tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
- dc->cc_op = CC_OP_LOGIC;
- }
- break;
case 0xc: /* subx, V9 subc */
gen_op_subx_int(dc, cpu_dst, cpu_src1, cpu_src2,
(xop & 0x10));
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 33/90] target/sparc: Move SUBC to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (31 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 32/90] target/sparc: Move UMUL, SMUL " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 34/90] target/sparc: Move UDIVX, SDIVX " Richard Henderson
` (57 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 28 ++++++++++++++++++++++++----
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index c114a13f1d..64f5885e67 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -176,5 +176,7 @@ UMUL 10 ..... 001010 ..... . ............. @r_r_ri
UMULcc 10 ..... 011010 ..... . ............. @r_r_ri
SMUL 10 ..... 001011 ..... . ............. @r_r_ri
SMULcc 10 ..... 011011 ..... . ............. @r_r_ri
+SUBC 10 ..... 001100 ..... . ............. @r_r_ri
+SUBCcc 10 ..... 011100 ..... . ............. @r_r_ri
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index b6ec7d5cfd..30eb9bf94b 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4236,6 +4236,30 @@ static bool trans_ADDCcc(DisasContext *dc, arg_r_r_ri *a)
return advance_pc(dc);
}
+static bool trans_SUBC(DisasContext *dc, arg_r_r_ri *a)
+{
+ TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
+
+ if (src2 == NULL) {
+ return false;
+ }
+ gen_op_subx_int(dc, gen_dest_gpr(dc, a->rd),
+ gen_load_gpr(dc, a->rs1), src2, false);
+ return advance_pc(dc);
+}
+
+static bool trans_SUBCcc(DisasContext *dc, arg_r_r_ri *a)
+{
+ TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
+
+ if (src2 == NULL) {
+ return false;
+ }
+ gen_op_subx_int(dc, gen_dest_gpr(dc, a->rd),
+ gen_load_gpr(dc, a->rs1), src2, true);
+ return advance_pc(dc);
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4660,10 +4684,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src1 = get_src1(dc, insn);
cpu_src2 = get_src2(dc, insn);
switch (xop & ~0x10) {
- case 0xc: /* subx, V9 subc */
- gen_op_subx_int(dc, cpu_dst, cpu_src1, cpu_src2,
- (xop & 0x10));
- break;
#ifdef TARGET_SPARC64
case 0xd: /* V9 udivx */
gen_helper_udivx(cpu_dst, tcg_env, cpu_src1, cpu_src2);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 34/90] target/sparc: Move UDIVX, SDIVX to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (32 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 33/90] target/sparc: Move SUBC " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 35/90] target/sparc: Move UDIV, SDIV " Richard Henderson
` (56 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 23 ++++++++++++++---------
2 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 64f5885e67..a2512d8d47 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -178,5 +178,7 @@ SMUL 10 ..... 001011 ..... . ............. @r_r_ri
SMULcc 10 ..... 011011 ..... . ............. @r_r_ri
SUBC 10 ..... 001100 ..... . ............. @r_r_ri
SUBCcc 10 ..... 011100 ..... . ............. @r_r_ri
+UDIVX 10 ..... 001101 ..... . ............. @r_r_ri
+SDIVX 10 ..... 101101 ..... . ............. @r_r_ri
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 30eb9bf94b..c2e4172872 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -53,6 +53,8 @@
#define gen_helper_write_softint(E, S) qemu_build_not_reached()
#define gen_helper_saved ({ qemu_build_not_reached(); NULL; })
#define gen_helper_restored ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_udivx(D, E, A, B) qemu_build_not_reached()
+#define gen_helper_sdivx(D, E, A, B) qemu_build_not_reached()
#endif
/* Dynamic PC, must exit to main loop. */
@@ -643,6 +645,16 @@ static void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
gen_op_multiply(dst, src1, src2, 1);
}
+static void gen_op_udivx(TCGv dst, TCGv src1, TCGv src2)
+{
+ gen_helper_udivx(dst, tcg_env, src1, src2);
+}
+
+static void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
+{
+ gen_helper_sdivx(dst, tcg_env, src1, src2);
+}
+
// 1
static void gen_op_eval_ba(TCGv dst)
{
@@ -4187,6 +4199,8 @@ TRANS(XORN, ALL, do_arith, a, tcg_gen_eqv_tl, NULL)
TRANS(MULX, 64, do_arith, a, tcg_gen_mul_tl, tcg_gen_muli_tl)
TRANS(UMUL, MUL, do_arith, a, gen_op_umul, NULL)
TRANS(SMUL, MUL, do_arith, a, gen_op_smul, NULL)
+TRANS(UDIVX, 64, do_arith, a, gen_op_udivx, NULL)
+TRANS(SDIVX, 64, do_arith, a, gen_op_sdivx, NULL)
TRANS(ADDcc, ALL, do_cc_arith, a, CC_OP_ADD, gen_op_add_cc, NULL)
TRANS(ANDcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_and_tl, tcg_gen_andi_tl)
@@ -4684,11 +4698,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src1 = get_src1(dc, insn);
cpu_src2 = get_src2(dc, insn);
switch (xop & ~0x10) {
-#ifdef TARGET_SPARC64
- case 0xd: /* V9 udivx */
- gen_helper_udivx(cpu_dst, tcg_env, cpu_src1, cpu_src2);
- break;
-#endif
case 0xe: /* udiv */
CHECK_IU_FEATURE(dc, DIV);
if (xop & 0x10) {
@@ -4826,10 +4835,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
gen_store_gpr(dc, rd, dst);
break;
}
- case 0x2d: /* V9 sdivx */
- gen_helper_sdivx(cpu_dst, tcg_env, cpu_src1, cpu_src2);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x2e: /* V9 popc */
tcg_gen_ctpop_tl(cpu_dst, cpu_src2);
gen_store_gpr(dc, rd, cpu_dst);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 35/90] target/sparc: Move UDIV, SDIV to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (33 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 34/90] target/sparc: Move UDIVX, SDIVX " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 36/90] target/sparc: Move TADD, TSUB, MULS " Richard Henderson
` (55 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 +++
target/sparc/translate.c | 66 ++++++++++++++++++++++-----------------
2 files changed, 41 insertions(+), 29 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index a2512d8d47..7d1afb2a87 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -180,5 +180,9 @@ SUBC 10 ..... 001100 ..... . ............. @r_r_ri
SUBCcc 10 ..... 011100 ..... . ............. @r_r_ri
UDIVX 10 ..... 001101 ..... . ............. @r_r_ri
SDIVX 10 ..... 101101 ..... . ............. @r_r_ri
+UDIV 10 ..... 001110 ..... . ............. @r_r_ri
+UDIVcc 10 ..... 011110 ..... . ............. @r_r_ri
+SDIV 10 ..... 001111 ..... . ............. @r_r_ri
+SDIVcc 10 ..... 011111 ..... . ............. @r_r_ri
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index c2e4172872..d57df60170 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -655,6 +655,26 @@ static void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
gen_helper_sdivx(dst, tcg_env, src1, src2);
}
+static void gen_op_udiv(TCGv dst, TCGv src1, TCGv src2)
+{
+ gen_helper_udiv(dst, tcg_env, src1, src2);
+}
+
+static void gen_op_sdiv(TCGv dst, TCGv src1, TCGv src2)
+{
+ gen_helper_sdiv(dst, tcg_env, src1, src2);
+}
+
+static void gen_op_udivcc(TCGv dst, TCGv src1, TCGv src2)
+{
+ gen_helper_udiv_cc(dst, tcg_env, src1, src2);
+}
+
+static void gen_op_sdivcc(TCGv dst, TCGv src1, TCGv src2)
+{
+ gen_helper_sdiv_cc(dst, tcg_env, src1, src2);
+}
+
// 1
static void gen_op_eval_ba(TCGv dst)
{
@@ -2869,6 +2889,7 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
# define avail_64(C) false
#endif
#define avail_ASR17(C) ((C)->def->features & CPU_FEATURE_ASR17)
+#define avail_DIV(C) ((C)->def->features & CPU_FEATURE_DIV)
#define avail_GL(C) ((C)->def->features & CPU_FEATURE_GL)
#define avail_HYPV(C) ((C)->def->features & CPU_FEATURE_HYPV)
#define avail_MUL(C) ((C)->def->features & CPU_FEATURE_MUL)
@@ -4166,6 +4187,17 @@ static bool do_arith(DisasContext *dc, arg_r_r_ri *a,
return do_cc_arith(dc, a, -1, func, funci);
}
+static bool do_flags_arith(DisasContext *dc, arg_r_r_ri *a, int cc_op,
+ void (*func)(TCGv, TCGv, TCGv))
+{
+ if (do_arith(dc, a, func, NULL)) {
+ /* Assume FUNC has set env->cc_op and all cc_foo variables. */
+ dc->cc_op = cc_op;
+ return true;
+ }
+ return false;
+}
+
static bool trans_OR(DisasContext *dc, arg_r_r_ri *a)
{
/* For simplicity, we under-decoded the rs2 form. */
@@ -4201,6 +4233,8 @@ TRANS(UMUL, MUL, do_arith, a, gen_op_umul, NULL)
TRANS(SMUL, MUL, do_arith, a, gen_op_smul, NULL)
TRANS(UDIVX, 64, do_arith, a, gen_op_udivx, NULL)
TRANS(SDIVX, 64, do_arith, a, gen_op_sdivx, NULL)
+TRANS(UDIV, DIV, do_arith, a, gen_op_udiv, NULL)
+TRANS(SDIV, DIV, do_arith, a, gen_op_sdiv, NULL)
TRANS(ADDcc, ALL, do_cc_arith, a, CC_OP_ADD, gen_op_add_cc, NULL)
TRANS(ANDcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_and_tl, tcg_gen_andi_tl)
@@ -4212,6 +4246,8 @@ TRANS(ORNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_orc_tl, NULL)
TRANS(XORNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_eqv_tl, NULL)
TRANS(UMULcc, MUL, do_cc_arith, a, CC_OP_LOGIC, gen_op_umul, NULL)
TRANS(SMULcc, MUL, do_cc_arith, a, CC_OP_LOGIC, gen_op_smul, NULL)
+TRANS(UDIVcc, DIV, do_flags_arith, a, CC_OP_DIV, gen_op_udivcc)
+TRANS(SDIVcc, DIV, do_flags_arith, a, CC_OP_DIV, gen_op_sdivcc)
static TCGv gen_rs2_or_imm(DisasContext *dc, bool imm, int rs2_or_imm)
{
@@ -4695,35 +4731,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
#endif
} else if (xop < 0x36) {
if (xop < 0x20) {
- cpu_src1 = get_src1(dc, insn);
- cpu_src2 = get_src2(dc, insn);
- switch (xop & ~0x10) {
- case 0xe: /* udiv */
- CHECK_IU_FEATURE(dc, DIV);
- if (xop & 0x10) {
- gen_helper_udiv_cc(cpu_dst, tcg_env, cpu_src1,
- cpu_src2);
- dc->cc_op = CC_OP_DIV;
- } else {
- gen_helper_udiv(cpu_dst, tcg_env, cpu_src1,
- cpu_src2);
- }
- break;
- case 0xf: /* sdiv */
- CHECK_IU_FEATURE(dc, DIV);
- if (xop & 0x10) {
- gen_helper_sdiv_cc(cpu_dst, tcg_env, cpu_src1,
- cpu_src2);
- dc->cc_op = CC_OP_DIV;
- } else {
- gen_helper_sdiv(cpu_dst, tcg_env, cpu_src1,
- cpu_src2);
- }
- break;
- default:
- goto illegal_insn;
- }
- gen_store_gpr(dc, rd, cpu_dst);
+ goto illegal_insn;
} else {
cpu_src1 = get_src1(dc, insn);
cpu_src2 = get_src2(dc, insn);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 36/90] target/sparc: Move TADD, TSUB, MULS to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (34 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 35/90] target/sparc: Move UDIV, SDIV " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 37/90] target/sparc: Move SLL, SRL, SRA " Richard Henderson
` (54 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 5 +++++
target/sparc/translate.c | 47 +++++++++++++++++----------------------
2 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 7d1afb2a87..18e2372928 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -184,5 +184,10 @@ UDIV 10 ..... 001110 ..... . ............. @r_r_ri
UDIVcc 10 ..... 011110 ..... . ............. @r_r_ri
SDIV 10 ..... 001111 ..... . ............. @r_r_ri
SDIVcc 10 ..... 011111 ..... . ............. @r_r_ri
+TADDcc 10 ..... 100000 ..... . ............. @r_r_ri
+TSUBcc 10 ..... 100001 ..... . ............. @r_r_ri
+TADDccTV 10 ..... 100010 ..... . ............. @r_r_ri
+TSUBccTV 10 ..... 100011 ..... . ............. @r_r_ri
+MULScc 10 ..... 100100 ..... . ............. @r_r_ri
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index d57df60170..4adf2cc3ae 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -675,6 +675,16 @@ static void gen_op_sdivcc(TCGv dst, TCGv src1, TCGv src2)
gen_helper_sdiv_cc(dst, tcg_env, src1, src2);
}
+static void gen_op_taddcctv(TCGv dst, TCGv src1, TCGv src2)
+{
+ gen_helper_taddcctv(dst, tcg_env, src1, src2);
+}
+
+static void gen_op_tsubcctv(TCGv dst, TCGv src1, TCGv src2)
+{
+ gen_helper_tsubcctv(dst, tcg_env, src1, src2);
+}
+
// 1
static void gen_op_eval_ba(TCGv dst)
{
@@ -4248,6 +4258,10 @@ TRANS(UMULcc, MUL, do_cc_arith, a, CC_OP_LOGIC, gen_op_umul, NULL)
TRANS(SMULcc, MUL, do_cc_arith, a, CC_OP_LOGIC, gen_op_smul, NULL)
TRANS(UDIVcc, DIV, do_flags_arith, a, CC_OP_DIV, gen_op_udivcc)
TRANS(SDIVcc, DIV, do_flags_arith, a, CC_OP_DIV, gen_op_sdivcc)
+TRANS(TADDcc, ALL, do_cc_arith, a, CC_OP_TADD, gen_op_add_cc, NULL)
+TRANS(TSUBcc, ALL, do_cc_arith, a, CC_OP_TSUB, gen_op_sub_cc, NULL)
+TRANS(TADDccTV, ALL, do_flags_arith, a, CC_OP_TADDTV, gen_op_taddcctv)
+TRANS(TSUBccTV, ALL, do_flags_arith, a, CC_OP_TSUBTV, gen_op_tsubcctv)
static TCGv gen_rs2_or_imm(DisasContext *dc, bool imm, int rs2_or_imm)
{
@@ -4310,6 +4324,12 @@ static bool trans_SUBCcc(DisasContext *dc, arg_r_r_ri *a)
return advance_pc(dc);
}
+static bool trans_MULScc(DisasContext *dc, arg_r_r_ri *a)
+{
+ update_psr(dc);
+ return do_cc_arith(dc, a, CC_OP_ADD, gen_op_mulscc, NULL);
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4737,36 +4757,11 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src2 = get_src2(dc, insn);
switch (xop) {
case 0x20: /* taddcc */
- gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
- gen_store_gpr(dc, rd, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD);
- dc->cc_op = CC_OP_TADD;
- break;
case 0x21: /* tsubcc */
- gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
- gen_store_gpr(dc, rd, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB);
- dc->cc_op = CC_OP_TSUB;
- break;
case 0x22: /* taddcctv */
- gen_helper_taddcctv(cpu_dst, tcg_env,
- cpu_src1, cpu_src2);
- gen_store_gpr(dc, rd, cpu_dst);
- dc->cc_op = CC_OP_TADDTV;
- break;
case 0x23: /* tsubcctv */
- gen_helper_tsubcctv(cpu_dst, tcg_env,
- cpu_src1, cpu_src2);
- gen_store_gpr(dc, rd, cpu_dst);
- dc->cc_op = CC_OP_TSUBTV;
- break;
case 0x24: /* mulscc */
- update_psr(dc);
- gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
- gen_store_gpr(dc, rd, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
- dc->cc_op = CC_OP_ADD;
- break;
+ goto illegal_insn; /* in decodetree */
#ifndef TARGET_SPARC64
case 0x25: /* sll */
if (IS_IMM) { /* immediate */
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 37/90] target/sparc: Move SLL, SRL, SRA to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (35 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 36/90] target/sparc: Move TADD, TSUB, MULS " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 38/90] target/sparc: Move MOVcc, MOVR " Richard Henderson
` (53 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 14 +++
target/sparc/translate.c | 182 ++++++++++++++++----------------------
2 files changed, 92 insertions(+), 104 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 18e2372928..fe0eacd779 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -190,4 +190,18 @@ TADDccTV 10 ..... 100010 ..... . ............. @r_r_ri
TSUBccTV 10 ..... 100011 ..... . ............. @r_r_ri
MULScc 10 ..... 100100 ..... . ............. @r_r_ri
+&shiftr rd rs1 rs2 x:bool
+@shiftr .. rd:5 ...... rs1:5 . x:1 ....... rs2:5 &shiftr
+
+SLL_r 10 ..... 100101 ..... 0 . 0000000 ..... @shiftr
+SRL_r 10 ..... 100110 ..... 0 . 0000000 ..... @shiftr
+SRA_r 10 ..... 100111 ..... 0 . 0000000 ..... @shiftr
+
+&shifti rd rs1 i x:bool
+@shifti .. rd:5 ...... rs1:5 . x:1 ...... i:6 &shifti
+
+SLL_i 10 ..... 100101 ..... 1 . 000000 ...... @shifti
+SRL_i 10 ..... 100110 ..... 1 . 000000 ...... @shifti
+SRA_i 10 ..... 100111 ..... 1 . 000000 ...... @shifti
+
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 4adf2cc3ae..deea3015b1 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4330,6 +4330,83 @@ static bool trans_MULScc(DisasContext *dc, arg_r_r_ri *a)
return do_cc_arith(dc, a, CC_OP_ADD, gen_op_mulscc, NULL);
}
+static bool do_shift_r(DisasContext *dc, arg_shiftr *a, bool l, bool u)
+{
+ TCGv dst, src1, src2;
+
+ /* Reject 64-bit shifts for sparc32. */
+ if (avail_32(dc) && a->x) {
+ return false;
+ }
+
+ src2 = tcg_temp_new();
+ tcg_gen_andi_tl(src2, gen_load_gpr(dc, a->rs2), a->x ? 63 : 31);
+ src1 = gen_load_gpr(dc, a->rs1);
+ dst = gen_dest_gpr(dc, a->rd);
+
+ if (l) {
+ tcg_gen_shl_tl(dst, src1, src2);
+ if (!a->x) {
+ tcg_gen_ext32u_tl(dst, dst);
+ }
+ } else if (u) {
+ if (!a->x) {
+ tcg_gen_ext32u_tl(dst, src1);
+ src1 = dst;
+ }
+ tcg_gen_shr_tl(dst, src1, src2);
+ } else {
+ if (!a->x) {
+ tcg_gen_ext32s_tl(dst, src1);
+ src1 = dst;
+ }
+ tcg_gen_sar_tl(dst, src1, src2);
+ }
+ gen_store_gpr(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(SLL_r, ALL, do_shift_r, a, true, true)
+TRANS(SRL_r, ALL, do_shift_r, a, false, true)
+TRANS(SRA_r, ALL, do_shift_r, a, false, false)
+
+static bool do_shift_i(DisasContext *dc, arg_shifti *a, bool l, bool u)
+{
+ TCGv dst, src1;
+
+ /* Reject 64-bit shifts for sparc32. */
+ if (avail_32(dc) && (a->x || a->i >= 32)) {
+ return false;
+ }
+
+ src1 = gen_load_gpr(dc, a->rs1);
+ dst = gen_dest_gpr(dc, a->rd);
+
+ if (avail_32(dc) || a->x) {
+ if (l) {
+ tcg_gen_shli_tl(dst, src1, a->i);
+ } else if (u) {
+ tcg_gen_shri_tl(dst, src1, a->i);
+ } else {
+ tcg_gen_sari_tl(dst, src1, a->i);
+ }
+ } else {
+ if (l) {
+ tcg_gen_deposit_z_tl(dst, src1, a->i, 32 - a->i);
+ } else if (u) {
+ tcg_gen_extract_tl(dst, src1, a->i, 32 - a->i);
+ } else {
+ tcg_gen_sextract_tl(dst, src1, a->i, 32 - a->i);
+ }
+ }
+ gen_store_gpr(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(SLL_i, ALL, do_shift_i, a, true, true)
+TRANS(SRL_i, ALL, do_shift_i, a, false, true)
+TRANS(SRA_i, ALL, do_shift_i, a, false, false)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4678,77 +4755,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
default:
goto illegal_insn;
}
-#ifdef TARGET_SPARC64
- } else if (xop == 0x25) { /* sll, V9 sllx */
- cpu_src1 = get_src1(dc, insn);
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 20, 31);
- if (insn & (1 << 12)) {
- tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x3f);
- } else {
- tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x1f);
- }
- } else { /* register */
- rs2 = GET_FIELD(insn, 27, 31);
- cpu_src2 = gen_load_gpr(dc, rs2);
- cpu_tmp0 = tcg_temp_new();
- if (insn & (1 << 12)) {
- tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
- } else {
- tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
- }
- tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
- }
- gen_store_gpr(dc, rd, cpu_dst);
- } else if (xop == 0x26) { /* srl, V9 srlx */
- cpu_src1 = get_src1(dc, insn);
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 20, 31);
- if (insn & (1 << 12)) {
- tcg_gen_shri_i64(cpu_dst, cpu_src1, simm & 0x3f);
- } else {
- tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
- tcg_gen_shri_i64(cpu_dst, cpu_dst, simm & 0x1f);
- }
- } else { /* register */
- rs2 = GET_FIELD(insn, 27, 31);
- cpu_src2 = gen_load_gpr(dc, rs2);
- cpu_tmp0 = tcg_temp_new();
- if (insn & (1 << 12)) {
- tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
- tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
- } else {
- tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
- tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
- tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
- }
- }
- gen_store_gpr(dc, rd, cpu_dst);
- } else if (xop == 0x27) { /* sra, V9 srax */
- cpu_src1 = get_src1(dc, insn);
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 20, 31);
- if (insn & (1 << 12)) {
- tcg_gen_sari_i64(cpu_dst, cpu_src1, simm & 0x3f);
- } else {
- tcg_gen_ext32s_i64(cpu_dst, cpu_src1);
- tcg_gen_sari_i64(cpu_dst, cpu_dst, simm & 0x1f);
- }
- } else { /* register */
- rs2 = GET_FIELD(insn, 27, 31);
- cpu_src2 = gen_load_gpr(dc, rs2);
- cpu_tmp0 = tcg_temp_new();
- if (insn & (1 << 12)) {
- tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
- tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
- } else {
- tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
- tcg_gen_ext32s_i64(cpu_dst, cpu_src1);
- tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
- }
- }
- gen_store_gpr(dc, rd, cpu_dst);
-#endif
} else if (xop < 0x36) {
if (xop < 0x20) {
goto illegal_insn;
@@ -4761,42 +4767,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x22: /* taddcctv */
case 0x23: /* tsubcctv */
case 0x24: /* mulscc */
- goto illegal_insn; /* in decodetree */
-#ifndef TARGET_SPARC64
case 0x25: /* sll */
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 20, 31);
- tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f);
- } else { /* register */
- cpu_tmp0 = tcg_temp_new();
- tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
- tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
- }
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x26: /* srl */
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 20, 31);
- tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f);
- } else { /* register */
- cpu_tmp0 = tcg_temp_new();
- tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
- tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
- }
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x27: /* sra */
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 20, 31);
- tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f);
- } else { /* register */
- cpu_tmp0 = tcg_temp_new();
- tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
- tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
- }
- gen_store_gpr(dc, rd, cpu_dst);
- break;
-#endif
+ goto illegal_insn; /* in decodetree */
case 0x30:
goto illegal_insn; /* WRASR in decodetree */
case 0x32:
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 38/90] target/sparc: Move MOVcc, MOVR to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (36 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 37/90] target/sparc: Move SLL, SRL, SRA " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 39/90] target/sparc: Move POPC " Richard Henderson
` (52 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 ++
target/sparc/translate.c | 103 +++++++++++++++++---------------------
2 files changed, 51 insertions(+), 56 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index fe0eacd779..a61d10be5a 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -205,3 +205,7 @@ SRL_i 10 ..... 100110 ..... 1 . 000000 ...... @shifti
SRA_i 10 ..... 100111 ..... 1 . 000000 ...... @shifti
Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
+
+MOVcc 10 rd:5 101100 1 cond:4 imm:1 cc:1 0 rs2_or_imm:s11
+MOVfcc 10 rd:5 101100 0 cond:4 imm:1 cc:2 rs2_or_imm:s11
+MOVR 10 rd:5 101111 rs1:5 imm:1 cond:3 rs2_or_imm:s10
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index deea3015b1..0b0b9aa8d3 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4407,6 +4407,51 @@ TRANS(SLL_i, ALL, do_shift_i, a, true, true)
TRANS(SRL_i, ALL, do_shift_i, a, false, true)
TRANS(SRA_i, ALL, do_shift_i, a, false, false)
+static bool do_mov_cond(DisasContext *dc, DisasCompare *cmp, int rd, TCGv src2)
+{
+ TCGv dst = gen_load_gpr(dc, rd);
+
+ tcg_gen_movcond_tl(cmp->cond, dst, cmp->c1, cmp->c2, src2, dst);
+ gen_store_gpr(dc, rd, dst);
+ return advance_pc(dc);
+}
+
+static bool trans_MOVcc(DisasContext *dc, arg_MOVcc *a)
+{
+ TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
+ DisasCompare cmp;
+
+ if (src2 == NULL) {
+ return false;
+ }
+ gen_compare(&cmp, a->cc, a->cond, dc);
+ return do_mov_cond(dc, &cmp, a->rd, src2);
+}
+
+static bool trans_MOVfcc(DisasContext *dc, arg_MOVfcc *a)
+{
+ TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
+ DisasCompare cmp;
+
+ if (src2 == NULL) {
+ return false;
+ }
+ gen_fcompare(&cmp, a->cc, a->cond);
+ return do_mov_cond(dc, &cmp, a->rd, src2);
+}
+
+static bool trans_MOVR(DisasContext *dc, arg_MOVR *a)
+{
+ TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
+ DisasCompare cmp;
+
+ if (src2 == NULL) {
+ return false;
+ }
+ gen_compare_reg(&cmp, a->cond, gen_load_gpr(dc, a->rs1));
+ return do_mov_cond(dc, &cmp, a->rd, src2);
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4779,66 +4824,12 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
goto illegal_insn; /* WRTBR, WRHPR in decodetree */
#ifdef TARGET_SPARC64
case 0x2c: /* V9 movcc */
- {
- int cc = GET_FIELD_SP(insn, 11, 12);
- int cond = GET_FIELD_SP(insn, 14, 17);
- DisasCompare cmp;
- TCGv dst;
-
- if (insn & (1 << 18)) {
- if (cc == 0) {
- gen_compare(&cmp, 0, cond, dc);
- } else if (cc == 2) {
- gen_compare(&cmp, 1, cond, dc);
- } else {
- goto illegal_insn;
- }
- } else {
- gen_fcompare(&cmp, cc, cond);
- }
-
- /* The get_src2 above loaded the normal 13-bit
- immediate field, not the 11-bit field we have
- in movcc. But it did handle the reg case. */
- if (IS_IMM) {
- simm = GET_FIELD_SPs(insn, 0, 10);
- tcg_gen_movi_tl(cpu_src2, simm);
- }
-
- dst = gen_load_gpr(dc, rd);
- tcg_gen_movcond_tl(cmp.cond, dst,
- cmp.c1, cmp.c2,
- cpu_src2, dst);
- gen_store_gpr(dc, rd, dst);
- break;
- }
+ case 0x2f: /* V9 movr */
+ goto illegal_insn; /* in decodetree */
case 0x2e: /* V9 popc */
tcg_gen_ctpop_tl(cpu_dst, cpu_src2);
gen_store_gpr(dc, rd, cpu_dst);
break;
- case 0x2f: /* V9 movr */
- {
- int cond = GET_FIELD_SP(insn, 10, 12);
- DisasCompare cmp;
- TCGv dst;
-
- gen_compare_reg(&cmp, cond, cpu_src1);
-
- /* The get_src2 above loaded the normal 13-bit
- immediate field, not the 10-bit field we have
- in movr. But it did handle the reg case. */
- if (IS_IMM) {
- simm = GET_FIELD_SPs(insn, 0, 9);
- tcg_gen_movi_tl(cpu_src2, simm);
- }
-
- dst = gen_load_gpr(dc, rd);
- tcg_gen_movcond_tl(cmp.cond, dst,
- cmp.c1, cmp.c2,
- cpu_src2, dst);
- gen_store_gpr(dc, rd, dst);
- break;
- }
#endif
default:
goto illegal_insn;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 39/90] target/sparc: Move POPC to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (37 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 38/90] target/sparc: Move MOVcc, MOVR " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 40/90] target/sparc: Convert remaining v8 coproc insns " Richard Henderson
` (51 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 1 +
target/sparc/translate.c | 55 ++++++---------------------------------
2 files changed, 9 insertions(+), 47 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index a61d10be5a..0c1517f024 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -189,6 +189,7 @@ TSUBcc 10 ..... 100001 ..... . ............. @r_r_ri
TADDccTV 10 ..... 100010 ..... . ............. @r_r_ri
TSUBccTV 10 ..... 100011 ..... . ............. @r_r_ri
MULScc 10 ..... 100100 ..... . ............. @r_r_ri
+POPC 10 rd:5 101110 00000 imm:1 rs2_or_imm:s13 &r_r_ri rs1=0
&shiftr rd rs1 rs2 x:bool
@shiftr .. rd:5 ...... rs1:5 . x:1 ....... rs2:5 &shiftr
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 0b0b9aa8d3..75a2de764e 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -685,6 +685,11 @@ static void gen_op_tsubcctv(TCGv dst, TCGv src1, TCGv src2)
gen_helper_tsubcctv(dst, tcg_env, src1, src2);
}
+static void gen_op_popc(TCGv dst, TCGv src1, TCGv src2)
+{
+ tcg_gen_ctpop_tl(dst, src2);
+}
+
// 1
static void gen_op_eval_ba(TCGv dst)
{
@@ -2678,19 +2683,6 @@ static TCGv get_src1(DisasContext *dc, unsigned int insn)
return gen_load_gpr(dc, rs1);
}
-static TCGv get_src2(DisasContext *dc, unsigned int insn)
-{
- if (IS_IMM) { /* immediate */
- target_long simm = GET_FIELDs(insn, 19, 31);
- TCGv t = tcg_temp_new();
- tcg_gen_movi_tl(t, simm);
- return t;
- } else { /* register */
- unsigned int rs2 = GET_FIELD(insn, 27, 31);
- return gen_load_gpr(dc, rs2);
- }
-}
-
#ifdef TARGET_SPARC64
static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
{
@@ -4245,6 +4237,8 @@ TRANS(UDIVX, 64, do_arith, a, gen_op_udivx, NULL)
TRANS(SDIVX, 64, do_arith, a, gen_op_sdivx, NULL)
TRANS(UDIV, DIV, do_arith, a, gen_op_udiv, NULL)
TRANS(SDIV, DIV, do_arith, a, gen_op_sdiv, NULL)
+/* TODO: Should have feature bit -- comes in with UltraSparc T2. */
+TRANS(POPC, 64, do_arith, a, gen_op_popc, NULL)
TRANS(ADDcc, ALL, do_cc_arith, a, CC_OP_ADD, gen_op_add_cc, NULL)
TRANS(ANDcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_and_tl, tcg_gen_andi_tl)
@@ -4801,40 +4795,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
goto illegal_insn;
}
} else if (xop < 0x36) {
- if (xop < 0x20) {
- goto illegal_insn;
- } else {
- cpu_src1 = get_src1(dc, insn);
- cpu_src2 = get_src2(dc, insn);
- switch (xop) {
- case 0x20: /* taddcc */
- case 0x21: /* tsubcc */
- case 0x22: /* taddcctv */
- case 0x23: /* tsubcctv */
- case 0x24: /* mulscc */
- case 0x25: /* sll */
- case 0x26: /* srl */
- case 0x27: /* sra */
- goto illegal_insn; /* in decodetree */
- case 0x30:
- goto illegal_insn; /* WRASR in decodetree */
- case 0x32:
- goto illegal_insn; /* WRPR in decodetree */
- case 0x33: /* wrtbr, UA2005 wrhpr */
- goto illegal_insn; /* WRTBR, WRHPR in decodetree */
-#ifdef TARGET_SPARC64
- case 0x2c: /* V9 movcc */
- case 0x2f: /* V9 movr */
- goto illegal_insn; /* in decodetree */
- case 0x2e: /* V9 popc */
- tcg_gen_ctpop_tl(cpu_dst, cpu_src2);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
-#endif
- default:
- goto illegal_insn;
- }
- }
+ goto illegal_insn; /* in decodetree */
} else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
#ifdef TARGET_SPARC64
int opf = GET_FIELD_SP(insn, 5, 13);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 40/90] target/sparc: Convert remaining v8 coproc insns to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (38 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 39/90] target/sparc: Move POPC " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 41/90] target/sparc: Move JMPL, RETT, RETURN " Richard Henderson
` (50 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 11 +++++++++++
target/sparc/translate.c | 32 ++++++--------------------------
2 files changed, 17 insertions(+), 26 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 0c1517f024..bdbf6d987c 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -210,3 +210,14 @@ Tcc 10 0 cond:4 111010 rs1:5 imm:1 cc:1 00000 rs2_or_imm:7
MOVcc 10 rd:5 101100 1 cond:4 imm:1 cc:1 0 rs2_or_imm:s11
MOVfcc 10 rd:5 101100 0 cond:4 imm:1 cc:2 rs2_or_imm:s11
MOVR 10 rd:5 101111 rs1:5 imm:1 cond:3 rs2_or_imm:s10
+
+NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
+NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
+
+NCP 11 ----- 110000 ----- --------- ----- # v8 LDC
+NCP 11 ----- 110001 ----- --------- ----- # v8 LDCSR
+NCP 11 ----- 110011 ----- --------- ----- # v8 LDDC
+NCP 11 ----- 110100 ----- --------- ----- # v8 STC
+NCP 11 ----- 110101 ----- --------- ----- # v8 STCSR
+NCP 11 ----- 110110 ----- --------- ----- # v8 STDCQ
+NCP 11 ----- 110111 ----- --------- ----- # v8 STDC
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 75a2de764e..5af642a637 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4796,8 +4796,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
}
} else if (xop < 0x36) {
goto illegal_insn; /* in decodetree */
- } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
+ } else if (xop == 0x36) {
#ifdef TARGET_SPARC64
+ /* VIS */
int opf = GET_FIELD_SP(insn, 5, 13);
rs1 = GET_FIELD(insn, 13, 17);
rs2 = GET_FIELD(insn, 27, 31);
@@ -5237,14 +5238,11 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
goto illegal_insn;
}
#else
- goto ncp_insn;
-#endif
- } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
-#ifdef TARGET_SPARC64
- goto illegal_insn;
-#else
- goto ncp_insn;
+ g_assert_not_reached(); /* in decodetree */
#endif
+ } else if (xop == 0x37) {
+ /* V8 CPop2, V9 impdep2 */
+ goto illegal_insn; /* in decodetree */
#ifdef TARGET_SPARC64
} else if (xop == 0x39) { /* V9 return */
save_state(dc);
@@ -5460,13 +5458,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src1 = gen_load_gpr(dc, rd);
gen_swap_asi(dc, cpu_val, cpu_src1, cpu_addr, insn);
break;
-
-#ifndef TARGET_SPARC64
- case 0x30: /* ldc */
- case 0x31: /* ldcsr */
- case 0x33: /* lddc */
- goto ncp_insn;
-#endif
#endif
#ifdef TARGET_SPARC64
case 0x08: /* V9 ldsw */
@@ -5727,12 +5718,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src2 = gen_load_gpr(dc, rs2);
gen_casx_asi(dc, cpu_addr, cpu_src2, insn, rd);
break;
-#else
- case 0x34: /* stc */
- case 0x35: /* stcsr */
- case 0x36: /* stdcq */
- case 0x37: /* stdc */
- goto ncp_insn;
#endif
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
case 0x3c: /* V9 or LEON3 casa */
@@ -5772,11 +5757,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
return;
#endif
-#ifndef TARGET_SPARC64
- ncp_insn:
- gen_exception(dc, TT_NCP_INSN);
- return;
-#endif
}
static void sparc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 41/90] target/sparc: Move JMPL, RETT, RETURN to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (39 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 40/90] target/sparc: Convert remaining v8 coproc insns " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 42/90] target/sparc: Move FLUSH, SAVE, RESTORE " Richard Henderson
` (49 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 6 ++
target/sparc/translate.c | 126 ++++++++++++++++++++++++--------------
2 files changed, 87 insertions(+), 45 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index bdbf6d987c..060ee79db0 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -211,6 +211,12 @@ MOVcc 10 rd:5 101100 1 cond:4 imm:1 cc:1 0 rs2_or_imm:s11
MOVfcc 10 rd:5 101100 0 cond:4 imm:1 cc:2 rs2_or_imm:s11
MOVR 10 rd:5 101111 rs1:5 imm:1 cond:3 rs2_or_imm:s10
+JMPL 10 ..... 111000 ..... . ............. @r_r_ri
+{
+ RETT 10 00000 111001 ..... . ............. @n_r_ri
+ RETURN 10 00000 111001 ..... . ............. @n_r_ri
+}
+
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 5af642a637..bf8d611942 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -40,6 +40,7 @@
#define gen_helper_rdpsr(D, E) qemu_build_not_reached()
#define gen_helper_wrpsr(E, S) qemu_build_not_reached()
#define gen_helper_power_down(E) g_assert_not_reached()
+#define gen_helper_rett(E) qemu_build_not_reached()
#else
#define gen_helper_rdccr(D, E) qemu_build_not_reached()
#define gen_helper_rdcwp(D, E) qemu_build_not_reached()
@@ -4446,6 +4447,85 @@ static bool trans_MOVR(DisasContext *dc, arg_MOVR *a)
return do_mov_cond(dc, &cmp, a->rd, src2);
}
+static bool do_add_special(DisasContext *dc, arg_r_r_ri *a,
+ bool (*func)(DisasContext *dc, int rd, TCGv src))
+{
+ TCGv src1, sum;
+
+ /* For simplicity, we under-decoded the rs2 form. */
+ if (!a->imm && a->rs2_or_imm & ~0x1f) {
+ return false;
+ }
+
+ /*
+ * Always load the sum into a new temporary.
+ * This is required to capture the value across a window change,
+ * e.g. SAVE and RESTORE, and may be optimized away otherwise.
+ */
+ sum = tcg_temp_new();
+ src1 = gen_load_gpr(dc, a->rs1);
+ if (a->imm || a->rs2_or_imm == 0) {
+ tcg_gen_addi_tl(sum, src1, a->rs2_or_imm);
+ } else {
+ tcg_gen_add_tl(sum, src1, cpu_regs[a->rs2_or_imm]);
+ }
+ return func(dc, a->rd, sum);
+}
+
+static bool do_jmpl(DisasContext *dc, int rd, TCGv src)
+{
+ /*
+ * Preserve pc across advance, so that we can delay
+ * the writeback to rd until after src is consumed.
+ */
+ target_ulong cur_pc = dc->pc;
+
+ gen_check_align(dc, src, 3);
+
+ gen_mov_pc_npc(dc);
+ tcg_gen_mov_tl(cpu_npc, src);
+ gen_address_mask(dc, cpu_npc);
+ gen_store_gpr(dc, rd, tcg_constant_tl(cur_pc));
+
+ dc->npc = DYNAMIC_PC_LOOKUP;
+ return true;
+}
+
+TRANS(JMPL, ALL, do_add_special, a, do_jmpl)
+
+static bool do_rett(DisasContext *dc, int rd, TCGv src)
+{
+ if (!supervisor(dc)) {
+ return raise_priv(dc);
+ }
+
+ gen_check_align(dc, src, 3);
+
+ gen_mov_pc_npc(dc);
+ tcg_gen_mov_tl(cpu_npc, src);
+ gen_helper_rett(tcg_env);
+
+ dc->npc = DYNAMIC_PC;
+ return true;
+}
+
+TRANS(RETT, 32, do_add_special, a, do_rett)
+
+static bool do_return(DisasContext *dc, int rd, TCGv src)
+{
+ gen_check_align(dc, src, 3);
+
+ gen_mov_pc_npc(dc);
+ tcg_gen_mov_tl(cpu_npc, src);
+ gen_address_mask(dc, cpu_npc);
+
+ gen_helper_restore(tcg_env);
+ dc->npc = DYNAMIC_PC_LOOKUP;
+ return true;
+}
+
+TRANS(RETURN, 64, do_add_special, a, do_return)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5243,30 +5323,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
} else if (xop == 0x37) {
/* V8 CPop2, V9 impdep2 */
goto illegal_insn; /* in decodetree */
-#ifdef TARGET_SPARC64
- } else if (xop == 0x39) { /* V9 return */
- save_state(dc);
- cpu_src1 = get_src1(dc, insn);
- cpu_tmp0 = tcg_temp_new();
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 19, 31);
- tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
- } else { /* register */
- rs2 = GET_FIELD(insn, 27, 31);
- if (rs2) {
- cpu_src2 = gen_load_gpr(dc, rs2);
- tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
- } else {
- tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
- }
- }
- gen_check_align(dc, cpu_tmp0, 3);
- gen_helper_restore(tcg_env);
- gen_mov_pc_npc(dc);
- tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
- dc->npc = DYNAMIC_PC_LOOKUP;
- goto jmp_insn;
-#endif
} else {
cpu_src1 = get_src1(dc, insn);
cpu_tmp0 = tcg_temp_new();
@@ -5284,28 +5340,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
}
switch (xop) {
case 0x38: /* jmpl */
- {
- gen_check_align(dc, cpu_tmp0, 3);
- gen_store_gpr(dc, rd, tcg_constant_tl(dc->pc));
- gen_mov_pc_npc(dc);
- gen_address_mask(dc, cpu_tmp0);
- tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
- dc->npc = DYNAMIC_PC_LOOKUP;
- }
- goto jmp_insn;
-#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
case 0x39: /* rett, V9 return */
- {
- if (!supervisor(dc))
- goto priv_insn;
- gen_check_align(dc, cpu_tmp0, 3);
- gen_mov_pc_npc(dc);
- tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
- dc->npc = DYNAMIC_PC;
- gen_helper_rett(tcg_env);
- }
- goto jmp_insn;
-#endif
+ g_assert_not_reached(); /* in decode tree */
case 0x3b: /* flush */
/* nop */
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 42/90] target/sparc: Move FLUSH, SAVE, RESTORE to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (40 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 41/90] target/sparc: Move JMPL, RETT, RETURN " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 43/90] target/sparc: Move DONE, RETRY " Richard Henderson
` (48 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 ++++
target/sparc/translate.c | 35 +++++++++++++++++++++++++----------
2 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 060ee79db0..9c4c493630 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -216,6 +216,10 @@ JMPL 10 ..... 111000 ..... . ............. @r_r_ri
RETT 10 00000 111001 ..... . ............. @n_r_ri
RETURN 10 00000 111001 ..... . ............. @n_r_ri
}
+NOP 10 00000 111011 ----- 0 00000000----- # FLUSH reg+reg
+NOP 10 00000 111011 ----- 1 ------------- # FLUSH reg+imm
+SAVE 10 ..... 111100 ..... . ............. @r_r_ri
+RESTORE 10 ..... 111101 ..... . ............. @r_r_ri
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index bf8d611942..5fc46d1b20 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4138,6 +4138,11 @@ static bool do_saved_restored(DisasContext *dc, void (*func)(TCGv_env))
TRANS(SAVED, 64, do_saved_restored, gen_helper_saved)
TRANS(RESTORED, 64, do_saved_restored, gen_helper_restored)
+static bool trans_NOP(DisasContext *dc, arg_NOP *a)
+{
+ return advance_pc(dc);
+}
+
static bool trans_NOP_v7(DisasContext *dc, arg_NOP_v7 *a)
{
/*
@@ -4526,6 +4531,24 @@ static bool do_return(DisasContext *dc, int rd, TCGv src)
TRANS(RETURN, 64, do_add_special, a, do_return)
+static bool do_save(DisasContext *dc, int rd, TCGv src)
+{
+ gen_helper_save(tcg_env);
+ gen_store_gpr(dc, rd, src);
+ return advance_pc(dc);
+}
+
+TRANS(SAVE, ALL, do_add_special, a, do_save)
+
+static bool do_restore(DisasContext *dc, int rd, TCGv src)
+{
+ gen_helper_restore(tcg_env);
+ gen_store_gpr(dc, rd, src);
+ return advance_pc(dc);
+}
+
+TRANS(RESTORE, ALL, do_add_special, a, do_restore)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5341,18 +5364,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
switch (xop) {
case 0x38: /* jmpl */
case 0x39: /* rett, V9 return */
- g_assert_not_reached(); /* in decode tree */
- case 0x3b: /* flush */
- /* nop */
- break;
+ case 0x3b: /* flush */
case 0x3c: /* save */
- gen_helper_save(tcg_env);
- gen_store_gpr(dc, rd, cpu_tmp0);
- break;
case 0x3d: /* restore */
- gen_helper_restore(tcg_env);
- gen_store_gpr(dc, rd, cpu_tmp0);
- break;
+ g_assert_not_reached(); /* in decode tree */
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
case 0x3e: /* V9 done/retry */
{
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 43/90] target/sparc: Move DONE, RETRY to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (41 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 42/90] target/sparc: Move FLUSH, SAVE, RESTORE " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 44/90] target/sparc: Split out resolve_asi Richard Henderson
` (47 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 3 ++
target/sparc/translate.c | 99 +++++++++++++++------------------------
2 files changed, 40 insertions(+), 62 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 9c4c493630..dface4a9dd 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -221,6 +221,9 @@ NOP 10 00000 111011 ----- 1 ------------- # FLUSH reg+imm
SAVE 10 ..... 111100 ..... . ............. @r_r_ri
RESTORE 10 ..... 111101 ..... . ............. @r_r_ri
+DONE 10 00000 111110 00000 0 0000000000000
+RETRY 10 00001 111110 00000 0 0000000000000
+
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 5fc46d1b20..784a019dcf 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -54,6 +54,8 @@
#define gen_helper_write_softint(E, S) qemu_build_not_reached()
#define gen_helper_saved ({ qemu_build_not_reached(); NULL; })
#define gen_helper_restored ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_done(E) qemu_build_not_reached()
+#define gen_helper_retry(E) qemu_build_not_reached()
#define gen_helper_udivx(D, E, A, B) qemu_build_not_reached()
#define gen_helper_sdivx(D, E, A, B) qemu_build_not_reached()
#endif
@@ -4549,6 +4551,36 @@ static bool do_restore(DisasContext *dc, int rd, TCGv src)
TRANS(RESTORE, ALL, do_add_special, a, do_restore)
+static bool trans_DONE(DisasContext *dc, arg_DONE *a)
+{
+ if (!avail_64(dc)) {
+ return false;
+ }
+ if (!supervisor(dc)) {
+ return raise_priv(dc);
+ }
+ dc->npc = DYNAMIC_PC;
+ dc->pc = DYNAMIC_PC;
+ translator_io_start(&dc->base);
+ gen_helper_done(tcg_env);
+ return true;
+}
+
+static bool trans_RETRY(DisasContext *dc, arg_RETRY *a)
+{
+ if (!avail_64(dc)) {
+ return false;
+ }
+ if (!supervisor(dc)) {
+ return raise_priv(dc);
+ }
+ dc->npc = DYNAMIC_PC;
+ dc->pc = DYNAMIC_PC;
+ translator_io_start(&dc->base);
+ gen_helper_retry(tcg_env);
+ return true;
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4560,7 +4592,8 @@ TRANS(RESTORE, ALL, do_add_special, a, do_restore)
static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
{
unsigned int opc, rs1, rs2, rd;
- TCGv cpu_src1, cpu_src2;
+ TCGv cpu_src1;
+ TCGv cpu_src2 __attribute__((unused));
TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
target_long simm;
@@ -4575,9 +4608,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
g_assert_not_reached(); /* in decodetree */
case 2: /* FPU & Logical Operations */
{
- unsigned int xop __attribute__((unused)) = GET_FIELD(insn, 7, 12);
+ unsigned int xop = GET_FIELD(insn, 7, 12);
TCGv cpu_dst __attribute__((unused)) = tcg_temp_new();
- TCGv cpu_tmp0 __attribute__((unused));
if (xop == 0x34) { /* FPU Operations */
if (gen_trap_ifnofpu(dc)) {
@@ -4897,8 +4929,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
default:
goto illegal_insn;
}
- } else if (xop < 0x36) {
- goto illegal_insn; /* in decodetree */
} else if (xop == 0x36) {
#ifdef TARGET_SPARC64
/* VIS */
@@ -5340,65 +5370,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
default:
goto illegal_insn;
}
-#else
- g_assert_not_reached(); /* in decodetree */
#endif
- } else if (xop == 0x37) {
- /* V8 CPop2, V9 impdep2 */
- goto illegal_insn; /* in decodetree */
} else {
- cpu_src1 = get_src1(dc, insn);
- cpu_tmp0 = tcg_temp_new();
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 19, 31);
- tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
- } else { /* register */
- rs2 = GET_FIELD(insn, 27, 31);
- if (rs2) {
- cpu_src2 = gen_load_gpr(dc, rs2);
- tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
- } else {
- tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
- }
- }
- switch (xop) {
- case 0x38: /* jmpl */
- case 0x39: /* rett, V9 return */
- case 0x3b: /* flush */
- case 0x3c: /* save */
- case 0x3d: /* restore */
- g_assert_not_reached(); /* in decode tree */
-#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
- case 0x3e: /* V9 done/retry */
- {
- switch (rd) {
- case 0:
- if (!supervisor(dc))
- goto priv_insn;
- dc->npc = DYNAMIC_PC;
- dc->pc = DYNAMIC_PC;
- translator_io_start(&dc->base);
- gen_helper_done(tcg_env);
- goto jmp_insn;
- case 1:
- if (!supervisor(dc))
- goto priv_insn;
- dc->npc = DYNAMIC_PC;
- dc->pc = DYNAMIC_PC;
- translator_io_start(&dc->base);
- gen_helper_retry(tcg_env);
- goto jmp_insn;
- default:
- goto illegal_insn;
- }
- }
- break;
-#endif
- default:
- goto illegal_insn;
- }
+ goto illegal_insn; /* in decodetree */
}
- break;
}
break;
case 3: /* load/store instructions */
@@ -5795,7 +5770,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
illegal_insn:
gen_exception(dc, TT_ILL_INSN);
return;
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
priv_insn:
gen_exception(dc, TT_PRIV_INSN);
return;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 44/90] target/sparc: Split out resolve_asi
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (42 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 43/90] target/sparc: Move DONE, RETRY " Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:11 ` [PATCH v2 45/90] target/sparc: Drop ifdef around get_asi and friends Richard Henderson
` (46 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 784a019dcf..1d3bfb724e 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1864,15 +1864,25 @@ typedef struct {
MemOp memop;
} DisasASI;
-static DisasASI get_asi(DisasContext *dc, int insn, MemOp memop)
+/*
+ * Build DisasASI.
+ * For asi == -1, treat as non-asi.
+ * For ask == -2, treat as immediate offset (v8 error, v9 %asi).
+ */
+static DisasASI resolve_asi(DisasContext *dc, int asi, MemOp memop)
{
- int asi = GET_FIELD(insn, 19, 26);
ASIType type = GET_ASI_HELPER;
int mem_idx = dc->mem_idx;
+ if (asi == -1) {
+ /* Artificial "non-asi" case. */
+ type = GET_ASI_DIRECT;
+ goto done;
+ }
+
#ifndef TARGET_SPARC64
/* Before v9, all asis are immediate and privileged. */
- if (IS_IMM) {
+ if (asi < 0) {
gen_exception(dc, TT_ILL_INSN);
type = GET_ASI_EXCP;
} else if (supervisor(dc)
@@ -1915,7 +1925,7 @@ static DisasASI get_asi(DisasContext *dc, int insn, MemOp memop)
type = GET_ASI_EXCP;
}
#else
- if (IS_IMM) {
+ if (asi < 0) {
asi = dc->asi;
}
/* With v9, all asis below 0x80 are privileged. */
@@ -2074,9 +2084,16 @@ static DisasASI get_asi(DisasContext *dc, int insn, MemOp memop)
}
#endif
+ done:
return (DisasASI){ type, asi, mem_idx, memop };
}
+static DisasASI get_asi(DisasContext *dc, int insn, MemOp memop)
+{
+ int asi = IS_IMM ? -2 : GET_FIELD(insn, 19, 26);
+ return resolve_asi(dc, asi, memop);
+}
+
static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
int insn, MemOp memop)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 45/90] target/sparc: Drop ifdef around get_asi and friends
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (43 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 44/90] target/sparc: Split out resolve_asi Richard Henderson
@ 2023-10-17 6:11 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 46/90] target/sparc: Split out ldst functions with asi pre-computed Richard Henderson
` (45 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Mark some of the functions as unused, temporarily.
Fix up some tl vs i64 issues revealed in the process.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 187 +++++++++++++++------------------------
1 file changed, 70 insertions(+), 117 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 1d3bfb724e..6404ec5858 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -58,6 +58,18 @@
#define gen_helper_retry(E) qemu_build_not_reached()
#define gen_helper_udivx(D, E, A, B) qemu_build_not_reached()
#define gen_helper_sdivx(D, E, A, B) qemu_build_not_reached()
+# ifdef CONFIG_USER_ONLY
+static void gen_helper_ld_asi(TCGv_i64 r, TCGv_env e, TCGv a,
+ TCGv_i32 asi, TCGv_i32 mop)
+{
+ g_assert_not_reached();
+}
+static void gen_helper_st_asi(TCGv_env e, TCGv a, TCGv_i64 r,
+ TCGv_i32 asi, TCGv_i32 mop)
+{
+ g_assert_not_reached();
+}
+# endif
#endif
/* Dynamic PC, must exit to main loop. */
@@ -1845,7 +1857,6 @@ static void gen_ldstub(DisasContext *dc, TCGv dst, TCGv addr, int mmu_idx)
}
/* asi moves */
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
typedef enum {
GET_ASI_HELPER,
GET_ASI_EXCP,
@@ -2094,8 +2105,8 @@ static DisasASI get_asi(DisasContext *dc, int insn, MemOp memop)
return resolve_asi(dc, asi, memop);
}
-static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
- int insn, MemOp memop)
+static void __attribute__((unused))
+gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn, MemOp memop)
{
DisasASI da = get_asi(dc, insn, memop);
@@ -2129,8 +2140,8 @@ static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
}
}
-static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
- int insn, MemOp memop)
+static void __attribute__((unused))
+gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, int insn, MemOp memop)
{
DisasASI da = get_asi(dc, insn, memop);
@@ -2205,8 +2216,8 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
}
}
-static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src,
- TCGv addr, int insn)
+static void __attribute__((unused))
+gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src, TCGv addr, int insn)
{
DisasASI da = get_asi(dc, insn, MO_TEUL);
@@ -2223,8 +2234,8 @@ static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src,
}
}
-static void gen_cas_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
- int insn, int rd)
+static void __attribute__((unused))
+gen_cas_asi(DisasContext *dc, TCGv addr, TCGv cmpv, int insn, int rd)
{
DisasASI da = get_asi(dc, insn, MO_TEUL);
TCGv oldv;
@@ -2245,7 +2256,8 @@ static void gen_cas_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
}
}
-static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
+static void __attribute__((unused))
+gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
{
DisasASI da = get_asi(dc, insn, MO_UB);
@@ -2280,11 +2292,9 @@ static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
break;
}
}
-#endif
-#ifdef TARGET_SPARC64
-static void gen_ldf_asi(DisasContext *dc, TCGv addr,
- int insn, int size, int rd)
+static void __attribute__((unused))
+gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
{
DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEUQ));
TCGv_i32 d32;
@@ -2392,8 +2402,8 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
}
}
-static void gen_stf_asi(DisasContext *dc, TCGv addr,
- int insn, int size, int rd)
+static void __attribute__((unused))
+gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
{
DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEUQ));
TCGv_i32 d32;
@@ -2475,21 +2485,23 @@ static void gen_stf_asi(DisasContext *dc, TCGv addr,
}
}
-static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
+static void __attribute__((unused))
+gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
{
DisasASI da = get_asi(dc, insn, MO_TEUQ);
- TCGv_i64 hi = gen_dest_gpr(dc, rd);
- TCGv_i64 lo = gen_dest_gpr(dc, rd + 1);
+ TCGv hi = gen_dest_gpr(dc, rd);
+ TCGv lo = gen_dest_gpr(dc, rd + 1);
switch (da.type) {
case GET_ASI_EXCP:
return;
case GET_ASI_DTWINX:
+ assert(TARGET_LONG_BITS == 64);
gen_address_mask(dc, addr);
- tcg_gen_qemu_ld_i64(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
+ tcg_gen_qemu_ld_tl(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_ld_i64(lo, addr, da.mem_idx, da.memop);
+ tcg_gen_qemu_ld_tl(lo, addr, da.mem_idx, da.memop);
break;
case GET_ASI_DIRECT:
@@ -2503,9 +2515,9 @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
result is byte swapped. Having just performed one
64-bit bswap, we need now to swap the writebacks. */
if ((da.memop & MO_BSWAP) == MO_TE) {
- tcg_gen_extr32_i64(lo, hi, tmp);
+ tcg_gen_extr_i64_tl(lo, hi, tmp);
} else {
- tcg_gen_extr32_i64(hi, lo, tmp);
+ tcg_gen_extr_i64_tl(hi, lo, tmp);
}
}
break;
@@ -2525,9 +2537,9 @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
/* See above. */
if ((da.memop & MO_BSWAP) == MO_TE) {
- tcg_gen_extr32_i64(lo, hi, tmp);
+ tcg_gen_extr_i64_tl(lo, hi, tmp);
} else {
- tcg_gen_extr32_i64(hi, lo, tmp);
+ tcg_gen_extr_i64_tl(hi, lo, tmp);
}
}
break;
@@ -2537,8 +2549,8 @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
gen_store_gpr(dc, rd + 1, lo);
}
-static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
- int insn, int rd)
+static void __attribute__((unused))
+gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd)
{
DisasASI da = get_asi(dc, insn, MO_TEUQ);
TCGv lo = gen_load_gpr(dc, rd + 1);
@@ -2548,10 +2560,11 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
break;
case GET_ASI_DTWINX:
+ assert(TARGET_LONG_BITS == 64);
gen_address_mask(dc, addr);
- tcg_gen_qemu_st_i64(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
+ tcg_gen_qemu_st_tl(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_st_i64(lo, addr, da.mem_idx, da.memop);
+ tcg_gen_qemu_st_tl(lo, addr, da.mem_idx, da.memop);
break;
case GET_ASI_DIRECT:
@@ -2562,15 +2575,37 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
byte swapped. We will perform one 64-bit LE store, so now
we must swap the order of the construction. */
if ((da.memop & MO_BSWAP) == MO_TE) {
- tcg_gen_concat32_i64(t64, lo, hi);
+ tcg_gen_concat_tl_i64(t64, lo, hi);
} else {
- tcg_gen_concat32_i64(t64, hi, lo);
+ tcg_gen_concat_tl_i64(t64, hi, lo);
}
gen_address_mask(dc, addr);
tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop | MO_ALIGN);
}
break;
+ 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. */
+ {
+ TCGv_i64 t64 = tcg_temp_new_i64();
+ TCGv d_addr = tcg_temp_new();
+ TCGv eight = tcg_constant_tl(8);
+ int i;
+
+ 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);
+ }
+ }
+ break;
+
default:
/* ??? In theory we've handled all of the ASIs that are valid
for stda, and this should raise DAE_invalid_asi. */
@@ -2581,9 +2616,9 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
/* See above. */
if ((da.memop & MO_BSWAP) == MO_TE) {
- tcg_gen_concat32_i64(t64, lo, hi);
+ tcg_gen_concat_tl_i64(t64, lo, hi);
} else {
- tcg_gen_concat32_i64(t64, hi, lo);
+ tcg_gen_concat_tl_i64(t64, hi, lo);
}
save_state(dc);
@@ -2593,8 +2628,8 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
}
}
-static void gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
- int insn, int rd)
+static void __attribute__((unused))
+gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv, int insn, int rd)
{
DisasASI da = get_asi(dc, insn, MO_TEUQ);
TCGv oldv;
@@ -2615,88 +2650,6 @@ static void gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
}
}
-#elif !defined(CONFIG_USER_ONLY)
-static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
-{
- /* ??? Work around an apparent bug in Ubuntu gcc 4.8.2-10ubuntu2+12,
- whereby "rd + 1" elicits "error: array subscript is above array".
- Since we have already asserted that rd is even, the semantics
- are unchanged. */
- TCGv lo = gen_dest_gpr(dc, rd | 1);
- TCGv hi = gen_dest_gpr(dc, rd);
- TCGv_i64 t64 = tcg_temp_new_i64();
- DisasASI da = get_asi(dc, insn, MO_TEUQ);
-
- switch (da.type) {
- case GET_ASI_EXCP:
- return;
- case GET_ASI_DIRECT:
- gen_address_mask(dc, addr);
- tcg_gen_qemu_ld_i64(t64, addr, da.mem_idx, da.memop | MO_ALIGN);
- break;
- default:
- {
- TCGv_i32 r_asi = tcg_constant_i32(da.asi);
- TCGv_i32 r_mop = tcg_constant_i32(MO_UQ);
-
- save_state(dc);
- gen_helper_ld_asi(t64, tcg_env, addr, r_asi, r_mop);
- }
- break;
- }
-
- tcg_gen_extr_i64_i32(lo, hi, t64);
- gen_store_gpr(dc, rd | 1, lo);
- gen_store_gpr(dc, rd, hi);
-}
-
-static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
- int insn, int rd)
-{
- DisasASI da = get_asi(dc, insn, MO_TEUQ);
- TCGv lo = gen_load_gpr(dc, rd + 1);
- TCGv_i64 t64 = tcg_temp_new_i64();
-
- tcg_gen_concat_tl_i64(t64, lo, hi);
-
- switch (da.type) {
- case GET_ASI_EXCP:
- break;
- case GET_ASI_DIRECT:
- gen_address_mask(dc, addr);
- tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop | MO_ALIGN);
- break;
- case GET_ASI_BFILL:
- /* 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. */
- {
- TCGv d_addr = tcg_temp_new();
- TCGv eight = tcg_constant_tl(8);
- int i;
-
- 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);
- }
- }
- break;
- default:
- {
- TCGv_i32 r_asi = tcg_constant_i32(da.asi);
- TCGv_i32 r_mop = tcg_constant_i32(MO_UQ);
-
- save_state(dc);
- gen_helper_st_asi(tcg_env, addr, t64, r_asi, r_mop);
- }
- break;
- }
-}
-#endif
-
static TCGv get_src1(DisasContext *dc, unsigned int insn)
{
unsigned int rs1 = GET_FIELD(insn, 13, 17);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 46/90] target/sparc: Split out ldst functions with asi pre-computed
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (44 preceding siblings ...)
2023-10-17 6:11 ` [PATCH v2 45/90] target/sparc: Drop ifdef around get_asi and friends Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 47/90] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for GET_ASI_DTWINX Richard Henderson
` (44 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
As an intermediate step in decodetree conversion, create
new functions passing in DisasASI and not insn.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 215 ++++++++++++++++++++++-----------------
1 file changed, 123 insertions(+), 92 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 6404ec5858..eed0fbadf9 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2105,25 +2105,21 @@ static DisasASI get_asi(DisasContext *dc, int insn, MemOp memop)
return resolve_asi(dc, asi, memop);
}
-static void __attribute__((unused))
-gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn, MemOp memop)
+static void gen_ld_asi0(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
{
- DisasASI da = get_asi(dc, insn, memop);
-
- switch (da.type) {
+ switch (da->type) {
case GET_ASI_EXCP:
break;
case GET_ASI_DTWINX: /* Reserved for ldda. */
gen_exception(dc, TT_ILL_INSN);
break;
case GET_ASI_DIRECT:
- gen_address_mask(dc, addr);
- tcg_gen_qemu_ld_tl(dst, addr, da.mem_idx, da.memop | MO_ALIGN);
+ tcg_gen_qemu_ld_tl(dst, addr, da->mem_idx, da->memop | MO_ALIGN);
break;
default:
{
- TCGv_i32 r_asi = tcg_constant_i32(da.asi);
- TCGv_i32 r_mop = tcg_constant_i32(memop | MO_ALIGN);
+ TCGv_i32 r_asi = tcg_constant_i32(da->asi);
+ TCGv_i32 r_mop = tcg_constant_i32(da->memop | MO_ALIGN);
save_state(dc);
#ifdef TARGET_SPARC64
@@ -2141,33 +2137,38 @@ gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn, MemOp memop)
}
static void __attribute__((unused))
-gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, int insn, MemOp memop)
+gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn, MemOp memop)
{
DisasASI da = get_asi(dc, insn, memop);
- switch (da.type) {
+ gen_address_mask(dc, addr);
+ gen_ld_asi0(dc, &da, dst, addr);
+}
+
+static void gen_st_asi0(DisasContext *dc, DisasASI *da, TCGv src, TCGv addr)
+{
+ switch (da->type) {
case GET_ASI_EXCP:
break;
+
case GET_ASI_DTWINX: /* Reserved for stda. */
-#ifndef TARGET_SPARC64
- gen_exception(dc, TT_ILL_INSN);
- break;
-#else
- if (!(dc->def->features & CPU_FEATURE_HYPV)) {
+ if (TARGET_LONG_BITS == 32) {
+ gen_exception(dc, TT_ILL_INSN);
+ break;
+ } else if (!(dc->def->features & CPU_FEATURE_HYPV)) {
/* Pre OpenSPARC CPUs don't have these */
gen_exception(dc, TT_ILL_INSN);
- return;
+ break;
}
- /* in OpenSPARC T1+ CPUs TWINX ASIs in store instructions
- * are ST_BLKINIT_ ASIs */
-#endif
+ /* In OpenSPARC T1+ CPUs TWINX ASIs in store are ST_BLKINIT_ ASIs */
/* fall through */
+
case GET_ASI_DIRECT:
- gen_address_mask(dc, addr);
- tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop | MO_ALIGN);
+ tcg_gen_qemu_st_tl(src, addr, da->mem_idx, da->memop | MO_ALIGN);
break;
-#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
+
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
@@ -2185,18 +2186,18 @@ gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, int insn, MemOp memop)
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_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);
}
}
break;
-#endif
+
default:
{
- TCGv_i32 r_asi = tcg_constant_i32(da.asi);
- TCGv_i32 r_mop = tcg_constant_i32(memop | MO_ALIGN);
+ TCGv_i32 r_asi = tcg_constant_i32(da->asi);
+ TCGv_i32 r_mop = tcg_constant_i32(da->memop | MO_ALIGN);
save_state(dc);
#ifdef TARGET_SPARC64
@@ -2216,16 +2217,49 @@ gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, int insn, MemOp memop)
}
}
+static void __attribute__((unused))
+gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, int insn, MemOp memop)
+{
+ DisasASI da = get_asi(dc, insn, memop);
+
+ gen_address_mask(dc, addr);
+ gen_st_asi0(dc, &da, src, addr);
+}
+
+static void gen_swap_asi0(DisasContext *dc, DisasASI *da,
+ TCGv dst, TCGv src, TCGv addr)
+{
+ switch (da->type) {
+ case GET_ASI_EXCP:
+ break;
+ case GET_ASI_DIRECT:
+ gen_swap(dc, dst, src, addr, da->mem_idx, da->memop);
+ break;
+ default:
+ /* ??? Should be DAE_invalid_asi. */
+ gen_exception(dc, TT_DATA_ACCESS);
+ break;
+ }
+}
+
static void __attribute__((unused))
gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src, TCGv addr, int insn)
{
DisasASI da = get_asi(dc, insn, MO_TEUL);
- switch (da.type) {
+ gen_address_mask(dc, addr);
+ gen_swap_asi0(dc, &da, dst, src, addr);
+}
+
+static void gen_cas_asi0(DisasContext *dc, DisasASI *da,
+ TCGv oldv, TCGv newv, TCGv cmpv, TCGv addr)
+{
+ switch (da->type) {
case GET_ASI_EXCP:
- break;
+ return;
case GET_ASI_DIRECT:
- gen_swap(dc, dst, src, addr, da.mem_idx, da.memop);
+ tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, newv,
+ da->mem_idx, da->memop | MO_ALIGN);
break;
default:
/* ??? Should be DAE_invalid_asi. */
@@ -2238,34 +2272,33 @@ static void __attribute__((unused))
gen_cas_asi(DisasContext *dc, TCGv addr, TCGv cmpv, int insn, int rd)
{
DisasASI da = get_asi(dc, insn, MO_TEUL);
- TCGv oldv;
+ TCGv oldv = gen_dest_gpr(dc, rd);
+ TCGv newv = gen_load_gpr(dc, rd);
- switch (da.type) {
- case GET_ASI_EXCP:
- return;
- case GET_ASI_DIRECT:
- oldv = tcg_temp_new();
- tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, gen_load_gpr(dc, rd),
- da.mem_idx, da.memop | MO_ALIGN);
- gen_store_gpr(dc, rd, oldv);
- break;
- default:
- /* ??? Should be DAE_invalid_asi. */
- gen_exception(dc, TT_DATA_ACCESS);
- break;
- }
+ gen_address_mask(dc, addr);
+ gen_cas_asi0(dc, &da, oldv, newv, cmpv, addr);
+ gen_store_gpr(dc, rd, oldv);
}
static void __attribute__((unused))
-gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
+gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv, int insn, int rd)
{
- DisasASI da = get_asi(dc, insn, MO_UB);
+ DisasASI da = get_asi(dc, insn, MO_TEUQ);
+ TCGv oldv = gen_dest_gpr(dc, rd);
+ TCGv newv = gen_load_gpr(dc, rd);
- switch (da.type) {
+ gen_address_mask(dc, addr);
+ gen_cas_asi0(dc, &da, oldv, newv, cmpv, addr);
+ gen_store_gpr(dc, rd, oldv);
+}
+
+static void gen_ldstub_asi0(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
+{
+ switch (da->type) {
case GET_ASI_EXCP:
break;
case GET_ASI_DIRECT:
- gen_ldstub(dc, dst, addr, da.mem_idx);
+ gen_ldstub(dc, dst, addr, da->mem_idx);
break;
default:
/* ??? In theory, this should be raise DAE_invalid_asi.
@@ -2273,7 +2306,7 @@ gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
if (tb_cflags(dc->base.tb) & CF_PARALLEL) {
gen_helper_exit_atomic(tcg_env);
} else {
- TCGv_i32 r_asi = tcg_constant_i32(da.asi);
+ TCGv_i32 r_asi = tcg_constant_i32(da->asi);
TCGv_i32 r_mop = tcg_constant_i32(MO_UB);
TCGv_i64 s64, t64;
@@ -2293,6 +2326,15 @@ gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
}
}
+static void __attribute__((unused))
+gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
+{
+ DisasASI da = get_asi(dc, insn, MO_UB);
+
+ gen_address_mask(dc, addr);
+ gen_ldstub_asi0(dc, &da, dst, addr);
+}
+
static void __attribute__((unused))
gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
{
@@ -2485,36 +2527,32 @@ gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
}
}
-static void __attribute__((unused))
-gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
+static void gen_ldda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
{
- DisasASI da = get_asi(dc, insn, MO_TEUQ);
TCGv hi = gen_dest_gpr(dc, rd);
TCGv lo = gen_dest_gpr(dc, rd + 1);
- switch (da.type) {
+ switch (da->type) {
case GET_ASI_EXCP:
return;
case GET_ASI_DTWINX:
assert(TARGET_LONG_BITS == 64);
- gen_address_mask(dc, addr);
- tcg_gen_qemu_ld_tl(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
+ tcg_gen_qemu_ld_tl(hi, addr, da->mem_idx, da->memop | MO_ALIGN_16);
tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_ld_tl(lo, addr, da.mem_idx, da.memop);
+ tcg_gen_qemu_ld_tl(lo, addr, da->mem_idx, da->memop);
break;
case GET_ASI_DIRECT:
{
TCGv_i64 tmp = tcg_temp_new_i64();
- gen_address_mask(dc, addr);
- tcg_gen_qemu_ld_i64(tmp, addr, da.mem_idx, da.memop | MO_ALIGN);
+ tcg_gen_qemu_ld_i64(tmp, addr, da->mem_idx, da->memop | MO_ALIGN);
/* Note that LE ldda acts as if each 32-bit register
result is byte swapped. Having just performed one
64-bit bswap, we need now to swap the writebacks. */
- if ((da.memop & MO_BSWAP) == MO_TE) {
+ if ((da->memop & MO_BSWAP) == MO_TE) {
tcg_gen_extr_i64_tl(lo, hi, tmp);
} else {
tcg_gen_extr_i64_tl(hi, lo, tmp);
@@ -2528,15 +2566,15 @@ gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
real hardware allows others. This can be seen with e.g.
FreeBSD 10.3 wrt ASI_IC_TAG. */
{
- TCGv_i32 r_asi = tcg_constant_i32(da.asi);
- TCGv_i32 r_mop = tcg_constant_i32(da.memop);
+ TCGv_i32 r_asi = tcg_constant_i32(da->asi);
+ TCGv_i32 r_mop = tcg_constant_i32(da->memop);
TCGv_i64 tmp = tcg_temp_new_i64();
save_state(dc);
gen_helper_ld_asi(tmp, tcg_env, addr, r_asi, r_mop);
/* See above. */
- if ((da.memop & MO_BSWAP) == MO_TE) {
+ if ((da->memop & MO_BSWAP) == MO_TE) {
tcg_gen_extr_i64_tl(lo, hi, tmp);
} else {
tcg_gen_extr_i64_tl(hi, lo, tmp);
@@ -2550,21 +2588,28 @@ gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
}
static void __attribute__((unused))
-gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd)
+gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
{
DisasASI da = get_asi(dc, insn, MO_TEUQ);
+
+ gen_address_mask(dc, addr);
+ gen_ldda_asi0(dc, &da, addr, rd);
+}
+
+static void gen_stda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
+{
+ TCGv hi = gen_load_gpr(dc, rd);
TCGv lo = gen_load_gpr(dc, rd + 1);
- switch (da.type) {
+ switch (da->type) {
case GET_ASI_EXCP:
break;
case GET_ASI_DTWINX:
assert(TARGET_LONG_BITS == 64);
- gen_address_mask(dc, addr);
- tcg_gen_qemu_st_tl(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
+ tcg_gen_qemu_st_tl(hi, addr, da->mem_idx, da->memop | MO_ALIGN_16);
tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_st_tl(lo, addr, da.mem_idx, da.memop);
+ tcg_gen_qemu_st_tl(lo, addr, da->mem_idx, da->memop);
break;
case GET_ASI_DIRECT:
@@ -2574,13 +2619,12 @@ gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd)
/* Note that LE stda acts as if each 32-bit register result is
byte swapped. We will perform one 64-bit LE store, so now
we must swap the order of the construction. */
- if ((da.memop & MO_BSWAP) == MO_TE) {
+ if ((da->memop & MO_BSWAP) == MO_TE) {
tcg_gen_concat_tl_i64(t64, lo, hi);
} else {
tcg_gen_concat_tl_i64(t64, hi, lo);
}
- gen_address_mask(dc, addr);
- tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop | MO_ALIGN);
+ tcg_gen_qemu_st_i64(t64, addr, da->mem_idx, da->memop | MO_ALIGN);
}
break;
@@ -2600,7 +2644,7 @@ gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd)
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_qemu_st_i64(t64, d_addr, da->mem_idx, da->memop);
tcg_gen_add_tl(d_addr, d_addr, eight);
}
}
@@ -2610,12 +2654,12 @@ gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd)
/* ??? In theory we've handled all of the ASIs that are valid
for stda, and this should raise DAE_invalid_asi. */
{
- TCGv_i32 r_asi = tcg_constant_i32(da.asi);
- TCGv_i32 r_mop = tcg_constant_i32(da.memop);
+ TCGv_i32 r_asi = tcg_constant_i32(da->asi);
+ TCGv_i32 r_mop = tcg_constant_i32(da->memop);
TCGv_i64 t64 = tcg_temp_new_i64();
/* See above. */
- if ((da.memop & MO_BSWAP) == MO_TE) {
+ if ((da->memop & MO_BSWAP) == MO_TE) {
tcg_gen_concat_tl_i64(t64, lo, hi);
} else {
tcg_gen_concat_tl_i64(t64, hi, lo);
@@ -2629,25 +2673,12 @@ gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd)
}
static void __attribute__((unused))
-gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv, int insn, int rd)
+gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd)
{
DisasASI da = get_asi(dc, insn, MO_TEUQ);
- TCGv oldv;
- switch (da.type) {
- case GET_ASI_EXCP:
- return;
- case GET_ASI_DIRECT:
- oldv = tcg_temp_new();
- tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, gen_load_gpr(dc, rd),
- da.mem_idx, da.memop | MO_ALIGN);
- gen_store_gpr(dc, rd, oldv);
- break;
- default:
- /* ??? Should be DAE_invalid_asi. */
- gen_exception(dc, TT_DATA_ACCESS);
- break;
- }
+ gen_address_mask(dc, addr);
+ gen_stda_asi0(dc, &da, addr, rd);
}
static TCGv get_src1(DisasContext *dc, unsigned int insn)
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 47/90] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for GET_ASI_DTWINX
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (45 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 46/90] target/sparc: Split out ldst functions with asi pre-computed Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 48/90] target/sparc: Move simple integer load/store to decodetree Richard Henderson
` (43 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Perform one atomic 16-byte operation.
The atomicity is required for the LDTXA instructions.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 48 +++++++++++++++++++++++++++++++++-------
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index eed0fbadf9..16b024fab7 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2537,11 +2537,27 @@ static void gen_ldda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
return;
case GET_ASI_DTWINX:
- assert(TARGET_LONG_BITS == 64);
- tcg_gen_qemu_ld_tl(hi, addr, da->mem_idx, da->memop | MO_ALIGN_16);
- tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_ld_tl(lo, addr, da->mem_idx, da->memop);
+#ifdef TARGET_SPARC64
+ {
+ MemOp mop = (da->memop & MO_BSWAP) | MO_128 | MO_ALIGN_16;
+ TCGv_i128 t = tcg_temp_new_i128();
+
+ tcg_gen_qemu_ld_i128(t, addr, da->mem_idx, mop);
+ /*
+ * Note that LE twinx acts as if each 64-bit register result is
+ * byte swapped. We perform one 128-bit LE load, so must swap
+ * the order of the writebacks.
+ */
+ if ((mop & MO_BSWAP) == MO_TE) {
+ tcg_gen_extr_i128_i64(lo, hi, t);
+ } else {
+ tcg_gen_extr_i128_i64(hi, lo, t);
+ }
+ }
break;
+#else
+ g_assert_not_reached();
+#endif
case GET_ASI_DIRECT:
{
@@ -2606,11 +2622,27 @@ static void gen_stda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
break;
case GET_ASI_DTWINX:
- assert(TARGET_LONG_BITS == 64);
- tcg_gen_qemu_st_tl(hi, addr, da->mem_idx, da->memop | MO_ALIGN_16);
- tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_st_tl(lo, addr, da->mem_idx, da->memop);
+#ifdef TARGET_SPARC64
+ {
+ MemOp mop = (da->memop & MO_BSWAP) | MO_128 | MO_ALIGN_16;
+ TCGv_i128 t = tcg_temp_new_i128();
+
+ /*
+ * Note that LE twinx acts as if each 64-bit register result is
+ * byte swapped. We perform one 128-bit LE store, so must swap
+ * the order of the construction.
+ */
+ if ((mop & MO_BSWAP) == MO_TE) {
+ tcg_gen_concat_i64_i128(t, lo, hi);
+ } else {
+ tcg_gen_concat_i64_i128(t, hi, lo);
+ }
+ tcg_gen_qemu_st_i128(t, addr, da->mem_idx, mop);
+ }
break;
+#else
+ g_assert_not_reached();
+#endif
case GET_ASI_DIRECT:
{
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 48/90] target/sparc: Move simple integer load/store to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (46 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 47/90] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for GET_ASI_DTWINX Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 49/90] target/sparc: Move asi " Richard Henderson
` (42 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move LDUW, LDUB, LDUH, LDD, LDSW, LDSB, LDSH, LDX,
STW, STB, STH, STD, STX.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 22 +++++
target/sparc/translate.c | 196 +++++++++++++++++++++++---------------
2 files changed, 142 insertions(+), 76 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index dface4a9dd..24c22c6ae3 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -224,6 +224,28 @@ RESTORE 10 ..... 111101 ..... . ............. @r_r_ri
DONE 10 00000 111110 00000 0 0000000000000
RETRY 10 00001 111110 00000 0 0000000000000
+##
+## Major Opcode 11 -- load and store instructions
+##
+
+&r_r_ri_asi rd rs1 rs2_or_imm asi imm:bool
+@r_r_ri_na .. rd:5 ...... rs1:5 imm:1 rs2_or_imm:s13 &r_r_ri_asi asi=-1
+
+LDUW 11 ..... 000000 ..... . ............. @r_r_ri_na
+LDUB 11 ..... 000001 ..... . ............. @r_r_ri_na
+LDUH 11 ..... 000010 ..... . ............. @r_r_ri_na
+LDD 11 ..... 000011 ..... . ............. @r_r_ri_na
+LDSW 11 ..... 001000 ..... . ............. @r_r_ri_na
+LDSB 11 ..... 001001 ..... . ............. @r_r_ri_na
+LDSH 11 ..... 001010 ..... . ............. @r_r_ri_na
+LDX 11 ..... 001011 ..... . ............. @r_r_ri_na
+
+STW 11 ..... 000100 ..... . ............. @r_r_ri_na
+STB 11 ..... 000101 ..... . ............. @r_r_ri_na
+STH 11 ..... 000110 ..... . ............. @r_r_ri_na
+STD 11 ..... 000111 ..... . ............. @r_r_ri_na
+STX 11 ..... 001110 ..... . ............. @r_r_ri_na
+
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 16b024fab7..db577ee963 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4614,6 +4614,117 @@ static bool trans_RETRY(DisasContext *dc, arg_RETRY *a)
return true;
}
+/*
+ * Major opcode 11 -- load and store instructions
+ */
+
+static TCGv gen_ldst_addr(DisasContext *dc, int rs1, bool imm, int rs2_or_imm)
+{
+ TCGv addr, tmp = NULL;
+
+ /* For simplicity, we under-decoded the rs2 form. */
+ if (!imm && rs2_or_imm & ~0x1f) {
+ return NULL;
+ }
+
+ addr = gen_load_gpr(dc, rs1);
+ if (rs2_or_imm) {
+ tmp = tcg_temp_new();
+ if (imm) {
+ tcg_gen_addi_tl(tmp, addr, rs2_or_imm);
+ } else {
+ tcg_gen_add_tl(tmp, addr, cpu_regs[rs2_or_imm]);
+ }
+ addr = tmp;
+ }
+ if (AM_CHECK(dc)) {
+ if (!tmp) {
+ tmp = tcg_temp_new();
+ }
+ tcg_gen_ext32u_tl(tmp, addr);
+ addr = tmp;
+ }
+ return addr;
+}
+
+static bool do_ld_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
+{
+ TCGv reg, addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ DisasASI da;
+
+ if (addr == NULL) {
+ return false;
+ }
+ da = resolve_asi(dc, a->asi, mop);
+
+ reg = gen_dest_gpr(dc, a->rd);
+ gen_ld_asi0(dc, &da, reg, addr);
+ gen_store_gpr(dc, a->rd, reg);
+ return advance_pc(dc);
+}
+
+TRANS(LDUW, ALL, do_ld_gpr, a, MO_TEUL)
+TRANS(LDUB, ALL, do_ld_gpr, a, MO_UB)
+TRANS(LDUH, ALL, do_ld_gpr, a, MO_TEUW)
+TRANS(LDSB, ALL, do_ld_gpr, a, MO_SB)
+TRANS(LDSH, ALL, do_ld_gpr, a, MO_TESW)
+TRANS(LDSW, 64, do_ld_gpr, a, MO_TESL)
+TRANS(LDX, 64, do_ld_gpr, a, MO_TEUQ)
+
+static bool do_st_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
+{
+ TCGv reg, addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ DisasASI da;
+
+ if (addr == NULL) {
+ return false;
+ }
+ da = resolve_asi(dc, a->asi, mop);
+
+ reg = gen_load_gpr(dc, a->rd);
+ gen_st_asi0(dc, &da, reg, addr);
+ return advance_pc(dc);
+}
+
+TRANS(STW, ALL, do_st_gpr, a, MO_TEUL)
+TRANS(STB, ALL, do_st_gpr, a, MO_UB)
+TRANS(STH, ALL, do_st_gpr, a, MO_TEUW)
+TRANS(STX, 64, do_st_gpr, a, MO_TEUQ)
+
+static bool trans_LDD(DisasContext *dc, arg_r_r_ri_asi *a)
+{
+ TCGv addr;
+ DisasASI da;
+
+ if (a->rd & 1) {
+ return false;
+ }
+ addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ if (addr == NULL) {
+ return false;
+ }
+ da = resolve_asi(dc, a->asi, MO_TEUQ);
+ gen_ldda_asi0(dc, &da, addr, a->rd);
+ return advance_pc(dc);
+}
+
+static bool trans_STD(DisasContext *dc, arg_r_r_ri_asi *a)
+{
+ TCGv addr;
+ DisasASI da;
+
+ if (a->rd & 1) {
+ return false;
+ }
+ addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ if (addr == NULL) {
+ return false;
+ }
+ da = resolve_asi(dc, a->asi, MO_TEUQ);
+ gen_stda_asi0(dc, &da, addr, a->rd);
+ return advance_pc(dc);
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5437,47 +5548,15 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
switch (xop) {
case 0x0: /* ld, V9 lduw, load unsigned word */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
- dc->mem_idx, MO_TEUL | MO_ALIGN);
- break;
case 0x1: /* ldub, load unsigned byte */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
- dc->mem_idx, MO_UB);
- break;
case 0x2: /* lduh, load unsigned halfword */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
- dc->mem_idx, MO_TEUW | MO_ALIGN);
- break;
case 0x3: /* ldd, load double word */
- if (rd & 1)
- goto illegal_insn;
- else {
- TCGv_i64 t64;
-
- gen_address_mask(dc, cpu_addr);
- t64 = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(t64, cpu_addr,
- dc->mem_idx, MO_TEUQ | MO_ALIGN);
- tcg_gen_trunc_i64_tl(cpu_val, t64);
- tcg_gen_ext32u_tl(cpu_val, cpu_val);
- gen_store_gpr(dc, rd + 1, cpu_val);
- tcg_gen_shri_i64(t64, t64, 32);
- tcg_gen_trunc_i64_tl(cpu_val, t64);
- tcg_gen_ext32u_tl(cpu_val, cpu_val);
- }
- break;
case 0x9: /* ldsb, load signed byte */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_ld_tl(cpu_val, cpu_addr, dc->mem_idx, MO_SB);
- break;
case 0xa: /* ldsh, load signed halfword */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
- dc->mem_idx, MO_TESW | MO_ALIGN);
- break;
+ g_assert_not_reached(); /* in decodetree */
+ case 0x08: /* V9 ldsw */
+ case 0x0b: /* V9 ldx */
+ goto illegal_insn; /* in decodetree */
case 0xd: /* ldstub */
gen_ldstub(dc, cpu_val, cpu_addr, dc->mem_idx);
break;
@@ -5519,16 +5598,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
break;
#endif
#ifdef TARGET_SPARC64
- case 0x08: /* V9 ldsw */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
- dc->mem_idx, MO_TESL | MO_ALIGN);
- break;
- case 0x0b: /* V9 ldx */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
- dc->mem_idx, MO_TEUQ | MO_ALIGN);
- break;
case 0x18: /* V9 ldswa */
gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
break;
@@ -5621,38 +5690,18 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
}
} else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
xop == 0xe || xop == 0x1e) {
+#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
TCGv cpu_val = gen_load_gpr(dc, rd);
+#endif
switch (xop) {
case 0x4: /* st, store word */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_st_tl(cpu_val, cpu_addr,
- dc->mem_idx, MO_TEUL | MO_ALIGN);
- break;
case 0x5: /* stb, store byte */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_st_tl(cpu_val, cpu_addr, dc->mem_idx, MO_UB);
- break;
case 0x6: /* sth, store halfword */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_st_tl(cpu_val, cpu_addr,
- dc->mem_idx, MO_TEUW | MO_ALIGN);
- break;
case 0x7: /* std, store double word */
- if (rd & 1)
- goto illegal_insn;
- else {
- TCGv_i64 t64;
- TCGv lo;
-
- gen_address_mask(dc, cpu_addr);
- lo = gen_load_gpr(dc, rd + 1);
- t64 = tcg_temp_new_i64();
- tcg_gen_concat_tl_i64(t64, lo, cpu_val);
- tcg_gen_qemu_st_i64(t64, cpu_addr,
- dc->mem_idx, MO_TEUQ | MO_ALIGN);
- }
- break;
+ g_assert_not_reached(); /* in decodetree */
+ case 0x0e: /* V9 stx */
+ goto illegal_insn; /* in decodetree */
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
case 0x14: /* sta, V9 stwa, store word alternate */
gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
@@ -5671,11 +5720,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
break;
#endif
#ifdef TARGET_SPARC64
- case 0x0e: /* V9 stx */
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_st_tl(cpu_val, cpu_addr,
- dc->mem_idx, MO_TEUQ | MO_ALIGN);
- break;
case 0x1e: /* V9 stxa */
gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 49/90] target/sparc: Move asi integer load/store to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (47 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 48/90] target/sparc: Move simple integer load/store to decodetree Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 50/90] target/sparc: Move LDSTUB, LDSTUBA " Richard Henderson
` (41 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move LDDA, LDSBA, LDSHA, LDSWA, LDUBA, LDUHA, LDUWA, LDXA,
STBA, STDA, STHA, STWA, STXA.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 31 +++++++++
target/sparc/translate.c | 128 +++++---------------------------------
2 files changed, 48 insertions(+), 111 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 24c22c6ae3..94f1f5b9c9 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -230,6 +230,9 @@ RETRY 10 00001 111110 00000 0 0000000000000
&r_r_ri_asi rd rs1 rs2_or_imm asi imm:bool
@r_r_ri_na .. rd:5 ...... rs1:5 imm:1 rs2_or_imm:s13 &r_r_ri_asi asi=-1
+@r_r_r_asi .. rd:5 ...... rs1:5 0 asi:8 rs2_or_imm:5 &r_r_ri_asi imm=0
+@r_r_i_asi .. rd:5 ...... rs1:5 1 rs2_or_imm:s13 \
+ &r_r_ri_asi imm=1 asi=-2
LDUW 11 ..... 000000 ..... . ............. @r_r_ri_na
LDUB 11 ..... 000001 ..... . ............. @r_r_ri_na
@@ -246,6 +249,34 @@ STH 11 ..... 000110 ..... . ............. @r_r_ri_na
STD 11 ..... 000111 ..... . ............. @r_r_ri_na
STX 11 ..... 001110 ..... . ............. @r_r_ri_na
+LDUW 11 ..... 010000 ..... . ............. @r_r_r_asi # LDUWA
+LDUW 11 ..... 010000 ..... . ............. @r_r_i_asi # LDUWA
+LDUB 11 ..... 010001 ..... . ............. @r_r_r_asi # LDUBA
+LDUB 11 ..... 010001 ..... . ............. @r_r_i_asi # LDUBA
+LDUH 11 ..... 010010 ..... . ............. @r_r_r_asi # LDUHA
+LDUH 11 ..... 010010 ..... . ............. @r_r_i_asi # LDUHA
+LDD 11 ..... 010011 ..... . ............. @r_r_r_asi # LDDA
+LDD 11 ..... 010011 ..... . ............. @r_r_i_asi # LDDA
+LDX 11 ..... 011011 ..... . ............. @r_r_r_asi # LDXA
+LDX 11 ..... 011011 ..... . ............. @r_r_i_asi # LDXA
+LDSB 11 ..... 011001 ..... . ............. @r_r_r_asi # LDSBA
+LDSB 11 ..... 011001 ..... . ............. @r_r_i_asi # LDSBA
+LDSH 11 ..... 011010 ..... . ............. @r_r_r_asi # LDSHA
+LDSH 11 ..... 011010 ..... . ............. @r_r_i_asi # LDSHA
+LDSW 11 ..... 011000 ..... . ............. @r_r_r_asi # LDSWA
+LDSW 11 ..... 011000 ..... . ............. @r_r_i_asi # LDSWA
+
+STW 11 ..... 010100 ..... . ............. @r_r_r_asi # STWA
+STW 11 ..... 010100 ..... . ............. @r_r_i_asi # STWA
+STB 11 ..... 010101 ..... . ............. @r_r_r_asi # STBA
+STB 11 ..... 010101 ..... . ............. @r_r_i_asi # STBA
+STH 11 ..... 010110 ..... . ............. @r_r_r_asi # STHA
+STH 11 ..... 010110 ..... . ............. @r_r_i_asi # STHA
+STD 11 ..... 010111 ..... . ............. @r_r_r_asi # STDA
+STD 11 ..... 010111 ..... . ............. @r_r_i_asi # STDA
+STX 11 ..... 011110 ..... . ............. @r_r_r_asi # STXA
+STX 11 ..... 011110 ..... . ............. @r_r_i_asi # STXA
+
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index db577ee963..587eb0ccd5 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2105,7 +2105,7 @@ static DisasASI get_asi(DisasContext *dc, int insn, MemOp memop)
return resolve_asi(dc, asi, memop);
}
-static void gen_ld_asi0(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
+static void gen_ld_asi(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
{
switch (da->type) {
case GET_ASI_EXCP:
@@ -2136,16 +2136,7 @@ static void gen_ld_asi0(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
}
}
-static void __attribute__((unused))
-gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn, MemOp memop)
-{
- DisasASI da = get_asi(dc, insn, memop);
-
- gen_address_mask(dc, addr);
- gen_ld_asi0(dc, &da, dst, addr);
-}
-
-static void gen_st_asi0(DisasContext *dc, DisasASI *da, TCGv src, TCGv addr)
+static void gen_st_asi(DisasContext *dc, DisasASI *da, TCGv src, TCGv addr)
{
switch (da->type) {
case GET_ASI_EXCP:
@@ -2217,15 +2208,6 @@ static void gen_st_asi0(DisasContext *dc, DisasASI *da, TCGv src, TCGv addr)
}
}
-static void __attribute__((unused))
-gen_st_asi(DisasContext *dc, TCGv src, TCGv addr, int insn, MemOp memop)
-{
- DisasASI da = get_asi(dc, insn, memop);
-
- gen_address_mask(dc, addr);
- gen_st_asi0(dc, &da, src, addr);
-}
-
static void gen_swap_asi0(DisasContext *dc, DisasASI *da,
TCGv dst, TCGv src, TCGv addr)
{
@@ -2527,7 +2509,7 @@ gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
}
}
-static void gen_ldda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
+static void gen_ldda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
{
TCGv hi = gen_dest_gpr(dc, rd);
TCGv lo = gen_dest_gpr(dc, rd + 1);
@@ -2603,16 +2585,7 @@ static void gen_ldda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
gen_store_gpr(dc, rd + 1, lo);
}
-static void __attribute__((unused))
-gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
-{
- DisasASI da = get_asi(dc, insn, MO_TEUQ);
-
- gen_address_mask(dc, addr);
- gen_ldda_asi0(dc, &da, addr, rd);
-}
-
-static void gen_stda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
+static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
{
TCGv hi = gen_load_gpr(dc, rd);
TCGv lo = gen_load_gpr(dc, rd + 1);
@@ -2704,15 +2677,6 @@ static void gen_stda_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
}
}
-static void __attribute__((unused))
-gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr, int insn, int rd)
-{
- DisasASI da = get_asi(dc, insn, MO_TEUQ);
-
- gen_address_mask(dc, addr);
- gen_stda_asi0(dc, &da, addr, rd);
-}
-
static TCGv get_src1(DisasContext *dc, unsigned int insn)
{
unsigned int rs1 = GET_FIELD(insn, 13, 17);
@@ -4658,7 +4622,7 @@ static bool do_ld_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
da = resolve_asi(dc, a->asi, mop);
reg = gen_dest_gpr(dc, a->rd);
- gen_ld_asi0(dc, &da, reg, addr);
+ gen_ld_asi(dc, &da, reg, addr);
gen_store_gpr(dc, a->rd, reg);
return advance_pc(dc);
}
@@ -4682,7 +4646,7 @@ static bool do_st_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
da = resolve_asi(dc, a->asi, mop);
reg = gen_load_gpr(dc, a->rd);
- gen_st_asi0(dc, &da, reg, addr);
+ gen_st_asi(dc, &da, reg, addr);
return advance_pc(dc);
}
@@ -4704,7 +4668,7 @@ static bool trans_LDD(DisasContext *dc, arg_r_r_ri_asi *a)
return false;
}
da = resolve_asi(dc, a->asi, MO_TEUQ);
- gen_ldda_asi0(dc, &da, addr, a->rd);
+ gen_ldda_asi(dc, &da, addr, a->rd);
return advance_pc(dc);
}
@@ -4721,7 +4685,7 @@ static bool trans_STD(DisasContext *dc, arg_r_r_ri_asi *a)
return false;
}
da = resolve_asi(dc, a->asi, MO_TEUQ);
- gen_stda_asi0(dc, &da, addr, a->rd);
+ gen_stda_asi(dc, &da, addr, a->rd);
return advance_pc(dc);
}
@@ -5553,9 +5517,17 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x3: /* ldd, load double word */
case 0x9: /* ldsb, load signed byte */
case 0xa: /* ldsh, load signed halfword */
+ case 0x10: /* lda, V9 lduwa, load word alternate */
+ case 0x11: /* lduba, load unsigned byte alternate */
+ case 0x12: /* lduha, load unsigned halfword alternate */
+ case 0x13: /* ldda, load double word alternate */
+ case 0x19: /* ldsba, load signed byte alternate */
+ case 0x1a: /* ldsha, load signed halfword alternate */
g_assert_not_reached(); /* in decodetree */
case 0x08: /* V9 ldsw */
case 0x0b: /* V9 ldx */
+ case 0x18: /* V9 ldswa */
+ case 0x1b: /* V9 ldxa */
goto illegal_insn; /* in decodetree */
case 0xd: /* ldstub */
gen_ldstub(dc, cpu_val, cpu_addr, dc->mem_idx);
@@ -5567,27 +5539,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
dc->mem_idx, MO_TEUL);
break;
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
- case 0x10: /* lda, V9 lduwa, load word alternate */
- gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
- break;
- case 0x11: /* lduba, load unsigned byte alternate */
- gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
- break;
- case 0x12: /* lduha, load unsigned halfword alternate */
- gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
- break;
- case 0x13: /* ldda, load double word alternate */
- if (rd & 1) {
- goto illegal_insn;
- }
- gen_ldda_asi(dc, cpu_addr, insn, rd);
- goto skip_move;
- case 0x19: /* ldsba, load signed byte alternate */
- gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_SB);
- break;
- case 0x1a: /* ldsha, load signed halfword alternate */
- gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESW);
- break;
case 0x1d: /* ldstuba -- XXX: should be atomically */
gen_ldstub_asi(dc, cpu_val, cpu_addr, insn);
break;
@@ -5598,12 +5549,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
break;
#endif
#ifdef TARGET_SPARC64
- case 0x18: /* V9 ldswa */
- gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
- break;
- case 0x1b: /* V9 ldxa */
- gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
- break;
case 0x2d: /* V9 prefetch, no effect */
goto skip_move;
case 0x30: /* V9 ldfa */
@@ -5635,7 +5580,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
goto illegal_insn;
}
gen_store_gpr(dc, rd, cpu_val);
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
+#if defined(TARGET_SPARC64)
skip_move: ;
#endif
} else if (xop >= 0x20 && xop < 0x24) {
@@ -5688,45 +5633,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
default:
goto illegal_insn;
}
- } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
- xop == 0xe || xop == 0x1e) {
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
- TCGv cpu_val = gen_load_gpr(dc, rd);
-#endif
-
- switch (xop) {
- case 0x4: /* st, store word */
- case 0x5: /* stb, store byte */
- case 0x6: /* sth, store halfword */
- case 0x7: /* std, store double word */
- g_assert_not_reached(); /* in decodetree */
- case 0x0e: /* V9 stx */
- goto illegal_insn; /* in decodetree */
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
- case 0x14: /* sta, V9 stwa, store word alternate */
- gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
- break;
- case 0x15: /* stba, store byte alternate */
- gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
- break;
- case 0x16: /* stha, store halfword alternate */
- gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
- break;
- case 0x17: /* stda, store double word alternate */
- if (rd & 1) {
- goto illegal_insn;
- }
- gen_stda_asi(dc, cpu_val, cpu_addr, insn, rd);
- break;
-#endif
-#ifdef TARGET_SPARC64
- case 0x1e: /* V9 stxa */
- gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
- break;
-#endif
- default:
- goto illegal_insn;
- }
} else if (xop > 0x23 && xop < 0x28) {
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 50/90] target/sparc: Move LDSTUB, LDSTUBA to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (48 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 49/90] target/sparc: Move asi " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 51/90] target/sparc: Move SWAP, SWAPA " Richard Henderson
` (40 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Remove gen_ldstub_asi.
Rename gen_ldstub_asi0 to gen_ldstub_asi.
Merge gen_ldstub into gen_ldstub_asi.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 ++++
target/sparc/translate.c | 46 +++++++++++++++++++--------------------
2 files changed, 26 insertions(+), 24 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 94f1f5b9c9..3233528b08 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -277,6 +277,10 @@ STD 11 ..... 010111 ..... . ............. @r_r_i_asi # STDA
STX 11 ..... 011110 ..... . ............. @r_r_r_asi # STXA
STX 11 ..... 011110 ..... . ............. @r_r_i_asi # STXA
+LDSTUB 11 ..... 001101 ..... . ............. @r_r_ri_na
+LDSTUB 11 ..... 011101 ..... . ............. @r_r_r_asi # LDSTUBA
+LDSTUB 11 ..... 011101 ..... . ............. @r_r_i_asi # LDSTUBA
+
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 587eb0ccd5..c2ea027fe1 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1849,13 +1849,6 @@ static void gen_swap(DisasContext *dc, TCGv dst, TCGv src,
tcg_gen_atomic_xchg_tl(dst, addr, src, mmu_idx, memop | MO_ALIGN);
}
-static void gen_ldstub(DisasContext *dc, TCGv dst, TCGv addr, int mmu_idx)
-{
- TCGv m1 = tcg_constant_tl(0xff);
- gen_address_mask(dc, addr);
- tcg_gen_atomic_xchg_tl(dst, addr, m1, mmu_idx, MO_UB);
-}
-
/* asi moves */
typedef enum {
GET_ASI_HELPER,
@@ -2274,13 +2267,14 @@ gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv, int insn, int rd)
gen_store_gpr(dc, rd, oldv);
}
-static void gen_ldstub_asi0(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
+static void gen_ldstub_asi(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
{
switch (da->type) {
case GET_ASI_EXCP:
break;
case GET_ASI_DIRECT:
- gen_ldstub(dc, dst, addr, da->mem_idx);
+ tcg_gen_atomic_xchg_tl(dst, addr, tcg_constant_tl(0xff),
+ da->mem_idx, MO_UB);
break;
default:
/* ??? In theory, this should be raise DAE_invalid_asi.
@@ -2308,15 +2302,6 @@ static void gen_ldstub_asi0(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
}
}
-static void __attribute__((unused))
-gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
-{
- DisasASI da = get_asi(dc, insn, MO_UB);
-
- gen_address_mask(dc, addr);
- gen_ldstub_asi0(dc, &da, dst, addr);
-}
-
static void __attribute__((unused))
gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
{
@@ -4689,6 +4674,23 @@ static bool trans_STD(DisasContext *dc, arg_r_r_ri_asi *a)
return advance_pc(dc);
}
+static bool trans_LDSTUB(DisasContext *dc, arg_r_r_ri_asi *a)
+{
+ TCGv addr, reg;
+ DisasASI da;
+
+ addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ if (addr == NULL) {
+ return false;
+ }
+ da = resolve_asi(dc, a->asi, MO_UB);
+
+ reg = gen_dest_gpr(dc, a->rd);
+ gen_ldstub_asi(dc, &da, reg, addr);
+ gen_store_gpr(dc, a->rd, reg);
+ return advance_pc(dc);
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5517,21 +5519,20 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x3: /* ldd, load double word */
case 0x9: /* ldsb, load signed byte */
case 0xa: /* ldsh, load signed halfword */
+ case 0xd: /* ldstub */
case 0x10: /* lda, V9 lduwa, load word alternate */
case 0x11: /* lduba, load unsigned byte alternate */
case 0x12: /* lduha, load unsigned halfword alternate */
case 0x13: /* ldda, load double word alternate */
case 0x19: /* ldsba, load signed byte alternate */
case 0x1a: /* ldsha, load signed halfword alternate */
+ case 0x1d: /* ldstuba */
g_assert_not_reached(); /* in decodetree */
case 0x08: /* V9 ldsw */
case 0x0b: /* V9 ldx */
case 0x18: /* V9 ldswa */
case 0x1b: /* V9 ldxa */
goto illegal_insn; /* in decodetree */
- case 0xd: /* ldstub */
- gen_ldstub(dc, cpu_val, cpu_addr, dc->mem_idx);
- break;
case 0x0f:
/* swap, swap register with memory. Also atomically */
cpu_src1 = gen_load_gpr(dc, rd);
@@ -5539,9 +5540,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
dc->mem_idx, MO_TEUL);
break;
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
- case 0x1d: /* ldstuba -- XXX: should be atomically */
- gen_ldstub_asi(dc, cpu_val, cpu_addr, insn);
- break;
case 0x1f: /* swapa, swap reg with alt. memory. Also
atomically */
cpu_src1 = gen_load_gpr(dc, rd);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 51/90] target/sparc: Move SWAP, SWAPA to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (49 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 50/90] target/sparc: Move LDSTUB, LDSTUBA " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 52/90] target/sparc: Move CASA, CASXA " Richard Henderson
` (39 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Remove gen_swap_asi.
Rename gen_swap_asi0 to gen_swap_asi.
Merge gen_swap into gen_swap_asi.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 +++
target/sparc/translate.c | 58 +++++++++++++++++----------------------
2 files changed, 29 insertions(+), 33 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 3233528b08..32ac9cdbf7 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -281,6 +281,10 @@ LDSTUB 11 ..... 001101 ..... . ............. @r_r_ri_na
LDSTUB 11 ..... 011101 ..... . ............. @r_r_r_asi # LDSTUBA
LDSTUB 11 ..... 011101 ..... . ............. @r_r_i_asi # LDSTUBA
+SWAP 11 ..... 001111 ..... . ............. @r_r_ri_na
+SWAP 11 ..... 011111 ..... . ............. @r_r_r_asi # SWAPA
+SWAP 11 ..... 011111 ..... . ............. @r_r_i_asi # SWAPA
+
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index c2ea027fe1..e1b8cdd798 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1842,13 +1842,6 @@ static void gen_ne_fop_QD(DisasContext *dc, int rd, int rs,
gen_update_fprs_dirty(dc, QFPREG(rd));
}
-static void gen_swap(DisasContext *dc, TCGv dst, TCGv src,
- TCGv addr, int mmu_idx, MemOp memop)
-{
- gen_address_mask(dc, addr);
- tcg_gen_atomic_xchg_tl(dst, addr, src, mmu_idx, memop | MO_ALIGN);
-}
-
/* asi moves */
typedef enum {
GET_ASI_HELPER,
@@ -2201,14 +2194,15 @@ static void gen_st_asi(DisasContext *dc, DisasASI *da, TCGv src, TCGv addr)
}
}
-static void gen_swap_asi0(DisasContext *dc, DisasASI *da,
- TCGv dst, TCGv src, TCGv addr)
+static void gen_swap_asi(DisasContext *dc, DisasASI *da,
+ TCGv dst, TCGv src, TCGv addr)
{
switch (da->type) {
case GET_ASI_EXCP:
break;
case GET_ASI_DIRECT:
- gen_swap(dc, dst, src, addr, da->mem_idx, da->memop);
+ tcg_gen_atomic_xchg_tl(dst, addr, src,
+ da->mem_idx, da->memop | MO_ALIGN);
break;
default:
/* ??? Should be DAE_invalid_asi. */
@@ -2217,15 +2211,6 @@ static void gen_swap_asi0(DisasContext *dc, DisasASI *da,
}
}
-static void __attribute__((unused))
-gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src, TCGv addr, int insn)
-{
- DisasASI da = get_asi(dc, insn, MO_TEUL);
-
- gen_address_mask(dc, addr);
- gen_swap_asi0(dc, &da, dst, src, addr);
-}
-
static void gen_cas_asi0(DisasContext *dc, DisasASI *da,
TCGv oldv, TCGv newv, TCGv cmpv, TCGv addr)
{
@@ -4691,6 +4676,24 @@ static bool trans_LDSTUB(DisasContext *dc, arg_r_r_ri_asi *a)
return advance_pc(dc);
}
+static bool trans_SWAP(DisasContext *dc, arg_r_r_ri_asi *a)
+{
+ TCGv addr, dst, src;
+ DisasASI da;
+
+ addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ if (addr == NULL) {
+ return false;
+ }
+ da = resolve_asi(dc, a->asi, MO_TEUL);
+
+ dst = gen_dest_gpr(dc, a->rd);
+ src = gen_load_gpr(dc, a->rd);
+ gen_swap_asi(dc, &da, dst, src, addr);
+ gen_store_gpr(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4702,7 +4705,7 @@ static bool trans_LDSTUB(DisasContext *dc, arg_r_r_ri_asi *a)
static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
{
unsigned int opc, rs1, rs2, rd;
- TCGv cpu_src1;
+ TCGv cpu_src1 __attribute__((unused));
TCGv cpu_src2 __attribute__((unused));
TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
@@ -5520,6 +5523,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x9: /* ldsb, load signed byte */
case 0xa: /* ldsh, load signed halfword */
case 0xd: /* ldstub */
+ case 0x0f: /* swap */
case 0x10: /* lda, V9 lduwa, load word alternate */
case 0x11: /* lduba, load unsigned byte alternate */
case 0x12: /* lduha, load unsigned halfword alternate */
@@ -5527,25 +5531,13 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x19: /* ldsba, load signed byte alternate */
case 0x1a: /* ldsha, load signed halfword alternate */
case 0x1d: /* ldstuba */
+ case 0x1f: /* swapa */
g_assert_not_reached(); /* in decodetree */
case 0x08: /* V9 ldsw */
case 0x0b: /* V9 ldx */
case 0x18: /* V9 ldswa */
case 0x1b: /* V9 ldxa */
goto illegal_insn; /* in decodetree */
- case 0x0f:
- /* swap, swap register with memory. Also atomically */
- cpu_src1 = gen_load_gpr(dc, rd);
- gen_swap(dc, cpu_val, cpu_src1, cpu_addr,
- dc->mem_idx, MO_TEUL);
- break;
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
- case 0x1f: /* swapa, swap reg with alt. memory. Also
- atomically */
- cpu_src1 = gen_load_gpr(dc, rd);
- gen_swap_asi(dc, cpu_val, cpu_src1, cpu_addr, insn);
- break;
-#endif
#ifdef TARGET_SPARC64
case 0x2d: /* V9 prefetch, no effect */
goto skip_move;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 52/90] target/sparc: Move CASA, CASXA to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (50 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 51/90] target/sparc: Move SWAP, SWAPA " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 53/90] target/sparc: Move PREFETCH, PREFETCHA " Richard Henderson
` (38 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Remove gen_cas_asi, gen_casx_asi.
Rename gen_cas_asi0 to gen_cas_asi.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 7 ++++
target/sparc/translate.c | 71 +++++++++++++++------------------------
2 files changed, 35 insertions(+), 43 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 32ac9cdbf7..8e6a24e094 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -233,6 +233,8 @@ RETRY 10 00001 111110 00000 0 0000000000000
@r_r_r_asi .. rd:5 ...... rs1:5 0 asi:8 rs2_or_imm:5 &r_r_ri_asi imm=0
@r_r_i_asi .. rd:5 ...... rs1:5 1 rs2_or_imm:s13 \
&r_r_ri_asi imm=1 asi=-2
+@casa_imm .. rd:5 ...... rs1:5 1 00000000 rs2_or_imm:5 \
+ &r_r_ri_asi imm=1 asi=-2
LDUW 11 ..... 000000 ..... . ............. @r_r_ri_na
LDUB 11 ..... 000001 ..... . ............. @r_r_ri_na
@@ -285,6 +287,11 @@ SWAP 11 ..... 001111 ..... . ............. @r_r_ri_na
SWAP 11 ..... 011111 ..... . ............. @r_r_r_asi # SWAPA
SWAP 11 ..... 011111 ..... . ............. @r_r_i_asi # SWAPA
+CASA 11 ..... 111100 ..... . ............. @r_r_r_asi
+CASA 11 ..... 111100 ..... . ............. @casa_imm
+CASXA 11 ..... 111110 ..... . ............. @r_r_r_asi
+CASXA 11 ..... 111110 ..... . ............. @casa_imm
+
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index e1b8cdd798..6b860dbd75 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2211,8 +2211,8 @@ static void gen_swap_asi(DisasContext *dc, DisasASI *da,
}
}
-static void gen_cas_asi0(DisasContext *dc, DisasASI *da,
- TCGv oldv, TCGv newv, TCGv cmpv, TCGv addr)
+static void gen_cas_asi(DisasContext *dc, DisasASI *da,
+ TCGv oldv, TCGv newv, TCGv cmpv, TCGv addr)
{
switch (da->type) {
case GET_ASI_EXCP:
@@ -2228,30 +2228,6 @@ static void gen_cas_asi0(DisasContext *dc, DisasASI *da,
}
}
-static void __attribute__((unused))
-gen_cas_asi(DisasContext *dc, TCGv addr, TCGv cmpv, int insn, int rd)
-{
- DisasASI da = get_asi(dc, insn, MO_TEUL);
- TCGv oldv = gen_dest_gpr(dc, rd);
- TCGv newv = gen_load_gpr(dc, rd);
-
- gen_address_mask(dc, addr);
- gen_cas_asi0(dc, &da, oldv, newv, cmpv, addr);
- gen_store_gpr(dc, rd, oldv);
-}
-
-static void __attribute__((unused))
-gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv, int insn, int rd)
-{
- DisasASI da = get_asi(dc, insn, MO_TEUQ);
- TCGv oldv = gen_dest_gpr(dc, rd);
- TCGv newv = gen_load_gpr(dc, rd);
-
- gen_address_mask(dc, addr);
- gen_cas_asi0(dc, &da, oldv, newv, cmpv, addr);
- gen_store_gpr(dc, rd, oldv);
-}
-
static void gen_ldstub_asi(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
{
switch (da->type) {
@@ -2861,6 +2837,7 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
# define avail_64(C) false
#endif
#define avail_ASR17(C) ((C)->def->features & CPU_FEATURE_ASR17)
+#define avail_CASA(C) ((C)->def->features & CPU_FEATURE_CASA)
#define avail_DIV(C) ((C)->def->features & CPU_FEATURE_DIV)
#define avail_GL(C) ((C)->def->features & CPU_FEATURE_GL)
#define avail_HYPV(C) ((C)->def->features & CPU_FEATURE_HYPV)
@@ -4694,6 +4671,28 @@ static bool trans_SWAP(DisasContext *dc, arg_r_r_ri_asi *a)
return advance_pc(dc);
}
+static bool do_casa(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
+{
+ TCGv addr, o, n, c;
+ DisasASI da;
+
+ addr = gen_ldst_addr(dc, a->rs1, true, 0);
+ if (addr == NULL) {
+ return false;
+ }
+ da = resolve_asi(dc, a->asi, mop);
+
+ o = gen_dest_gpr(dc, a->rd);
+ n = gen_load_gpr(dc, a->rd);
+ c = gen_load_gpr(dc, a->rs2_or_imm);
+ gen_cas_asi(dc, &da, o, n, c, addr);
+ gen_store_gpr(dc, a->rd, o);
+ return advance_pc(dc);
+}
+
+TRANS(CASA, CASA, do_casa, a, MO_TEUL)
+TRANS(CASXA, 64, do_casa, a, MO_TEUQ)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5497,9 +5496,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv cpu_addr = tcg_temp_new();
tcg_gen_mov_tl(cpu_addr, get_src1(dc, insn));
- if (xop == 0x3c || xop == 0x3e) {
- /* V9 casa/casxa : no offset */
- } else if (IS_IMM) { /* immediate */
+ if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 19, 31);
if (simm != 0) {
tcg_gen_addi_tl(cpu_addr, cpu_addr, simm);
@@ -5712,22 +5709,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
}
gen_stf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
break;
+#endif
case 0x3e: /* V9 casxa */
- rs2 = GET_FIELD(insn, 27, 31);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_casx_asi(dc, cpu_addr, cpu_src2, insn, rd);
- break;
-#endif
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
case 0x3c: /* V9 or LEON3 casa */
-#ifndef TARGET_SPARC64
- CHECK_IU_FEATURE(dc, CASA);
-#endif
- rs2 = GET_FIELD(insn, 27, 31);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
- break;
-#endif
+ goto illegal_insn; /* in decodetree */
default:
goto illegal_insn;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 53/90] target/sparc: Move PREFETCH, PREFETCHA to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (51 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 52/90] target/sparc: Move CASA, CASXA " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 54/90] target/sparc: Split out fp ldst functions with asi precomputed Richard Henderson
` (37 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 8 ++++++--
target/sparc/translate.c | 14 ++++++++++----
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 8e6a24e094..86108679eb 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -224,6 +224,9 @@ RESTORE 10 ..... 111101 ..... . ............. @r_r_ri
DONE 10 00000 111110 00000 0 0000000000000
RETRY 10 00001 111110 00000 0 0000000000000
+NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
+NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
+
##
## Major Opcode 11 -- load and store instructions
##
@@ -292,8 +295,9 @@ CASA 11 ..... 111100 ..... . ............. @casa_imm
CASXA 11 ..... 111110 ..... . ............. @r_r_r_asi
CASXA 11 ..... 111110 ..... . ............. @casa_imm
-NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
-NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
+NOP_v9 11 ----- 101101 ----- 0 00000000 ----- # PREFETCH
+NOP_v9 11 ----- 101101 ----- 1 ------------- # PREFETCH
+NOP_v9 11 ----- 111101 ----- - ------------- # PREFETCHA
NCP 11 ----- 110000 ----- --------- ----- # v8 LDC
NCP 11 ----- 110001 ----- --------- ----- # v8 LDCSR
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 6b860dbd75..1b402de49f 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4101,6 +4101,14 @@ static bool trans_NOP_v7(DisasContext *dc, arg_NOP_v7 *a)
return false;
}
+static bool trans_NOP_v9(DisasContext *dc, arg_NOP_v9 *a)
+{
+ if (avail_64(dc)) {
+ return advance_pc(dc);
+ }
+ return false;
+}
+
static bool do_cc_arith(DisasContext *dc, arg_r_r_ri *a, int cc_op,
void (*func)(TCGv, TCGv, TCGv),
void (*funci)(TCGv, TCGv, target_long))
@@ -5534,10 +5542,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x0b: /* V9 ldx */
case 0x18: /* V9 ldswa */
case 0x1b: /* V9 ldxa */
+ case 0x2d: /* V9 prefetch */
+ case 0x3d: /* V9 prefetcha */
goto illegal_insn; /* in decodetree */
#ifdef TARGET_SPARC64
- case 0x2d: /* V9 prefetch, no effect */
- goto skip_move;
case 0x30: /* V9 ldfa */
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
@@ -5552,8 +5560,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
gen_ldf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
gen_update_fprs_dirty(dc, DFPREG(rd));
goto skip_move;
- case 0x3d: /* V9 prefetcha, no effect */
- goto skip_move;
case 0x32: /* V9 ldqfa */
CHECK_FPU_FEATURE(dc, FLOAT128);
if (gen_trap_ifnofpu(dc)) {
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 54/90] target/sparc: Split out fp ldst functions with asi precomputed
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (52 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 53/90] target/sparc: Move PREFETCH, PREFETCHA " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 55/90] target/sparc: Move simple fp load/store to decodetree Richard Henderson
` (36 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Take the operation size from the MemOp instead of a
separate parameter.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 136 ++++++++++++++++++++++-----------------
1 file changed, 78 insertions(+), 58 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 1b402de49f..822e74fa3e 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2263,35 +2263,40 @@ static void gen_ldstub_asi(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
}
}
-static void __attribute__((unused))
-gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
+static void gen_ldf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
{
- DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEUQ));
+ MemOp memop = da->memop;
+ MemOp size = memop & MO_SIZE;
TCGv_i32 d32;
TCGv_i64 d64;
- switch (da.type) {
+ /* TODO: Use 128-bit load/store below. */
+ if (size == MO_128) {
+ memop = (memop & ~MO_SIZE) | MO_64;
+ }
+
+ switch (da->type) {
case GET_ASI_EXCP:
break;
case GET_ASI_DIRECT:
- gen_address_mask(dc, addr);
+ memop |= MO_ALIGN_4;
switch (size) {
- case 4:
+ case MO_32:
d32 = gen_dest_fpr_F(dc);
- tcg_gen_qemu_ld_i32(d32, addr, da.mem_idx, da.memop | MO_ALIGN);
+ tcg_gen_qemu_ld_i32(d32, addr, da->mem_idx, memop);
gen_store_fpr_F(dc, rd, d32);
break;
- case 8:
- tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
- da.memop | MO_ALIGN_4);
+
+ case MO_64:
+ tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da->mem_idx, memop);
break;
- case 16:
+
+ case MO_128:
d64 = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(d64, addr, da.mem_idx, da.memop | MO_ALIGN_4);
+ tcg_gen_qemu_ld_i64(d64, addr, da->mem_idx, memop);
tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_ld_i64(cpu_fpr[rd/2+1], addr, da.mem_idx,
- da.memop | MO_ALIGN_4);
+ tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + 1], addr, da->mem_idx, memop);
tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
break;
default:
@@ -2301,24 +2306,19 @@ gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
case GET_ASI_BLOCK:
/* Valid for lddfa on aligned registers only. */
- if (size == 8 && (rd & 7) == 0) {
- MemOp memop;
+ if (size == MO_64 && (rd & 7) == 0) {
TCGv eight;
int i;
- gen_address_mask(dc, addr);
-
/* The first operation checks required alignment. */
- memop = da.memop | MO_ALIGN_64;
eight = tcg_constant_tl(8);
for (i = 0; ; ++i) {
- tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + i], addr,
- da.mem_idx, memop);
+ tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + i], addr, da->mem_idx,
+ memop | (i == 0 ? MO_ALIGN_64 : 0));
if (i == 7) {
break;
}
tcg_gen_add_tl(addr, addr, eight);
- memop = da.memop;
}
} else {
gen_exception(dc, TT_ILL_INSN);
@@ -2327,10 +2327,9 @@ gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
case GET_ASI_SHORT:
/* Valid for lddfa only. */
- if (size == 8) {
- gen_address_mask(dc, addr);
- tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
- da.memop | MO_ALIGN);
+ if (size == MO_64) {
+ tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da->mem_idx,
+ memop | MO_ALIGN);
} else {
gen_exception(dc, TT_ILL_INSN);
}
@@ -2338,8 +2337,8 @@ gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
default:
{
- TCGv_i32 r_asi = tcg_constant_i32(da.asi);
- TCGv_i32 r_mop = tcg_constant_i32(da.memop | MO_ALIGN);
+ TCGv_i32 r_asi = tcg_constant_i32(da->asi);
+ TCGv_i32 r_mop = tcg_constant_i32(memop | MO_ALIGN);
save_state(dc);
/* According to the table in the UA2011 manual, the only
@@ -2347,21 +2346,23 @@ gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
the NO_FAULT asis. We still need a helper for these,
but we can just use the integer asi helper for them. */
switch (size) {
- case 4:
+ 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);
tcg_gen_extrl_i64_i32(d32, d64);
gen_store_fpr_F(dc, rd, d32);
break;
- case 8:
- gen_helper_ld_asi(cpu_fpr[rd / 2], tcg_env, addr, r_asi, r_mop);
+ case MO_64:
+ gen_helper_ld_asi(cpu_fpr[rd / 2], tcg_env, addr,
+ r_asi, r_mop);
break;
- case 16:
+ case MO_128:
d64 = tcg_temp_new_i64();
gen_helper_ld_asi(d64, tcg_env, addr, r_asi, r_mop);
tcg_gen_addi_tl(addr, addr, 8);
- gen_helper_ld_asi(cpu_fpr[rd/2+1], tcg_env, addr, r_asi, r_mop);
+ gen_helper_ld_asi(cpu_fpr[rd / 2 + 1], tcg_env, addr,
+ r_asi, r_mop);
tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
break;
default:
@@ -2373,36 +2374,51 @@ gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
}
static void __attribute__((unused))
-gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
+gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
{
- DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEUQ));
+ DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL :
+ size == 8 ? MO_TEUQ : MO_TE | MO_128));
+
+ gen_address_mask(dc, addr);
+ gen_ldf_asi0(dc, &da, addr, rd);
+}
+
+static void gen_stf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
+{
+ MemOp memop = da->memop;
+ MemOp size = memop & MO_SIZE;
TCGv_i32 d32;
- switch (da.type) {
+ /* TODO: Use 128-bit load/store below. */
+ if (size == MO_128) {
+ memop = (memop & ~MO_SIZE) | MO_64;
+ }
+
+ switch (da->type) {
case GET_ASI_EXCP:
break;
case GET_ASI_DIRECT:
- gen_address_mask(dc, addr);
+ memop |= MO_ALIGN_4;
switch (size) {
- case 4:
+ case MO_32:
d32 = gen_load_fpr_F(dc, rd);
- tcg_gen_qemu_st_i32(d32, addr, da.mem_idx, da.memop | MO_ALIGN);
+ tcg_gen_qemu_st_i32(d32, addr, da->mem_idx, memop | MO_ALIGN);
break;
- case 8:
- tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
- da.memop | MO_ALIGN_4);
+ case MO_64:
+ tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da->mem_idx,
+ memop | MO_ALIGN_4);
break;
- case 16:
+ case MO_128:
/* Only 4-byte alignment required. However, it is legal for the
cpu to signal the alignment fault, and the OS trap handler is
required to fix it up. Requiring 16-byte alignment here avoids
having to probe the second page before performing the first
write. */
- tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
- da.memop | MO_ALIGN_16);
+ tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da->mem_idx,
+ memop | MO_ALIGN_16);
tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_st_i64(cpu_fpr[rd/2+1], addr, da.mem_idx, da.memop);
+ tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + 1], addr, da->mem_idx, memop);
break;
default:
g_assert_not_reached();
@@ -2411,24 +2427,19 @@ gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
case GET_ASI_BLOCK:
/* Valid for stdfa on aligned registers only. */
- if (size == 8 && (rd & 7) == 0) {
- MemOp memop;
+ if (size == MO_64 && (rd & 7) == 0) {
TCGv eight;
int i;
- gen_address_mask(dc, addr);
-
/* The first operation checks required alignment. */
- memop = da.memop | MO_ALIGN_64;
eight = tcg_constant_tl(8);
for (i = 0; ; ++i) {
- tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + i], addr,
- da.mem_idx, memop);
+ tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + i], addr, da->mem_idx,
+ memop | (i == 0 ? MO_ALIGN_64 : 0));
if (i == 7) {
break;
}
tcg_gen_add_tl(addr, addr, eight);
- memop = da.memop;
}
} else {
gen_exception(dc, TT_ILL_INSN);
@@ -2437,10 +2448,9 @@ gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
case GET_ASI_SHORT:
/* Valid for stdfa only. */
- if (size == 8) {
- gen_address_mask(dc, addr);
- tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
- da.memop | MO_ALIGN);
+ if (size == MO_64) {
+ tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da->mem_idx,
+ memop | MO_ALIGN);
} else {
gen_exception(dc, TT_ILL_INSN);
}
@@ -2455,6 +2465,16 @@ gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
}
}
+static void __attribute__((unused))
+gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
+{
+ DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL :
+ size == 8 ? MO_TEUQ : MO_TE | MO_128));
+
+ gen_address_mask(dc, addr);
+ gen_stf_asi0(dc, &da, addr, rd);
+}
+
static void gen_ldda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
{
TCGv hi = gen_dest_gpr(dc, rd);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 55/90] target/sparc: Move simple fp load/store to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (53 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 54/90] target/sparc: Split out fp ldst functions with asi precomputed Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 56/90] target/sparc: Move asi " Richard Henderson
` (35 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 19 ++++
target/sparc/translate.c | 194 ++++++++++++++++++--------------------
2 files changed, 113 insertions(+), 100 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 86108679eb..ab311055da 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -231,8 +231,16 @@ NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
## Major Opcode 11 -- load and store instructions
##
+%dfp_rd 25:5 !function=extract_dfpreg
+%qfp_rd 25:5 !function=extract_qfpreg
+
&r_r_ri_asi rd rs1 rs2_or_imm asi imm:bool
@r_r_ri_na .. rd:5 ...... rs1:5 imm:1 rs2_or_imm:s13 &r_r_ri_asi asi=-1
+@d_r_ri_na .. ..... ...... rs1:5 imm:1 rs2_or_imm:s13 \
+ &r_r_ri_asi rd=%dfp_rd asi=-1
+@q_r_ri_na .. ..... ...... rs1:5 imm:1 rs2_or_imm:s13 \
+ &r_r_ri_asi rd=%qfp_rd asi=-1
+
@r_r_r_asi .. rd:5 ...... rs1:5 0 asi:8 rs2_or_imm:5 &r_r_ri_asi imm=0
@r_r_i_asi .. rd:5 ...... rs1:5 1 rs2_or_imm:s13 \
&r_r_ri_asi imm=1 asi=-2
@@ -282,6 +290,17 @@ STD 11 ..... 010111 ..... . ............. @r_r_i_asi # STDA
STX 11 ..... 011110 ..... . ............. @r_r_r_asi # STXA
STX 11 ..... 011110 ..... . ............. @r_r_i_asi # STXA
+LDF 11 ..... 100000 ..... . ............. @r_r_ri_na
+LDQF 11 ..... 100010 ..... . ............. @q_r_ri_na
+LDDF 11 ..... 100011 ..... . ............. @d_r_ri_na
+
+STF 11 ..... 100100 ..... . ............. @r_r_ri_na
+{
+ STQF 11 ..... 100110 ..... . ............. @q_r_ri_na
+ STDFQ 11 ----- 100110 ----- - -------------
+}
+STDF 11 ..... 100111 ..... . ............. @d_r_ri_na
+
LDSTUB 11 ..... 001101 ..... . ............. @r_r_ri_na
LDSTUB 11 ..... 011101 ..... . ............. @r_r_r_asi # LDSTUBA
LDSTUB 11 ..... 011101 ..... . ............. @r_r_i_asi # LDSTUBA
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 822e74fa3e..eeec1e751c 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -253,29 +253,7 @@ static void gen_op_store_QT0_fpr(unsigned int dst)
offsetof(CPU_QuadU, ll.lower));
}
-static void gen_store_fpr_Q(DisasContext *dc, unsigned int dst,
- TCGv_i64 v1, TCGv_i64 v2)
-{
- dst = QFPREG(dst);
-
- tcg_gen_mov_i64(cpu_fpr[dst / 2], v1);
- tcg_gen_mov_i64(cpu_fpr[dst / 2 + 1], v2);
- gen_update_fprs_dirty(dc, dst);
-}
-
#ifdef TARGET_SPARC64
-static TCGv_i64 gen_load_fpr_Q0(DisasContext *dc, unsigned int src)
-{
- src = QFPREG(src);
- return cpu_fpr[src / 2];
-}
-
-static TCGv_i64 gen_load_fpr_Q1(DisasContext *dc, unsigned int src)
-{
- src = QFPREG(src);
- return cpu_fpr[src / 2 + 1];
-}
-
static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
{
rd = QFPREG(rd);
@@ -2841,6 +2819,16 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
}
#endif
+static int extract_dfpreg(DisasContext *dc, int x)
+{
+ return DFPREG(x);
+}
+
+static int extract_qfpreg(DisasContext *dc, int x)
+{
+ return QFPREG(x);
+}
+
/* Include the auto-generated decoder. */
#include "decode-insns.c.inc"
@@ -2969,6 +2957,20 @@ static bool raise_priv(DisasContext *dc)
return true;
}
+static bool raise_unimpfpop(DisasContext *dc)
+{
+ gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
+ return true;
+}
+
+static bool gen_trap_float128(DisasContext *dc)
+{
+ if (dc->def->features & CPU_FEATURE_FLOAT128) {
+ return false;
+ }
+ return raise_unimpfpop(dc);
+}
+
static bool do_bpcc(DisasContext *dc, arg_bcc *a)
{
target_long target = dc->pc + a->i * 4;
@@ -4721,6 +4723,68 @@ static bool do_casa(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
TRANS(CASA, CASA, do_casa, a, MO_TEUL)
TRANS(CASXA, 64, do_casa, a, MO_TEUQ)
+static bool do_ld_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
+{
+ TCGv addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ DisasASI da;
+
+ if (addr == NULL) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if ((mop & MO_SIZE) == MO_128 && gen_trap_float128(dc)) {
+ return true;
+ }
+ da = resolve_asi(dc, a->asi, mop);
+ gen_ldf_asi0(dc, &da, addr, a->rd);
+ gen_update_fprs_dirty(dc, a->rd);
+ return advance_pc(dc);
+}
+
+TRANS(LDF, ALL, do_ld_fpr, a, MO_TEUL)
+TRANS(LDDF, ALL, do_ld_fpr, a, MO_TEUQ)
+TRANS(LDQF, ALL, do_ld_fpr, a, MO_TE | MO_128)
+
+static bool do_st_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
+{
+ TCGv addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ DisasASI da;
+
+ if (addr == NULL) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if ((mop & MO_SIZE) == MO_128 && gen_trap_float128(dc)) {
+ return true;
+ }
+ da = resolve_asi(dc, a->asi, mop);
+ gen_stf_asi0(dc, &da, addr, a->rd);
+ return advance_pc(dc);
+}
+
+TRANS(STF, ALL, do_st_fpr, a, MO_TEUL)
+TRANS(STDF, ALL, do_st_fpr, a, MO_TEUQ)
+TRANS(STQF, ALL, do_st_fpr, a, MO_TE | MO_128)
+
+static bool trans_STDFQ(DisasContext *dc, arg_STDFQ *a)
+{
+ if (!avail_32(dc)) {
+ return false;
+ }
+ if (!supervisor(dc)) {
+ return raise_priv(dc);
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
+ return true;
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4735,7 +4799,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv cpu_src1 __attribute__((unused));
TCGv cpu_src2 __attribute__((unused));
TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
- TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
+ TCGv_i64 cpu_src1_64, cpu_src2_64;
+ TCGv_i64 cpu_dst_64 __attribute__((unused));
target_long simm;
opc = GET_FIELD(insn, 0, 1);
@@ -5602,12 +5667,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
}
switch (xop) {
case 0x20: /* ldf, load fpreg */
- gen_address_mask(dc, cpu_addr);
- cpu_dst_32 = gen_dest_fpr_F(dc);
- tcg_gen_qemu_ld_i32(cpu_dst_32, cpu_addr,
- dc->mem_idx, MO_TEUL | MO_ALIGN);
- gen_store_fpr_F(dc, rd, cpu_dst_32);
- break;
+ case 0x22: /* ldqf, load quad fpreg */
+ case 0x23: /* lddf, load double fpreg */
+ g_assert_not_reached(); /* in decodetree */
case 0x21: /* ldfsr, V9 ldxfsr */
#ifdef TARGET_SPARC64
gen_address_mask(dc, cpu_addr);
@@ -5624,25 +5686,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
dc->mem_idx, MO_TEUL | MO_ALIGN);
gen_helper_ldfsr(cpu_fsr, tcg_env, cpu_fsr, cpu_dst_32);
break;
- case 0x22: /* ldqf, load quad fpreg */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_address_mask(dc, cpu_addr);
- cpu_src1_64 = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(cpu_src1_64, cpu_addr, dc->mem_idx,
- MO_TEUQ | MO_ALIGN_4);
- tcg_gen_addi_tl(cpu_addr, cpu_addr, 8);
- cpu_src2_64 = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(cpu_src2_64, cpu_addr, dc->mem_idx,
- MO_TEUQ | MO_ALIGN_4);
- gen_store_fpr_Q(dc, rd, cpu_src1_64, cpu_src2_64);
- break;
- case 0x23: /* lddf, load double fpreg */
- gen_address_mask(dc, cpu_addr);
- cpu_dst_64 = gen_dest_fpr_D(dc, rd);
- tcg_gen_qemu_ld_i64(cpu_dst_64, cpu_addr, dc->mem_idx,
- MO_TEUQ | MO_ALIGN_4);
- gen_store_fpr_D(dc, rd, cpu_dst_64);
- break;
default:
goto illegal_insn;
}
@@ -5652,11 +5695,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
}
switch (xop) {
case 0x24: /* stf, store fpreg */
- gen_address_mask(dc, cpu_addr);
- cpu_src1_32 = gen_load_fpr_F(dc, rd);
- tcg_gen_qemu_st_i32(cpu_src1_32, cpu_addr,
- dc->mem_idx, MO_TEUL | MO_ALIGN);
- break;
+ case 0x26: /* v9 stqf, v8 stdfq */
+ case 0x27: /* stdf, store double fpreg */
+ g_assert_not_reached();
case 0x25: /* stfsr, V9 stxfsr */
{
#ifdef TARGET_SPARC64
@@ -5671,43 +5712,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
dc->mem_idx, MO_TEUL | MO_ALIGN);
}
break;
- case 0x26:
-#ifdef TARGET_SPARC64
- /* V9 stqf, store quad fpreg */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_address_mask(dc, cpu_addr);
- /* ??? While stqf only requires 4-byte alignment, it is
- legal for the cpu to signal the unaligned exception.
- The OS trap handler is then required to fix it up.
- For qemu, this avoids having to probe the second page
- before performing the first write. */
- cpu_src1_64 = gen_load_fpr_Q0(dc, rd);
- tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr,
- dc->mem_idx, MO_TEUQ | MO_ALIGN_16);
- tcg_gen_addi_tl(cpu_addr, cpu_addr, 8);
- cpu_src2_64 = gen_load_fpr_Q1(dc, rd);
- tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr,
- dc->mem_idx, MO_TEUQ);
- break;
-#else /* !TARGET_SPARC64 */
- /* stdfq, store floating point queue */
-#if defined(CONFIG_USER_ONLY)
- goto illegal_insn;
-#else
- if (!supervisor(dc))
- goto priv_insn;
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- goto nfq_insn;
-#endif
-#endif
- case 0x27: /* stdf, store double fpreg */
- gen_address_mask(dc, cpu_addr);
- cpu_src1_64 = gen_load_fpr_D(dc, rd);
- tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr, dc->mem_idx,
- MO_TEUQ | MO_ALIGN_4);
- break;
default:
goto illegal_insn;
}
@@ -5754,19 +5758,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
illegal_insn:
gen_exception(dc, TT_ILL_INSN);
return;
-#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
- priv_insn:
- gen_exception(dc, TT_PRIV_INSN);
- return;
-#endif
nfpu_insn:
gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
return;
-#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
- nfq_insn:
- gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
- return;
-#endif
}
static void sparc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 56/90] target/sparc: Move asi fp load/store to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (54 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 55/90] target/sparc: Move simple fp load/store to decodetree Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 57/90] target/sparc: Move LDFSR, STFSR " Richard Henderson
` (34 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 51 ++++++++++--
target/sparc/translate.c | 169 ++++++++------------------------------
2 files changed, 79 insertions(+), 141 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index ab311055da..fa9c8d3d8b 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -244,6 +244,14 @@ NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
@r_r_r_asi .. rd:5 ...... rs1:5 0 asi:8 rs2_or_imm:5 &r_r_ri_asi imm=0
@r_r_i_asi .. rd:5 ...... rs1:5 1 rs2_or_imm:s13 \
&r_r_ri_asi imm=1 asi=-2
+@d_r_r_asi .. ..... ...... rs1:5 0 asi:8 rs2_or_imm:5 \
+ &r_r_ri_asi rd=%dfp_rd imm=0
+@d_r_i_asi .. ..... ...... rs1:5 1 rs2_or_imm:s13 \
+ &r_r_ri_asi rd=%dfp_rd imm=1 asi=-2
+@q_r_r_asi .. ..... ...... rs1:5 0 asi:8 rs2_or_imm:5 \
+ &r_r_ri_asi rd=%qfp_rd imm=0
+@q_r_i_asi .. ..... ...... rs1:5 1 rs2_or_imm:s13 \
+ &r_r_ri_asi rd=%qfp_rd imm=1 asi=-2
@casa_imm .. rd:5 ...... rs1:5 1 00000000 rs2_or_imm:5 \
&r_r_ri_asi imm=1 asi=-2
@@ -318,10 +326,43 @@ NOP_v9 11 ----- 101101 ----- 0 00000000 ----- # PREFETCH
NOP_v9 11 ----- 101101 ----- 1 ------------- # PREFETCH
NOP_v9 11 ----- 111101 ----- - ------------- # PREFETCHA
-NCP 11 ----- 110000 ----- --------- ----- # v8 LDC
+{
+ [
+ LDFA 11 ..... 110000 ..... . ............. @r_r_r_asi
+ LDFA 11 ..... 110000 ..... . ............. @r_r_i_asi
+ ]
+ NCP 11 ----- 110000 ----- --------- ----- # v8 LDC
+}
NCP 11 ----- 110001 ----- --------- ----- # v8 LDCSR
-NCP 11 ----- 110011 ----- --------- ----- # v8 LDDC
-NCP 11 ----- 110100 ----- --------- ----- # v8 STC
+LDQFA 11 ..... 110010 ..... . ............. @q_r_r_asi
+LDQFA 11 ..... 110010 ..... . ............. @q_r_i_asi
+{
+ [
+ LDDFA 11 ..... 110011 ..... . ............. @d_r_r_asi
+ LDDFA 11 ..... 110011 ..... . ............. @d_r_i_asi
+ ]
+ NCP 11 ----- 110011 ----- --------- ----- # v8 LDDC
+}
+
+{
+ [
+ STFA 11 ..... 110100 ..... . ............. @r_r_r_asi
+ STFA 11 ..... 110100 ..... . ............. @r_r_i_asi
+ ]
+ NCP 11 ----- 110100 ----- --------- ----- # v8 STC
+}
NCP 11 ----- 110101 ----- --------- ----- # v8 STCSR
-NCP 11 ----- 110110 ----- --------- ----- # v8 STDCQ
-NCP 11 ----- 110111 ----- --------- ----- # v8 STDC
+{
+ [
+ STQFA 11 ..... 110110 ..... . ............. @q_r_r_asi
+ STQFA 11 ..... 110110 ..... . ............. @q_r_i_asi
+ ]
+ NCP 11 ----- 110110 ----- --------- ----- # v8 STDCQ
+}
+{
+ [
+ STDFA 11 ..... 110111 ..... . ............. @d_r_r_asi
+ STDFA 11 ..... 110111 ..... . ............. @d_r_i_asi
+ ]
+ NCP 11 ----- 110111 ----- --------- ----- # v8 STDC
+}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index eeec1e751c..6fdcfebe55 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2063,12 +2063,6 @@ static DisasASI resolve_asi(DisasContext *dc, int asi, MemOp memop)
return (DisasASI){ type, asi, mem_idx, memop };
}
-static DisasASI get_asi(DisasContext *dc, int insn, MemOp memop)
-{
- int asi = IS_IMM ? -2 : GET_FIELD(insn, 19, 26);
- return resolve_asi(dc, asi, memop);
-}
-
static void gen_ld_asi(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
{
switch (da->type) {
@@ -2241,12 +2235,13 @@ static void gen_ldstub_asi(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
}
}
-static void gen_ldf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
+static void gen_ldf_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
{
MemOp memop = da->memop;
MemOp size = memop & MO_SIZE;
TCGv_i32 d32;
TCGv_i64 d64;
+ TCGv addr_tmp;
/* TODO: Use 128-bit load/store below. */
if (size == MO_128) {
@@ -2273,8 +2268,9 @@ static void gen_ldf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
case MO_128:
d64 = tcg_temp_new_i64();
tcg_gen_qemu_ld_i64(d64, addr, da->mem_idx, memop);
- tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + 1], addr, da->mem_idx, memop);
+ addr_tmp = tcg_temp_new();
+ tcg_gen_addi_tl(addr_tmp, addr, 8);
+ tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + 1], addr_tmp, da->mem_idx, memop);
tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
break;
default:
@@ -2285,18 +2281,16 @@ static void gen_ldf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
case GET_ASI_BLOCK:
/* Valid for lddfa on aligned registers only. */
if (size == MO_64 && (rd & 7) == 0) {
- TCGv eight;
- int i;
-
/* The first operation checks required alignment. */
- eight = tcg_constant_tl(8);
- for (i = 0; ; ++i) {
+ addr_tmp = tcg_temp_new();
+ for (int i = 0; ; ++i) {
tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + i], addr, da->mem_idx,
memop | (i == 0 ? MO_ALIGN_64 : 0));
if (i == 7) {
break;
}
- tcg_gen_add_tl(addr, addr, eight);
+ tcg_gen_addi_tl(addr_tmp, addr, 8);
+ addr = addr_tmp;
}
} else {
gen_exception(dc, TT_ILL_INSN);
@@ -2338,8 +2332,9 @@ static void gen_ldf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
case MO_128:
d64 = tcg_temp_new_i64();
gen_helper_ld_asi(d64, tcg_env, addr, r_asi, r_mop);
- tcg_gen_addi_tl(addr, addr, 8);
- gen_helper_ld_asi(cpu_fpr[rd / 2 + 1], tcg_env, addr,
+ addr_tmp = tcg_temp_new();
+ tcg_gen_addi_tl(addr_tmp, addr, 8);
+ gen_helper_ld_asi(cpu_fpr[rd / 2 + 1], tcg_env, addr_tmp,
r_asi, r_mop);
tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
break;
@@ -2351,21 +2346,12 @@ static void gen_ldf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
}
}
-static void __attribute__((unused))
-gen_ldf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
-{
- DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL :
- size == 8 ? MO_TEUQ : MO_TE | MO_128));
-
- gen_address_mask(dc, addr);
- gen_ldf_asi0(dc, &da, addr, rd);
-}
-
-static void gen_stf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
+static void gen_stf_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
{
MemOp memop = da->memop;
MemOp size = memop & MO_SIZE;
TCGv_i32 d32;
+ TCGv addr_tmp;
/* TODO: Use 128-bit load/store below. */
if (size == MO_128) {
@@ -2395,8 +2381,9 @@ static void gen_stf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
write. */
tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da->mem_idx,
memop | MO_ALIGN_16);
- tcg_gen_addi_tl(addr, addr, 8);
- tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + 1], addr, da->mem_idx, memop);
+ addr_tmp = tcg_temp_new();
+ tcg_gen_addi_tl(addr_tmp, addr, 8);
+ tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + 1], addr_tmp, da->mem_idx, memop);
break;
default:
g_assert_not_reached();
@@ -2406,18 +2393,16 @@ static void gen_stf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
case GET_ASI_BLOCK:
/* Valid for stdfa on aligned registers only. */
if (size == MO_64 && (rd & 7) == 0) {
- TCGv eight;
- int i;
-
/* The first operation checks required alignment. */
- eight = tcg_constant_tl(8);
- for (i = 0; ; ++i) {
+ addr_tmp = tcg_temp_new();
+ for (int i = 0; ; ++i) {
tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + i], addr, da->mem_idx,
memop | (i == 0 ? MO_ALIGN_64 : 0));
if (i == 7) {
break;
}
- tcg_gen_add_tl(addr, addr, eight);
+ tcg_gen_addi_tl(addr_tmp, addr, 8);
+ addr = addr_tmp;
}
} else {
gen_exception(dc, TT_ILL_INSN);
@@ -2443,16 +2428,6 @@ static void gen_stf_asi0(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
}
}
-static void __attribute__((unused))
-gen_stf_asi(DisasContext *dc, TCGv addr, int insn, int size, int rd)
-{
- DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL :
- size == 8 ? MO_TEUQ : MO_TE | MO_128));
-
- gen_address_mask(dc, addr);
- gen_stf_asi0(dc, &da, addr, rd);
-}
-
static void gen_ldda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
{
TCGv hi = gen_dest_gpr(dc, rd);
@@ -4738,7 +4713,7 @@ static bool do_ld_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
return true;
}
da = resolve_asi(dc, a->asi, mop);
- gen_ldf_asi0(dc, &da, addr, a->rd);
+ gen_ldf_asi(dc, &da, addr, a->rd);
gen_update_fprs_dirty(dc, a->rd);
return advance_pc(dc);
}
@@ -4747,6 +4722,10 @@ TRANS(LDF, ALL, do_ld_fpr, a, MO_TEUL)
TRANS(LDDF, ALL, do_ld_fpr, a, MO_TEUQ)
TRANS(LDQF, ALL, do_ld_fpr, a, MO_TE | MO_128)
+TRANS(LDFA, 64, do_ld_fpr, a, MO_TEUL)
+TRANS(LDDFA, 64, do_ld_fpr, a, MO_TEUQ)
+TRANS(LDQFA, 64, do_ld_fpr, a, MO_TE | MO_128)
+
static bool do_st_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
{
TCGv addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
@@ -4762,7 +4741,7 @@ static bool do_st_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
return true;
}
da = resolve_asi(dc, a->asi, mop);
- gen_stf_asi0(dc, &da, addr, a->rd);
+ gen_stf_asi(dc, &da, addr, a->rd);
return advance_pc(dc);
}
@@ -4770,6 +4749,10 @@ TRANS(STF, ALL, do_st_fpr, a, MO_TEUL)
TRANS(STDF, ALL, do_st_fpr, a, MO_TEUQ)
TRANS(STQF, ALL, do_st_fpr, a, MO_TE | MO_128)
+TRANS(STFA, 64, do_st_fpr, a, MO_TEUL)
+TRANS(STDFA, 64, do_st_fpr, a, MO_TEUQ)
+TRANS(STQFA, 64, do_st_fpr, a, MO_TE | MO_128)
+
static bool trans_STDFQ(DisasContext *dc, arg_STDFQ *a)
{
if (!avail_32(dc)) {
@@ -5603,64 +5586,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
(xop > 0x17 && xop <= 0x1d ) ||
(xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
- TCGv cpu_val = gen_dest_gpr(dc, rd);
-
- switch (xop) {
- case 0x0: /* ld, V9 lduw, load unsigned word */
- case 0x1: /* ldub, load unsigned byte */
- case 0x2: /* lduh, load unsigned halfword */
- case 0x3: /* ldd, load double word */
- case 0x9: /* ldsb, load signed byte */
- case 0xa: /* ldsh, load signed halfword */
- case 0xd: /* ldstub */
- case 0x0f: /* swap */
- case 0x10: /* lda, V9 lduwa, load word alternate */
- case 0x11: /* lduba, load unsigned byte alternate */
- case 0x12: /* lduha, load unsigned halfword alternate */
- case 0x13: /* ldda, load double word alternate */
- case 0x19: /* ldsba, load signed byte alternate */
- case 0x1a: /* ldsha, load signed halfword alternate */
- case 0x1d: /* ldstuba */
- case 0x1f: /* swapa */
- g_assert_not_reached(); /* in decodetree */
- case 0x08: /* V9 ldsw */
- case 0x0b: /* V9 ldx */
- case 0x18: /* V9 ldswa */
- case 0x1b: /* V9 ldxa */
- case 0x2d: /* V9 prefetch */
- case 0x3d: /* V9 prefetcha */
- goto illegal_insn; /* in decodetree */
-#ifdef TARGET_SPARC64
- case 0x30: /* V9 ldfa */
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- gen_ldf_asi(dc, cpu_addr, insn, 4, rd);
- gen_update_fprs_dirty(dc, rd);
- goto skip_move;
- case 0x33: /* V9 lddfa */
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- gen_ldf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
- gen_update_fprs_dirty(dc, DFPREG(rd));
- goto skip_move;
- case 0x32: /* V9 ldqfa */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- gen_ldf_asi(dc, cpu_addr, insn, 16, QFPREG(rd));
- gen_update_fprs_dirty(dc, QFPREG(rd));
- goto skip_move;
-#endif
- default:
- goto illegal_insn;
- }
- gen_store_gpr(dc, rd, cpu_val);
-#if defined(TARGET_SPARC64)
- skip_move: ;
-#endif
+ goto illegal_insn; /* in decodetree */
} else if (xop >= 0x20 && xop < 0x24) {
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
@@ -5716,36 +5642,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
goto illegal_insn;
}
} else if (xop > 0x33 && xop < 0x3f) {
- switch (xop) {
-#ifdef TARGET_SPARC64
- case 0x34: /* V9 stfa */
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- gen_stf_asi(dc, cpu_addr, insn, 4, rd);
- break;
- case 0x36: /* V9 stqfa */
- {
- CHECK_FPU_FEATURE(dc, FLOAT128);
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- gen_stf_asi(dc, cpu_addr, insn, 16, QFPREG(rd));
- }
- break;
- case 0x37: /* V9 stdfa */
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- gen_stf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
- break;
-#endif
- case 0x3e: /* V9 casxa */
- case 0x3c: /* V9 or LEON3 casa */
- goto illegal_insn; /* in decodetree */
- default:
- goto illegal_insn;
- }
+ goto illegal_insn; /* in decodetree */
} else {
goto illegal_insn;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 57/90] target/sparc: Move LDFSR, STFSR to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (55 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 56/90] target/sparc: Move asi " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 58/90] target/sparc: Merge LDFSR, LDXFSR implementations Richard Henderson
` (33 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 +
target/sparc/translate.c | 152 +++++++++++++++-----------------------
2 files changed, 64 insertions(+), 92 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index fa9c8d3d8b..42eb807e21 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -299,10 +299,14 @@ STX 11 ..... 011110 ..... . ............. @r_r_r_asi # STXA
STX 11 ..... 011110 ..... . ............. @r_r_i_asi # STXA
LDF 11 ..... 100000 ..... . ............. @r_r_ri_na
+LDFSR 11 00000 100001 ..... . ............. @n_r_ri
+LDXFSR 11 00001 100001 ..... . ............. @n_r_ri
LDQF 11 ..... 100010 ..... . ............. @q_r_ri_na
LDDF 11 ..... 100011 ..... . ............. @d_r_ri_na
STF 11 ..... 100100 ..... . ............. @r_r_ri_na
+STFSR 11 00000 100101 ..... . ............. @n_r_ri
+STXFSR 11 00001 100101 ..... . ............. @n_r_ri
{
STQF 11 ..... 100110 ..... . ............. @q_r_ri_na
STDFQ 11 ----- 100110 ----- - -------------
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 6fdcfebe55..b23f77a199 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -58,6 +58,7 @@
#define gen_helper_retry(E) qemu_build_not_reached()
#define gen_helper_udivx(D, E, A, B) qemu_build_not_reached()
#define gen_helper_sdivx(D, E, A, B) qemu_build_not_reached()
+#define gen_helper_ldxfsr(R, E, X, Y) qemu_build_not_reached()
# ifdef CONFIG_USER_ONLY
static void gen_helper_ld_asi(TCGv_i64 r, TCGv_env e, TCGv a,
TCGv_i32 asi, TCGv_i32 mop)
@@ -163,12 +164,6 @@ typedef struct {
#define UA2005_HTRAP_MASK 0xff
#define V8_TRAP_MASK 0x7f
-static int sign_extend(int x, int len)
-{
- len = 32 - len;
- return (x << len) >> len;
-}
-
#define IS_IMM (insn & (1<<13))
static void gen_update_fprs_dirty(DisasContext *dc, int rd)
@@ -2596,13 +2591,13 @@ static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
}
}
+#ifdef TARGET_SPARC64
static TCGv get_src1(DisasContext *dc, unsigned int insn)
{
unsigned int rs1 = GET_FIELD(insn, 13, 17);
return gen_load_gpr(dc, rs1);
}
-#ifdef TARGET_SPARC64
static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
{
TCGv_i32 c32, zero, dst, s1, s2;
@@ -4768,6 +4763,61 @@ static bool trans_STDFQ(DisasContext *dc, arg_STDFQ *a)
return true;
}
+static bool trans_LDFSR(DisasContext *dc, arg_r_r_ri *a)
+{
+ TCGv addr;
+ TCGv_i32 tmp;
+
+ addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ if (addr == NULL) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ tmp = tcg_temp_new_i32();
+ tcg_gen_qemu_ld_i32(tmp, addr, dc->mem_idx, MO_TEUL | MO_ALIGN);
+ gen_helper_ldfsr(cpu_fsr, tcg_env, cpu_fsr, tmp);
+ return advance_pc(dc);
+}
+
+static bool trans_LDXFSR(DisasContext *dc, arg_r_r_ri *a)
+{
+ TCGv addr;
+ TCGv_i64 tmp;
+
+ if (!avail_64(dc)) {
+ return false;
+ }
+ addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ if (addr == NULL) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ tmp = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_i64(tmp, addr, dc->mem_idx, MO_TEUQ | MO_ALIGN);
+ gen_helper_ldxfsr(cpu_fsr, tcg_env, cpu_fsr, tmp);
+ return advance_pc(dc);
+}
+
+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);
+ 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);
+ return advance_pc(dc);
+}
+
+TRANS(STFSR, ALL, do_stfsr, a, MO_TEUL)
+TRANS(STXFSR, 64, do_stfsr, a, MO_TEUQ)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4781,10 +4831,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
unsigned int opc, rs1, rs2, rd;
TCGv cpu_src1 __attribute__((unused));
TCGv cpu_src2 __attribute__((unused));
- TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
+ TCGv_i32 cpu_src1_32, cpu_src2_32;
TCGv_i64 cpu_src1_64, cpu_src2_64;
+ TCGv_i32 cpu_dst_32 __attribute__((unused));
TCGv_i64 cpu_dst_64 __attribute__((unused));
- target_long simm;
opc = GET_FIELD(insn, 0, 1);
rd = GET_FIELD(insn, 2, 6);
@@ -5565,89 +5615,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
}
break;
case 3: /* load/store instructions */
- {
- unsigned int xop = GET_FIELD(insn, 7, 12);
- /* ??? gen_address_mask prevents us from using a source
- register directly. Always generate a temporary. */
- TCGv cpu_addr = tcg_temp_new();
-
- tcg_gen_mov_tl(cpu_addr, get_src1(dc, insn));
- if (IS_IMM) { /* immediate */
- simm = GET_FIELDs(insn, 19, 31);
- if (simm != 0) {
- tcg_gen_addi_tl(cpu_addr, cpu_addr, simm);
- }
- } else { /* register */
- rs2 = GET_FIELD(insn, 27, 31);
- if (rs2 != 0) {
- tcg_gen_add_tl(cpu_addr, cpu_addr, gen_load_gpr(dc, rs2));
- }
- }
- if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
- (xop > 0x17 && xop <= 0x1d ) ||
- (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
- goto illegal_insn; /* in decodetree */
- } else if (xop >= 0x20 && xop < 0x24) {
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- switch (xop) {
- case 0x20: /* ldf, load fpreg */
- case 0x22: /* ldqf, load quad fpreg */
- case 0x23: /* lddf, load double fpreg */
- g_assert_not_reached(); /* in decodetree */
- case 0x21: /* ldfsr, V9 ldxfsr */
-#ifdef TARGET_SPARC64
- gen_address_mask(dc, cpu_addr);
- if (rd == 1) {
- TCGv_i64 t64 = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(t64, cpu_addr,
- dc->mem_idx, MO_TEUQ | MO_ALIGN);
- gen_helper_ldxfsr(cpu_fsr, tcg_env, cpu_fsr, t64);
- break;
- }
-#endif
- cpu_dst_32 = tcg_temp_new_i32();
- tcg_gen_qemu_ld_i32(cpu_dst_32, cpu_addr,
- dc->mem_idx, MO_TEUL | MO_ALIGN);
- gen_helper_ldfsr(cpu_fsr, tcg_env, cpu_fsr, cpu_dst_32);
- break;
- default:
- goto illegal_insn;
- }
- } else if (xop > 0x23 && xop < 0x28) {
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- switch (xop) {
- case 0x24: /* stf, store fpreg */
- case 0x26: /* v9 stqf, v8 stdfq */
- case 0x27: /* stdf, store double fpreg */
- g_assert_not_reached();
- case 0x25: /* stfsr, V9 stxfsr */
- {
-#ifdef TARGET_SPARC64
- gen_address_mask(dc, cpu_addr);
- if (rd == 1) {
- tcg_gen_qemu_st_tl(cpu_fsr, cpu_addr,
- dc->mem_idx, MO_TEUQ | MO_ALIGN);
- break;
- }
-#endif
- tcg_gen_qemu_st_tl(cpu_fsr, cpu_addr,
- dc->mem_idx, MO_TEUL | MO_ALIGN);
- }
- break;
- default:
- goto illegal_insn;
- }
- } else if (xop > 0x33 && xop < 0x3f) {
- goto illegal_insn; /* in decodetree */
- } else {
- goto illegal_insn;
- }
- }
- break;
+ goto illegal_insn; /* in decodetree */
}
advance_pc(dc);
jmp_insn:
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 58/90] target/sparc: Merge LDFSR, LDXFSR implementations
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (56 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 57/90] target/sparc: Move LDFSR, STFSR " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 59/90] target/sparc: Move EDGE* to decodetree Richard Henderson
` (32 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Combine the helper to a single set_fsr().
Perform the mask and merge inline.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 3 +--
target/sparc/fop_helper.c | 17 ++--------------
target/sparc/translate.c | 42 ++++++++++++---------------------------
3 files changed, 16 insertions(+), 46 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index b116ddcb29..790752467f 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -42,7 +42,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_3(ldfsr, TCG_CALL_NO_RWG, tl, env, tl, i32)
+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)
@@ -54,7 +54,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_3(ldxfsr, TCG_CALL_NO_RWG, tl, env, tl, i64)
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)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index f54fa9b959..0f8aa3abcd 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -382,20 +382,7 @@ static void set_fsr(CPUSPARCState *env, target_ulong fsr)
set_float_rounding_mode(rnd_mode, &env->fp_status);
}
-target_ulong helper_ldfsr(CPUSPARCState *env, target_ulong old_fsr,
- uint32_t new_fsr)
+void helper_set_fsr(CPUSPARCState *env, target_ulong fsr)
{
- old_fsr = (new_fsr & FSR_LDFSR_MASK) | (old_fsr & FSR_LDFSR_OLDMASK);
- set_fsr(env, old_fsr);
- return old_fsr;
+ set_fsr(env, fsr);
}
-
-#ifdef TARGET_SPARC64
-target_ulong helper_ldxfsr(CPUSPARCState *env, target_ulong old_fsr,
- uint64_t new_fsr)
-{
- old_fsr = (new_fsr & FSR_LDXFSR_MASK) | (old_fsr & FSR_LDXFSR_OLDMASK);
- set_fsr(env, old_fsr);
- return old_fsr;
-}
-#endif
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index b23f77a199..5ee5d30b2a 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -58,7 +58,8 @@
#define gen_helper_retry(E) qemu_build_not_reached()
#define gen_helper_udivx(D, E, A, B) qemu_build_not_reached()
#define gen_helper_sdivx(D, E, A, B) qemu_build_not_reached()
-#define gen_helper_ldxfsr(R, E, X, Y) qemu_build_not_reached()
+#define FSR_LDXFSR_MASK ({ qemu_build_not_reached(); 0; })
+#define FSR_LDXFSR_OLDMASK ({ qemu_build_not_reached(); 0; })
# ifdef CONFIG_USER_ONLY
static void gen_helper_ld_asi(TCGv_i64 r, TCGv_env e, TCGv a,
TCGv_i32 asi, TCGv_i32 mop)
@@ -4763,44 +4764,27 @@ static bool trans_STDFQ(DisasContext *dc, arg_STDFQ *a)
return true;
}
-static bool trans_LDFSR(DisasContext *dc, arg_r_r_ri *a)
+static bool do_ldfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop,
+ target_ulong new_mask, target_ulong old_mask)
{
- TCGv addr;
- TCGv_i32 tmp;
-
- addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
+ TCGv tmp, addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
if (addr == NULL) {
return false;
}
if (gen_trap_ifnofpu(dc)) {
return true;
}
- tmp = tcg_temp_new_i32();
- tcg_gen_qemu_ld_i32(tmp, addr, dc->mem_idx, MO_TEUL | MO_ALIGN);
- gen_helper_ldfsr(cpu_fsr, tcg_env, cpu_fsr, tmp);
+ 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);
return advance_pc(dc);
}
-static bool trans_LDXFSR(DisasContext *dc, arg_r_r_ri *a)
-{
- TCGv addr;
- TCGv_i64 tmp;
-
- if (!avail_64(dc)) {
- return false;
- }
- addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
- if (addr == NULL) {
- return false;
- }
- if (gen_trap_ifnofpu(dc)) {
- return true;
- }
- tmp = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(tmp, addr, dc->mem_idx, MO_TEUQ | MO_ALIGN);
- gen_helper_ldxfsr(cpu_fsr, tcg_env, cpu_fsr, 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 do_stfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 59/90] target/sparc: Move EDGE* to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (57 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 58/90] target/sparc: Merge LDFSR, LDXFSR implementations Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 60/90] target/sparc: Move ARRAY* " Richard Henderson
` (31 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 22 ++-
target/sparc/translate.c | 272 ++++++++++++++++----------------------
2 files changed, 134 insertions(+), 160 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 42eb807e21..fb104e77d1 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -30,6 +30,9 @@ CALL 01 i:s30
@n_r_ri .. ..... ...... rs1:5 imm:1 rs2_or_imm:s13 &r_r_ri rd=0
@r_r_ri .. rd:5 ...... rs1:5 imm:1 rs2_or_imm:s13 &r_r_ri
+&r_r_r rd rs1 rs2
+@r_r_r .. rd:5 ...... rs1:5 . ........ rs2:5 &r_r_r
+
{
[
STBAR 10 00000 101000 01111 0 0000000000000
@@ -224,7 +227,24 @@ RESTORE 10 ..... 111101 ..... . ............. @r_r_ri
DONE 10 00000 111110 00000 0 0000000000000
RETRY 10 00001 111110 00000 0 0000000000000
-NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
+{
+ [
+ EDGE8cc 10 ..... 110110 ..... 0 0000 0000 ..... @r_r_r
+ EDGE8N 10 ..... 110110 ..... 0 0000 0001 ..... @r_r_r
+ EDGE8Lcc 10 ..... 110110 ..... 0 0000 0010 ..... @r_r_r
+ EDGE8LN 10 ..... 110110 ..... 0 0000 0011 ..... @r_r_r
+ EDGE16cc 10 ..... 110110 ..... 0 0000 0100 ..... @r_r_r
+ EDGE16N 10 ..... 110110 ..... 0 0000 0101 ..... @r_r_r
+ EDGE16Lcc 10 ..... 110110 ..... 0 0000 0110 ..... @r_r_r
+ EDGE16LN 10 ..... 110110 ..... 0 0000 0111 ..... @r_r_r
+ EDGE32cc 10 ..... 110110 ..... 0 0000 1000 ..... @r_r_r
+ EDGE32N 10 ..... 110110 ..... 0 0000 1001 ..... @r_r_r
+ EDGE32Lcc 10 ..... 110110 ..... 0 0000 1010 ..... @r_r_r
+ EDGE32LN 10 ..... 110110 ..... 0 0000 1011 ..... @r_r_r
+ ]
+ NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
+}
+
NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2
##
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 5ee5d30b2a..5145692885 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2669,93 +2669,6 @@ static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr)
}
}
-static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2,
- int width, bool cc, bool left)
-{
- TCGv lo1, lo2;
- uint64_t amask, tabl, tabr;
- int shift, imask, omask;
-
- if (cc) {
- tcg_gen_mov_tl(cpu_cc_src, s1);
- tcg_gen_mov_tl(cpu_cc_src2, s2);
- tcg_gen_sub_tl(cpu_cc_dst, s1, s2);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
- dc->cc_op = CC_OP_SUB;
- }
-
- /* Theory of operation: there are two tables, left and right (not to
- be confused with the left and right versions of the opcode). These
- are indexed by the low 3 bits of the inputs. To make things "easy",
- these tables are loaded into two constants, TABL and TABR below.
- The operation index = (input & imask) << shift calculates the index
- into the constant, while val = (table >> index) & omask calculates
- the value we're looking for. */
- switch (width) {
- case 8:
- imask = 0x7;
- shift = 3;
- omask = 0xff;
- if (left) {
- tabl = 0x80c0e0f0f8fcfeffULL;
- tabr = 0xff7f3f1f0f070301ULL;
- } else {
- tabl = 0x0103070f1f3f7fffULL;
- tabr = 0xfffefcf8f0e0c080ULL;
- }
- break;
- case 16:
- imask = 0x6;
- shift = 1;
- omask = 0xf;
- if (left) {
- tabl = 0x8cef;
- tabr = 0xf731;
- } else {
- tabl = 0x137f;
- tabr = 0xfec8;
- }
- break;
- case 32:
- imask = 0x4;
- shift = 0;
- omask = 0x3;
- if (left) {
- tabl = (2 << 2) | 3;
- tabr = (3 << 2) | 1;
- } else {
- tabl = (1 << 2) | 3;
- tabr = (3 << 2) | 2;
- }
- break;
- default:
- abort();
- }
-
- lo1 = tcg_temp_new();
- lo2 = tcg_temp_new();
- tcg_gen_andi_tl(lo1, s1, imask);
- tcg_gen_andi_tl(lo2, s2, imask);
- tcg_gen_shli_tl(lo1, lo1, shift);
- tcg_gen_shli_tl(lo2, lo2, shift);
-
- tcg_gen_shr_tl(lo1, tcg_constant_tl(tabl), lo1);
- tcg_gen_shr_tl(lo2, tcg_constant_tl(tabr), lo2);
- tcg_gen_andi_tl(lo1, lo1, omask);
- tcg_gen_andi_tl(lo2, lo2, omask);
-
- amask = -8;
- if (AM_CHECK(dc)) {
- amask &= 0xffffffffULL;
- }
- tcg_gen_andi_tl(s1, s1, amask);
- tcg_gen_andi_tl(s2, s2, amask);
-
- /* Compute dst = (s1 == s2 ? lo1 : lo1 & lo2). */
- tcg_gen_and_tl(lo2, lo2, lo1);
- tcg_gen_movcond_tl(TCG_COND_EQ, dst, s1, s2, lo1, lo2);
-}
-
static void gen_alignaddr(TCGv dst, TCGv s1, TCGv s2, bool left)
{
TCGv tmp = tcg_temp_new();
@@ -2822,6 +2735,8 @@ static int extract_qfpreg(DisasContext *dc, int x)
#define avail_HYPV(C) ((C)->def->features & CPU_FEATURE_HYPV)
#define avail_MUL(C) ((C)->def->features & CPU_FEATURE_MUL)
#define avail_POWERDOWN(C) ((C)->def->features & CPU_FEATURE_POWERDOWN)
+#define avail_VIS1(C) ((C)->def->features & CPU_FEATURE_VIS1)
+#define avail_VIS2(C) ((C)->def->features & CPU_FEATURE_VIS2)
/* Default case for non jump instructions. */
static bool advance_pc(DisasContext *dc)
@@ -4277,6 +4192,116 @@ static bool trans_MULScc(DisasContext *dc, arg_r_r_ri *a)
return do_cc_arith(dc, a, CC_OP_ADD, gen_op_mulscc, NULL);
}
+static bool gen_edge(DisasContext *dc, arg_r_r_r *a,
+ int width, bool cc, bool left)
+{
+ TCGv dst, s1, s2, lo1, lo2;
+ uint64_t amask, tabl, tabr;
+ int shift, imask, omask;
+
+ dst = gen_dest_gpr(dc, a->rd);
+ s1 = gen_load_gpr(dc, a->rs1);
+ s2 = gen_load_gpr(dc, a->rs2);
+
+ if (cc) {
+ tcg_gen_mov_tl(cpu_cc_src, s1);
+ tcg_gen_mov_tl(cpu_cc_src2, s2);
+ tcg_gen_sub_tl(cpu_cc_dst, s1, s2);
+ tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
+ dc->cc_op = CC_OP_SUB;
+ }
+
+ /*
+ * Theory of operation: there are two tables, left and right (not to
+ * be confused with the left and right versions of the opcode). These
+ * are indexed by the low 3 bits of the inputs. To make things "easy",
+ * these tables are loaded into two constants, TABL and TABR below.
+ * The operation index = (input & imask) << shift calculates the index
+ * into the constant, while val = (table >> index) & omask calculates
+ * the value we're looking for.
+ */
+ switch (width) {
+ case 8:
+ imask = 0x7;
+ shift = 3;
+ omask = 0xff;
+ if (left) {
+ tabl = 0x80c0e0f0f8fcfeffULL;
+ tabr = 0xff7f3f1f0f070301ULL;
+ } else {
+ tabl = 0x0103070f1f3f7fffULL;
+ tabr = 0xfffefcf8f0e0c080ULL;
+ }
+ break;
+ case 16:
+ imask = 0x6;
+ shift = 1;
+ omask = 0xf;
+ if (left) {
+ tabl = 0x8cef;
+ tabr = 0xf731;
+ } else {
+ tabl = 0x137f;
+ tabr = 0xfec8;
+ }
+ break;
+ case 32:
+ imask = 0x4;
+ shift = 0;
+ omask = 0x3;
+ if (left) {
+ tabl = (2 << 2) | 3;
+ tabr = (3 << 2) | 1;
+ } else {
+ tabl = (1 << 2) | 3;
+ tabr = (3 << 2) | 2;
+ }
+ break;
+ default:
+ abort();
+ }
+
+ lo1 = tcg_temp_new();
+ lo2 = tcg_temp_new();
+ tcg_gen_andi_tl(lo1, s1, imask);
+ tcg_gen_andi_tl(lo2, s2, imask);
+ tcg_gen_shli_tl(lo1, lo1, shift);
+ tcg_gen_shli_tl(lo2, lo2, shift);
+
+ tcg_gen_shr_tl(lo1, tcg_constant_tl(tabl), lo1);
+ tcg_gen_shr_tl(lo2, tcg_constant_tl(tabr), lo2);
+ tcg_gen_andi_tl(lo1, lo1, omask);
+ tcg_gen_andi_tl(lo2, lo2, omask);
+
+ amask = -8;
+ if (AM_CHECK(dc)) {
+ amask &= 0xffffffffULL;
+ }
+ tcg_gen_andi_tl(s1, s1, amask);
+ tcg_gen_andi_tl(s2, s2, amask);
+
+ /* Compute dst = (s1 == s2 ? lo1 : lo1 & lo2). */
+ tcg_gen_and_tl(lo2, lo2, lo1);
+ tcg_gen_movcond_tl(TCG_COND_EQ, dst, s1, s2, lo1, lo2);
+
+ gen_store_gpr(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(EDGE8cc, VIS1, gen_edge, a, 8, 1, 0)
+TRANS(EDGE8Lcc, VIS1, gen_edge, a, 8, 1, 1)
+TRANS(EDGE16cc, VIS1, gen_edge, a, 16, 1, 0)
+TRANS(EDGE16Lcc, VIS1, gen_edge, a, 16, 1, 1)
+TRANS(EDGE32cc, VIS1, gen_edge, a, 32, 1, 0)
+TRANS(EDGE32Lcc, VIS1, gen_edge, a, 32, 1, 1)
+
+TRANS(EDGE8N, VIS2, gen_edge, a, 8, 0, 0)
+TRANS(EDGE8LN, VIS2, gen_edge, a, 8, 0, 1)
+TRANS(EDGE16N, VIS2, gen_edge, a, 16, 0, 0)
+TRANS(EDGE16LN, VIS2, gen_edge, a, 16, 0, 1)
+TRANS(EDGE32N, VIS2, gen_edge, a, 32, 0, 0)
+TRANS(EDGE32LN, VIS2, gen_edge, a, 32, 0, 1)
+
static bool do_shift_r(DisasContext *dc, arg_shiftr *a, bool l, bool u)
{
TCGv dst, src1, src2;
@@ -5163,89 +5188,18 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
switch (opf) {
case 0x000: /* VIS I edge8cc */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 0);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x001: /* VIS II edge8n */
- CHECK_FPU_FEATURE(dc, VIS2);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 0);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x002: /* VIS I edge8lcc */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 1);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x003: /* VIS II edge8ln */
- CHECK_FPU_FEATURE(dc, VIS2);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 1);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x004: /* VIS I edge16cc */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 0);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x005: /* VIS II edge16n */
- CHECK_FPU_FEATURE(dc, VIS2);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 0);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x006: /* VIS I edge16lcc */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 1);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x007: /* VIS II edge16ln */
- CHECK_FPU_FEATURE(dc, VIS2);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 1);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x008: /* VIS I edge32cc */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 0);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x009: /* VIS II edge32n */
- CHECK_FPU_FEATURE(dc, VIS2);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 0);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x00a: /* VIS I edge32lcc */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 1);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x00b: /* VIS II edge32ln */
- CHECK_FPU_FEATURE(dc, VIS2);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 1);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x010: /* VIS I array8 */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_src1 = gen_load_gpr(dc, rs1);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 60/90] target/sparc: Move ARRAY* to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (58 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 59/90] target/sparc: Move EDGE* to decodetree Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 61/90] target/sparc: Move ADDRALIGN* " Richard Henderson
` (30 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 +++
target/sparc/translate.c | 54 ++++++++++++++++++++++++---------------
2 files changed, 37 insertions(+), 21 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index fb104e77d1..07a84b109c 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -241,6 +241,10 @@ RETRY 10 00001 111110 00000 0 0000000000000
EDGE32N 10 ..... 110110 ..... 0 0000 1001 ..... @r_r_r
EDGE32Lcc 10 ..... 110110 ..... 0 0000 1010 ..... @r_r_r
EDGE32LN 10 ..... 110110 ..... 0 0000 1011 ..... @r_r_r
+
+ ARRAY8 10 ..... 110110 ..... 0 0001 0000 ..... @r_r_r
+ ARRAY16 10 ..... 110110 ..... 0 0001 0010 ..... @r_r_r
+ ARRAY32 10 ..... 110110 ..... 0 0001 0100 ..... @r_r_r
]
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 5145692885..87f3ab27b1 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -72,6 +72,10 @@ static void gen_helper_st_asi(TCGv_env e, TCGv a, TCGv_i64 r,
g_assert_not_reached();
}
# endif
+static void gen_helper_array8(TCGv r, TCGv a, TCGv b)
+{
+ g_assert_not_reached();
+}
#endif
/* Dynamic PC, must exit to main loop. */
@@ -679,6 +683,18 @@ static void gen_op_popc(TCGv dst, TCGv src1, TCGv src2)
tcg_gen_ctpop_tl(dst, src2);
}
+static void gen_op_array16(TCGv dst, TCGv src1, TCGv src2)
+{
+ gen_helper_array8(dst, src1, src2);
+ tcg_gen_shli_tl(dst, dst, 1);
+}
+
+static void gen_op_array32(TCGv dst, TCGv src1, TCGv src2)
+{
+ gen_helper_array8(dst, src1, src2);
+ tcg_gen_shli_tl(dst, dst, 2);
+}
+
// 1
static void gen_op_eval_ba(TCGv dst)
{
@@ -4302,6 +4318,22 @@ TRANS(EDGE16LN, VIS2, gen_edge, a, 16, 0, 1)
TRANS(EDGE32N, VIS2, gen_edge, a, 32, 0, 0)
TRANS(EDGE32LN, VIS2, gen_edge, a, 32, 0, 1)
+static bool do_rrr(DisasContext *dc, arg_r_r_r *a,
+ void (*func)(TCGv, TCGv, TCGv))
+{
+ TCGv dst = gen_dest_gpr(dc, a->rd);
+ TCGv src1 = gen_load_gpr(dc, a->rs1);
+ TCGv src2 = gen_load_gpr(dc, a->rs2);
+
+ func(dst, src1, src2);
+ gen_store_gpr(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(ARRAY8, VIS1, do_rrr, a, gen_helper_array8)
+TRANS(ARRAY16, VIS1, do_rrr, a, gen_op_array16)
+TRANS(ARRAY32, VIS1, do_rrr, a, gen_op_array32)
+
static bool do_shift_r(DisasContext *dc, arg_shiftr *a, bool l, bool u)
{
TCGv dst, src1, src2;
@@ -5199,30 +5231,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x009: /* VIS II edge32n */
case 0x00a: /* VIS I edge32lcc */
case 0x00b: /* VIS II edge32ln */
- g_assert_not_reached(); /* in decodetree */
case 0x010: /* VIS I array8 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x012: /* VIS I array16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
- tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x014: /* VIS I array32 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
- tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x018: /* VIS I alignaddr */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_src1 = gen_load_gpr(dc, rs1);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 61/90] target/sparc: Move ADDRALIGN* to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (59 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 60/90] target/sparc: Move ARRAY* " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 62/90] target/sparc: Move BMASK " Richard Henderson
` (29 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 3 +++
target/sparc/translate.c | 56 ++++++++++++++++++++++-----------------
2 files changed, 34 insertions(+), 25 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 07a84b109c..8bd57f620a 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -245,6 +245,9 @@ RETRY 10 00001 111110 00000 0 0000000000000
ARRAY8 10 ..... 110110 ..... 0 0001 0000 ..... @r_r_r
ARRAY16 10 ..... 110110 ..... 0 0001 0010 ..... @r_r_r
ARRAY32 10 ..... 110110 ..... 0 0001 0100 ..... @r_r_r
+
+ ALIGNADDR 10 ..... 110110 ..... 0 0001 1000 ..... @r_r_r
+ ALIGNADDRL 10 ..... 110110 ..... 0 0001 1010 ..... @r_r_r
]
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 87f3ab27b1..dab3e83c27 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2685,18 +2685,6 @@ static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr)
}
}
-static void gen_alignaddr(TCGv dst, TCGv s1, TCGv s2, bool left)
-{
- TCGv tmp = tcg_temp_new();
-
- tcg_gen_add_tl(tmp, s1, s2);
- tcg_gen_andi_tl(dst, tmp, -8);
- if (left) {
- tcg_gen_neg_tl(tmp, tmp);
- }
- tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, tmp, 0, 3);
-}
-
static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
{
TCGv t1, t2, shift;
@@ -4334,6 +4322,36 @@ TRANS(ARRAY8, VIS1, do_rrr, a, gen_helper_array8)
TRANS(ARRAY16, VIS1, do_rrr, a, gen_op_array16)
TRANS(ARRAY32, VIS1, do_rrr, a, gen_op_array32)
+static void gen_op_alignaddr(TCGv dst, TCGv s1, TCGv s2)
+{
+#ifdef TARGET_SPARC64
+ TCGv tmp = tcg_temp_new();
+
+ tcg_gen_add_tl(tmp, s1, s2);
+ tcg_gen_andi_tl(dst, tmp, -8);
+ tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, tmp, 0, 3);
+#else
+ g_assert_not_reached();
+#endif
+}
+
+static void gen_op_alignaddrl(TCGv dst, TCGv s1, TCGv s2)
+{
+#ifdef TARGET_SPARC64
+ TCGv tmp = tcg_temp_new();
+
+ tcg_gen_add_tl(tmp, s1, s2);
+ tcg_gen_andi_tl(dst, tmp, -8);
+ tcg_gen_neg_tl(tmp, tmp);
+ tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, tmp, 0, 3);
+#else
+ g_assert_not_reached();
+#endif
+}
+
+TRANS(ALIGNADDR, VIS1, do_rrr, a, gen_op_alignaddr)
+TRANS(ALIGNADDRL, VIS1, do_rrr, a, gen_op_alignaddrl)
+
static bool do_shift_r(DisasContext *dc, arg_shiftr *a, bool l, bool u)
{
TCGv dst, src1, src2;
@@ -5234,21 +5252,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x010: /* VIS I array8 */
case 0x012: /* VIS I array16 */
case 0x014: /* VIS I array32 */
- g_assert_not_reached(); /* in decodetree */
case 0x018: /* VIS I alignaddr */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_alignaddr(cpu_dst, cpu_src1, cpu_src2, 0);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x01a: /* VIS I alignaddrl */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- gen_alignaddr(cpu_dst, cpu_src1, cpu_src2, 1);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x019: /* VIS II bmask */
CHECK_FPU_FEATURE(dc, VIS2);
cpu_src1 = gen_load_gpr(dc, rs1);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 62/90] target/sparc: Move BMASK to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (60 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 61/90] target/sparc: Move ADDRALIGN* " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 63/90] target/sparc: Move FMOVS, FNEGS, FABSS, FSRC*S, FNOT*S " Richard Henderson
` (28 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 22 +++++++++++++---------
2 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 8bd57f620a..6f136e0602 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -248,6 +248,8 @@ RETRY 10 00001 111110 00000 0 0000000000000
ALIGNADDR 10 ..... 110110 ..... 0 0001 1000 ..... @r_r_r
ALIGNADDRL 10 ..... 110110 ..... 0 0001 1010 ..... @r_r_r
+
+ BMASK 10 ..... 110110 ..... 0 0001 1001 ..... @r_r_r
]
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index dab3e83c27..64f1999cba 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4352,6 +4352,18 @@ static void gen_op_alignaddrl(TCGv dst, TCGv s1, TCGv s2)
TRANS(ALIGNADDR, VIS1, do_rrr, a, gen_op_alignaddr)
TRANS(ALIGNADDRL, VIS1, do_rrr, a, gen_op_alignaddrl)
+static void gen_op_bmask(TCGv dst, TCGv s1, TCGv s2)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_add_tl(dst, s1, s2);
+ tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, dst, 32, 32);
+#else
+ g_assert_not_reached();
+#endif
+}
+
+TRANS(BMASK, VIS2, do_rrr, a, gen_op_bmask)
+
static bool do_shift_r(DisasContext *dc, arg_shiftr *a, bool l, bool u)
{
TCGv dst, src1, src2;
@@ -4889,7 +4901,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
{
unsigned int opc, rs1, rs2, rd;
TCGv cpu_src1 __attribute__((unused));
- TCGv cpu_src2 __attribute__((unused));
TCGv_i32 cpu_src1_32, cpu_src2_32;
TCGv_i64 cpu_src1_64, cpu_src2_64;
TCGv_i32 cpu_dst_32 __attribute__((unused));
@@ -5254,15 +5265,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x014: /* VIS I array32 */
case 0x018: /* VIS I alignaddr */
case 0x01a: /* VIS I alignaddrl */
- g_assert_not_reached(); /* in decodetree */
case 0x019: /* VIS II bmask */
- CHECK_FPU_FEATURE(dc, VIS2);
- cpu_src1 = gen_load_gpr(dc, rs1);
- cpu_src2 = gen_load_gpr(dc, rs2);
- tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
- tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, cpu_dst, 32, 32);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x020: /* VIS I fcmple16 */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_src1_64 = gen_load_fpr_D(dc, rs1);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 63/90] target/sparc: Move FMOVS, FNEGS, FABSS, FSRC*S, FNOT*S to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (61 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 62/90] target/sparc: Move BMASK " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 64/90] target/sparc: Move FMOVD, FNEGD, FABSD, FSRC*D, FNOT*D " Richard Henderson
` (27 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 13 ++++++
target/sparc/translate.c | 92 +++++++++++++++++++++------------------
2 files changed, 62 insertions(+), 43 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 6f136e0602..d591efb0f9 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -33,6 +33,10 @@ CALL 01 i:s30
&r_r_r rd rs1 rs2
@r_r_r .. rd:5 ...... rs1:5 . ........ rs2:5 &r_r_r
+&r_r rd rs
+@r_r1 .. rd:5 ...... rs:5 . ........ ..... &r_r
+@r_r2 .. rd:5 ...... ..... . ........ rs:5 &r_r
+
{
[
STBAR 10 00000 101000 01111 0 0000000000000
@@ -227,6 +231,10 @@ RESTORE 10 ..... 111101 ..... . ............. @r_r_ri
DONE 10 00000 111110 00000 0 0000000000000
RETRY 10 00001 111110 00000 0 0000000000000
+FMOVs 10 ..... 110100 00000 0 0000 0001 ..... @r_r2
+FNEGs 10 ..... 110100 00000 0 0000 0101 ..... @r_r2
+FABSs 10 ..... 110100 00000 0 0000 1001 ..... @r_r2
+
{
[
EDGE8cc 10 ..... 110110 ..... 0 0000 0000 ..... @r_r_r
@@ -250,6 +258,11 @@ RETRY 10 00001 111110 00000 0 0000000000000
ALIGNADDRL 10 ..... 110110 ..... 0 0001 1010 ..... @r_r_r
BMASK 10 ..... 110110 ..... 0 0001 1001 ..... @r_r_r
+
+ FSRCs 10 ..... 110110 ..... 0 0111 0101 00000 @r_r1 # FSRC1s
+ FSRCs 10 ..... 110110 00000 0 0111 1001 ..... @r_r2 # FSRC2s
+ FNOTs 10 ..... 110110 ..... 0 0110 1011 00000 @r_r1 # FNOT1s
+ FNOTs 10 ..... 110110 00000 0 0110 0111 ..... @r_r2 # FNOT2s
]
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 64f1999cba..3b0ce1adcc 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1351,6 +1351,29 @@ static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
cmp->c2 = tcg_constant_tl(0);
}
+static void gen_op_clear_ieee_excp_and_FTT(void)
+{
+ tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
+}
+
+static void gen_op_fmovs(TCGv_i32 dst, TCGv_i32 src)
+{
+ gen_op_clear_ieee_excp_and_FTT();
+ tcg_gen_mov_i32(dst, src);
+}
+
+static void gen_op_fnegs(TCGv_i32 dst, TCGv_i32 src)
+{
+ gen_op_clear_ieee_excp_and_FTT();
+ gen_helper_fnegs(dst, src);
+}
+
+static void gen_op_fabss(TCGv_i32 dst, TCGv_i32 src)
+{
+ gen_op_clear_ieee_excp_and_FTT();
+ gen_helper_fabss(dst, src);
+}
+
#ifdef TARGET_SPARC64
static void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
{
@@ -1511,11 +1534,6 @@ static int gen_trap_ifnofpu(DisasContext *dc)
return 0;
}
-static void gen_op_clear_ieee_excp_and_FTT(void)
-{
- tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
-}
-
static void gen_fop_FF(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32))
{
@@ -1530,19 +1548,6 @@ static void gen_fop_FF(DisasContext *dc, int rd, int rs,
gen_store_fpr_F(dc, rd, dst);
}
-static void gen_ne_fop_FF(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_i32, TCGv_i32))
-{
- TCGv_i32 dst, src;
-
- src = gen_load_fpr_F(dc, rs);
- dst = gen_dest_fpr_F(dc);
-
- gen(dst, src);
-
- gen_store_fpr_F(dc, rd, dst);
-}
-
static void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32))
{
@@ -4889,6 +4894,27 @@ static bool do_stfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop)
TRANS(STFSR, ALL, do_stfsr, a, MO_TEUL)
TRANS(STXFSR, 64, do_stfsr, a, MO_TEUQ)
+static bool do_ff(DisasContext *dc, arg_r_r *a,
+ void (*func)(TCGv_i32, TCGv_i32))
+{
+ TCGv_i32 tmp;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ tmp = gen_load_fpr_F(dc, a->rs);
+ func(tmp, tmp);
+ gen_store_fpr_F(dc, a->rd, tmp);
+ return advance_pc(dc);
+}
+
+TRANS(FMOVs, ALL, do_ff, a, gen_op_fmovs)
+TRANS(FNEGs, ALL, do_ff, a, gen_op_fnegs)
+TRANS(FABSs, ALL, do_ff, a, gen_op_fabss)
+TRANS(FSRCs, VIS1, do_ff, a, tcg_gen_mov_i32)
+TRANS(FNOTs, VIS1, do_ff, a, tcg_gen_not_i32)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4930,15 +4956,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
switch (xop) {
case 0x1: /* fmovs */
- cpu_src1_32 = gen_load_fpr_F(dc, rs2);
- gen_store_fpr_F(dc, rd, cpu_src1_32);
- break;
case 0x5: /* fnegs */
- gen_ne_fop_FF(dc, rd, rs2, gen_helper_fnegs);
- break;
case 0x9: /* fabss */
- gen_ne_fop_FF(dc, rd, rs2, gen_helper_fabss);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x29: /* fsqrts */
gen_fop_FF(dc, rd, rs2, gen_helper_fsqrts);
break;
@@ -5266,6 +5286,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x018: /* VIS I alignaddr */
case 0x01a: /* VIS I alignaddrl */
case 0x019: /* VIS II bmask */
+ case 0x067: /* VIS I fnot2s */
+ case 0x06b: /* VIS I fnot1s */
+ case 0x075: /* VIS I fsrc1s */
+ case 0x079: /* VIS I fsrc2s */
g_assert_not_reached(); /* in decodetree */
case 0x020: /* VIS I fcmple16 */
CHECK_FPU_FEATURE(dc, VIS1);
@@ -5453,10 +5477,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DD(dc, rd, rs2, tcg_gen_not_i64);
break;
- case 0x067: /* VIS I fnot2s */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FF(dc, rd, rs2, tcg_gen_not_i32);
- break;
case 0x068: /* VIS I fandnot1 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_andc_i64);
@@ -5469,10 +5489,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DD(dc, rd, rs1, tcg_gen_not_i64);
break;
- case 0x06b: /* VIS I fnot1s */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FF(dc, rd, rs1, tcg_gen_not_i32);
- break;
case 0x06c: /* VIS I fxor */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_xor_i64);
@@ -5510,11 +5526,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src1_64 = gen_load_fpr_D(dc, rs1);
gen_store_fpr_D(dc, rd, cpu_src1_64);
break;
- case 0x075: /* VIS I fsrc1s */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_32 = gen_load_fpr_F(dc, rs1);
- gen_store_fpr_F(dc, rd, cpu_src1_32);
- break;
case 0x076: /* VIS I fornot2 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_orc_i64);
@@ -5528,11 +5539,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
cpu_src1_64 = gen_load_fpr_D(dc, rs2);
gen_store_fpr_D(dc, rd, cpu_src1_64);
break;
- case 0x079: /* VIS I fsrc2s */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_32 = gen_load_fpr_F(dc, rs2);
- gen_store_fpr_F(dc, rd, cpu_src1_32);
- break;
case 0x07a: /* VIS I fornot1 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_orc_i64);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 64/90] target/sparc: Move FMOVD, FNEGD, FABSD, FSRC*D, FNOT*D to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (62 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 63/90] target/sparc: Move FMOVS, FNEGS, FABSS, FSRC*S, FNOT*S " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 65/90] target/sparc: Use tcg_gen_vec_{add,sub}* Richard Henderson
` (26 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 7 +++
target/sparc/translate.c | 91 +++++++++++++++++++++------------------
2 files changed, 56 insertions(+), 42 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index d591efb0f9..91988e2978 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -232,8 +232,11 @@ DONE 10 00000 111110 00000 0 0000000000000
RETRY 10 00001 111110 00000 0 0000000000000
FMOVs 10 ..... 110100 00000 0 0000 0001 ..... @r_r2
+FMOVd 10 ..... 110100 00000 0 0000 0010 ..... @r_r2
FNEGs 10 ..... 110100 00000 0 0000 0101 ..... @r_r2
+FNEGd 10 ..... 110100 00000 0 0000 0110 ..... @r_r2
FABSs 10 ..... 110100 00000 0 0000 1001 ..... @r_r2
+FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
{
[
@@ -259,9 +262,13 @@ FABSs 10 ..... 110100 00000 0 0000 1001 ..... @r_r2
BMASK 10 ..... 110110 ..... 0 0001 1001 ..... @r_r_r
+ FSRCd 10 ..... 110110 ..... 0 0111 0100 00000 @r_r1 # FSRC1d
FSRCs 10 ..... 110110 ..... 0 0111 0101 00000 @r_r1 # FSRC1s
+ FSRCd 10 ..... 110110 00000 0 0111 1000 ..... @r_r2 # FSRC2d
FSRCs 10 ..... 110110 00000 0 0111 1001 ..... @r_r2 # FSRC2s
+ FNOTd 10 ..... 110110 ..... 0 0110 1010 00000 @r_r1 # FNOT1d
FNOTs 10 ..... 110110 ..... 0 0110 1011 00000 @r_r1 # FNOT1s
+ FNOTd 10 ..... 110110 00000 0 0110 0110 ..... @r_r2 # FNOT2d
FNOTs 10 ..... 110110 00000 0 0110 0111 ..... @r_r2 # FNOT2s
]
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 3b0ce1adcc..c92b080b8f 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -54,6 +54,8 @@
#define gen_helper_write_softint(E, S) qemu_build_not_reached()
#define gen_helper_saved ({ qemu_build_not_reached(); NULL; })
#define gen_helper_restored ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_fnegd(D, S) qemu_build_not_reached()
+#define gen_helper_fabsd(D, S) qemu_build_not_reached()
#define gen_helper_done(E) qemu_build_not_reached()
#define gen_helper_retry(E) qemu_build_not_reached()
#define gen_helper_udivx(D, E, A, B) qemu_build_not_reached()
@@ -1374,6 +1376,24 @@ static void gen_op_fabss(TCGv_i32 dst, TCGv_i32 src)
gen_helper_fabss(dst, src);
}
+static void gen_op_fmovd(TCGv_i64 dst, TCGv_i64 src)
+{
+ gen_op_clear_ieee_excp_and_FTT();
+ tcg_gen_mov_i64(dst, src);
+}
+
+static void gen_op_fnegd(TCGv_i64 dst, TCGv_i64 src)
+{
+ gen_op_clear_ieee_excp_and_FTT();
+ gen_helper_fnegd(dst, src);
+}
+
+static void gen_op_fabsd(TCGv_i64 dst, TCGv_i64 src)
+{
+ gen_op_clear_ieee_excp_and_FTT();
+ gen_helper_fabsd(dst, src);
+}
+
#ifdef TARGET_SPARC64
static void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
{
@@ -1593,21 +1613,6 @@ static void gen_fop_DD(DisasContext *dc, int rd, int rs,
gen_store_fpr_D(dc, rd, dst);
}
-#ifdef TARGET_SPARC64
-static void gen_ne_fop_DD(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_i64, TCGv_i64))
-{
- TCGv_i64 dst, src;
-
- src = gen_load_fpr_D(dc, rs);
- dst = gen_dest_fpr_D(dc, rd);
-
- gen(dst, src);
-
- gen_store_fpr_D(dc, rd, dst);
-}
-#endif
-
static void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64))
{
@@ -4915,6 +4920,28 @@ TRANS(FABSs, ALL, do_ff, a, gen_op_fabss)
TRANS(FSRCs, VIS1, do_ff, a, tcg_gen_mov_i32)
TRANS(FNOTs, VIS1, do_ff, a, tcg_gen_not_i32)
+static bool do_dd(DisasContext *dc, arg_r_r *a,
+ void (*func)(TCGv_i64, TCGv_i64))
+{
+ TCGv_i64 dst, src;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ dst = gen_dest_fpr_D(dc, a->rd);
+ src = gen_load_fpr_D(dc, a->rs);
+ func(dst, src);
+ gen_store_fpr_D(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(FMOVd, 64, do_dd, a, gen_op_fmovd)
+TRANS(FNEGd, 64, do_dd, a, gen_op_fnegd)
+TRANS(FABSd, 64, do_dd, a, gen_op_fabsd)
+TRANS(FSRCd, VIS1, do_dd, a, tcg_gen_mov_i64)
+TRANS(FNOTd, VIS1, do_dd, a, tcg_gen_not_i64)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4958,6 +4985,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x1: /* fmovs */
case 0x5: /* fnegs */
case 0x9: /* fabss */
+ case 0x2: /* V9 fmovd */
+ case 0x6: /* V9 fnegd */
+ case 0xa: /* V9 fabsd */
g_assert_not_reached(); /* in decodetree */
case 0x29: /* fsqrts */
gen_fop_FF(dc, rd, rs2, gen_helper_fsqrts);
@@ -5060,24 +5090,14 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
gen_fop_FQ(dc, rd, rs2, gen_helper_fqtoi);
break;
#ifdef TARGET_SPARC64
- case 0x2: /* V9 fmovd */
- cpu_src1_64 = gen_load_fpr_D(dc, rs2);
- gen_store_fpr_D(dc, rd, cpu_src1_64);
- break;
case 0x3: /* V9 fmovq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_move_Q(dc, rd, rs2);
break;
- case 0x6: /* V9 fnegd */
- gen_ne_fop_DD(dc, rd, rs2, gen_helper_fnegd);
- break;
case 0x7: /* V9 fnegq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fnegq);
break;
- case 0xa: /* V9 fabsd */
- gen_ne_fop_DD(dc, rd, rs2, gen_helper_fabsd);
- break;
case 0xb: /* V9 fabsq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fabsq);
@@ -5290,6 +5310,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x06b: /* VIS I fnot1s */
case 0x075: /* VIS I fsrc1s */
case 0x079: /* VIS I fsrc2s */
+ case 0x066: /* VIS I fnot2 */
+ case 0x06a: /* VIS I fnot1 */
+ case 0x074: /* VIS I fsrc1 */
+ case 0x078: /* VIS I fsrc2 */
g_assert_not_reached(); /* in decodetree */
case 0x020: /* VIS I fcmple16 */
CHECK_FPU_FEATURE(dc, VIS1);
@@ -5473,10 +5497,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_andc_i32);
break;
- case 0x066: /* VIS I fnot2 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DD(dc, rd, rs2, tcg_gen_not_i64);
- break;
case 0x068: /* VIS I fandnot1 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_andc_i64);
@@ -5485,10 +5505,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_andc_i32);
break;
- case 0x06a: /* VIS I fnot1 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DD(dc, rd, rs1, tcg_gen_not_i64);
- break;
case 0x06c: /* VIS I fxor */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_xor_i64);
@@ -5521,10 +5537,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_eqv_i32);
break;
- case 0x074: /* VIS I fsrc1 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- gen_store_fpr_D(dc, rd, cpu_src1_64);
break;
case 0x076: /* VIS I fornot2 */
CHECK_FPU_FEATURE(dc, VIS1);
@@ -5534,11 +5546,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_orc_i32);
break;
- case 0x078: /* VIS I fsrc2 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs2);
- gen_store_fpr_D(dc, rd, cpu_src1_64);
- break;
case 0x07a: /* VIS I fornot1 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_orc_i64);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 65/90] target/sparc: Use tcg_gen_vec_{add,sub}*
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (63 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 64/90] target/sparc: Move FMOVD, FNEGD, FABSD, FSRC*D, FNOT*D " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 66/90] target/sparc: Move gen_ne_fop_FFF insns to decodetree Richard Henderson
` (25 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Replace the local helpers for the same integer operations.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/helper.h | 12 --------
target/sparc/translate.c | 15 +++++-----
target/sparc/vis_helper.c | 59 ---------------------------------------
3 files changed, 7 insertions(+), 79 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 790752467f..dd1721a340 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -137,18 +137,6 @@ DEF_HELPER_FLAGS_2(fpack16, TCG_CALL_NO_RWG_SE, i32, i64, i64)
DEF_HELPER_FLAGS_3(fpack32, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
DEF_HELPER_FLAGS_2(fpackfix, TCG_CALL_NO_RWG_SE, i32, i64, i64)
DEF_HELPER_FLAGS_3(bshuffle, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
-#define VIS_HELPER(name) \
- DEF_HELPER_FLAGS_2(f ## name ## 16, TCG_CALL_NO_RWG_SE, \
- i64, i64, i64) \
- DEF_HELPER_FLAGS_2(f ## name ## 16s, TCG_CALL_NO_RWG_SE, \
- i32, i32, i32) \
- DEF_HELPER_FLAGS_2(f ## name ## 32, TCG_CALL_NO_RWG_SE, \
- i64, i64, i64) \
- DEF_HELPER_FLAGS_2(f ## name ## 32s, TCG_CALL_NO_RWG_SE, \
- i32, i32, i32)
-
-VIS_HELPER(padd)
-VIS_HELPER(psub)
#define VIS_CMPHELPER(name) \
DEF_HELPER_FLAGS_2(f##name##16, TCG_CALL_NO_RWG_SE, \
i64, i64, i64) \
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index c92b080b8f..d13980165b 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -25,9 +25,8 @@
#include "exec/helper-proto.h"
#include "exec/exec-all.h"
#include "tcg/tcg-op.h"
-
+#include "tcg/tcg-op-gvec.h"
#include "exec/helper-gen.h"
-
#include "exec/translator.h"
#include "exec/log.h"
#include "asi.h"
@@ -5439,15 +5438,15 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
break;
case 0x050: /* VIS I fpadd16 */
CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpadd16);
+ gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_add16_i64);
break;
case 0x051: /* VIS I fpadd16s */
CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, gen_helper_fpadd16s);
+ gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_vec_add16_i32);
break;
case 0x052: /* VIS I fpadd32 */
CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpadd32);
+ gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_add32_i64);
break;
case 0x053: /* VIS I fpadd32s */
CHECK_FPU_FEATURE(dc, VIS1);
@@ -5455,15 +5454,15 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
break;
case 0x054: /* VIS I fpsub16 */
CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpsub16);
+ gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_sub16_i64);
break;
case 0x055: /* VIS I fpsub16s */
CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, gen_helper_fpsub16s);
+ gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_vec_sub16_i32);
break;
case 0x056: /* VIS I fpsub32 */
CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpsub32);
+ gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_add32_i64);
break;
case 0x057: /* VIS I fpsub32s */
CHECK_FPU_FEATURE(dc, VIS1);
diff --git a/target/sparc/vis_helper.c b/target/sparc/vis_helper.c
index 3afdc6975c..7763b16c24 100644
--- a/target/sparc/vis_helper.c
+++ b/target/sparc/vis_helper.c
@@ -275,65 +275,6 @@ uint64_t helper_fexpand(uint64_t src1, uint64_t src2)
return d.ll;
}
-#define VIS_HELPER(name, F) \
- uint64_t name##16(uint64_t src1, uint64_t src2) \
- { \
- VIS64 s, d; \
- \
- s.ll = src1; \
- d.ll = src2; \
- \
- d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0)); \
- d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1)); \
- d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2)); \
- d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3)); \
- \
- return d.ll; \
- } \
- \
- uint32_t name##16s(uint32_t src1, uint32_t src2) \
- { \
- VIS32 s, d; \
- \
- s.l = src1; \
- d.l = src2; \
- \
- d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0)); \
- d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1)); \
- \
- return d.l; \
- } \
- \
- uint64_t name##32(uint64_t src1, uint64_t src2) \
- { \
- VIS64 s, d; \
- \
- s.ll = src1; \
- d.ll = src2; \
- \
- d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0)); \
- d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1)); \
- \
- return d.ll; \
- } \
- \
- uint32_t name##32s(uint32_t src1, uint32_t src2) \
- { \
- VIS32 s, d; \
- \
- s.l = src1; \
- d.l = src2; \
- \
- d.l = F(d.l, s.l); \
- \
- return d.l; \
- }
-
-#define FADD(a, b) ((a) + (b))
-#define FSUB(a, b) ((a) - (b))
-VIS_HELPER(helper_fpadd, FADD)
-VIS_HELPER(helper_fpsub, FSUB)
-
#define VIS_CMPHELPER(name, F) \
uint64_t name##16(uint64_t src1, uint64_t src2) \
{ \
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 66/90] target/sparc: Move gen_ne_fop_FFF insns to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (64 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 65/90] target/sparc: Use tcg_gen_vec_{add,sub}* Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 67/90] target/sparc: Move gen_ne_fop_DDD " Richard Henderson
` (24 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move FANDNOT1s, FANDNOT2s, FANDs, FNANDs, FNORs, FORNOT1s, FORNOT2s,
FORs, FPADD16s, FPADD32s, FPSUB16s, FPSUB32s, FXNORs, FXORs.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 16 ++++++
target/sparc/translate.c | 116 ++++++++++++++------------------------
2 files changed, 59 insertions(+), 73 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 91988e2978..d0301c929c 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -32,6 +32,7 @@ CALL 01 i:s30
&r_r_r rd rs1 rs2
@r_r_r .. rd:5 ...... rs1:5 . ........ rs2:5 &r_r_r
+@r_r_r_swap .. rd:5 ...... rs2:5 . ........ rs1:5 &r_r_r
&r_r rd rs
@r_r1 .. rd:5 ...... rs:5 . ........ ..... &r_r
@@ -270,6 +271,21 @@ FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
FNOTs 10 ..... 110110 ..... 0 0110 1011 00000 @r_r1 # FNOT1s
FNOTd 10 ..... 110110 00000 0 0110 0110 ..... @r_r2 # FNOT2d
FNOTs 10 ..... 110110 00000 0 0110 0111 ..... @r_r2 # FNOT2s
+
+ FPADD16s 10 ..... 110110 ..... 0 0101 0001 ..... @r_r_r
+ FPADD32s 10 ..... 110110 ..... 0 0101 0011 ..... @r_r_r
+ FPSUB16s 10 ..... 110110 ..... 0 0101 0101 ..... @r_r_r
+ FPSUB32s 10 ..... 110110 ..... 0 0101 0111 ..... @r_r_r
+ FNORs 10 ..... 110110 ..... 0 0110 0011 ..... @r_r_r
+ FANDNOTs 10 ..... 110110 ..... 0 0110 0101 ..... @r_r_r # FANDNOT2s
+ FANDNOTs 10 ..... 110110 ..... 0 0110 1001 ..... @r_r_r_swap # ... 1s
+ FXORs 10 ..... 110110 ..... 0 0110 1101 ..... @r_r_r
+ FNANDs 10 ..... 110110 ..... 0 0110 1111 ..... @r_r_r
+ FANDs 10 ..... 110110 ..... 0 0111 0001 ..... @r_r_r
+ FXNORs 10 ..... 110110 ..... 0 0111 0011 ..... @r_r_r
+ FORNOTs 10 ..... 110110 ..... 0 0111 0111 ..... @r_r_r # FORNOT2s
+ FORNOTs 10 ..... 110110 ..... 0 0111 1011 ..... @r_r_r_swap # ... 1s
+ FORs 10 ..... 110110 ..... 0 0111 1101 ..... @r_r_r
]
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index d13980165b..6f4406dbb3 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1582,22 +1582,6 @@ static void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
gen_store_fpr_F(dc, rd, dst);
}
-#ifdef TARGET_SPARC64
-static void gen_ne_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
- void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
-{
- TCGv_i32 dst, src1, src2;
-
- src1 = gen_load_fpr_F(dc, rs1);
- src2 = gen_load_fpr_F(dc, rs2);
- dst = gen_dest_fpr_F(dc);
-
- gen(dst, src1, src2);
-
- gen_store_fpr_F(dc, rd, dst);
-}
-#endif
-
static void gen_fop_DD(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64))
{
@@ -4941,6 +4925,35 @@ TRANS(FABSd, 64, do_dd, a, gen_op_fabsd)
TRANS(FSRCd, VIS1, do_dd, a, tcg_gen_mov_i64)
TRANS(FNOTd, VIS1, do_dd, a, tcg_gen_not_i64)
+static bool do_fff(DisasContext *dc, arg_r_r_r *a,
+ void (*func)(TCGv_i32, TCGv_i32, TCGv_i32))
+{
+ TCGv_i32 src1, src2;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ src1 = gen_load_fpr_F(dc, a->rs1);
+ src2 = gen_load_fpr_F(dc, a->rs2);
+ func(src1, src1, src2);
+ gen_store_fpr_F(dc, a->rd, src1);
+ return advance_pc(dc);
+}
+
+TRANS(FPADD16s, VIS1, do_fff, a, tcg_gen_vec_add16_i32)
+TRANS(FPADD32s, VIS1, do_fff, a, tcg_gen_add_i32)
+TRANS(FPSUB16s, VIS1, do_fff, a, tcg_gen_vec_sub16_i32)
+TRANS(FPSUB32s, VIS1, do_fff, a, tcg_gen_sub_i32)
+TRANS(FNORs, VIS1, do_fff, a, tcg_gen_nor_i32)
+TRANS(FANDNOTs, VIS1, do_fff, a, tcg_gen_andc_i32)
+TRANS(FXORs, VIS1, do_fff, a, tcg_gen_xor_i32)
+TRANS(FNANDs, VIS1, do_fff, a, tcg_gen_nand_i32)
+TRANS(FANDs, VIS1, do_fff, a, tcg_gen_and_i32)
+TRANS(FXNORs, VIS1, do_fff, a, tcg_gen_eqv_i32)
+TRANS(FORNOTs, VIS1, do_fff, a, tcg_gen_orc_i32)
+TRANS(FORs, VIS1, do_fff, a, tcg_gen_or_i32)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5313,6 +5326,20 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x06a: /* VIS I fnot1 */
case 0x074: /* VIS I fsrc1 */
case 0x078: /* VIS I fsrc2 */
+ case 0x051: /* VIS I fpadd16s */
+ case 0x053: /* VIS I fpadd32s */
+ case 0x055: /* VIS I fpsub16s */
+ case 0x057: /* VIS I fpsub32s */
+ case 0x063: /* VIS I fnors */
+ case 0x065: /* VIS I fandnot2s */
+ case 0x069: /* VIS I fandnot1s */
+ case 0x06d: /* VIS I fxors */
+ case 0x06f: /* VIS I fnands */
+ case 0x071: /* VIS I fands */
+ case 0x073: /* VIS I fxnors */
+ case 0x077: /* VIS I fornot2s */
+ case 0x07b: /* VIS I fornot1s */
+ case 0x07d: /* VIS I fors */
g_assert_not_reached(); /* in decodetree */
case 0x020: /* VIS I fcmple16 */
CHECK_FPU_FEATURE(dc, VIS1);
@@ -5440,34 +5467,18 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_add16_i64);
break;
- case 0x051: /* VIS I fpadd16s */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_vec_add16_i32);
- break;
case 0x052: /* VIS I fpadd32 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_add32_i64);
break;
- case 0x053: /* VIS I fpadd32s */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_add_i32);
- break;
case 0x054: /* VIS I fpsub16 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_sub16_i64);
break;
- case 0x055: /* VIS I fpsub16s */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_vec_sub16_i32);
- break;
case 0x056: /* VIS I fpsub32 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_add32_i64);
break;
- case 0x057: /* VIS I fpsub32s */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_sub_i32);
- break;
case 0x060: /* VIS I fzero */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_dst_64 = gen_dest_fpr_D(dc, rd);
@@ -5484,83 +5495,42 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nor_i64);
break;
- case 0x063: /* VIS I fnors */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_nor_i32);
- break;
case 0x064: /* VIS I fandnot2 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_andc_i64);
break;
- case 0x065: /* VIS I fandnot2s */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_andc_i32);
- break;
case 0x068: /* VIS I fandnot1 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_andc_i64);
break;
- case 0x069: /* VIS I fandnot1s */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_andc_i32);
- break;
case 0x06c: /* VIS I fxor */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_xor_i64);
break;
- case 0x06d: /* VIS I fxors */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_xor_i32);
- break;
case 0x06e: /* VIS I fnand */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nand_i64);
break;
- case 0x06f: /* VIS I fnands */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_nand_i32);
- break;
case 0x070: /* VIS I fand */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_and_i64);
break;
- case 0x071: /* VIS I fands */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_and_i32);
- break;
case 0x072: /* VIS I fxnor */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_eqv_i64);
break;
- case 0x073: /* VIS I fxnors */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_eqv_i32);
- break;
- break;
case 0x076: /* VIS I fornot2 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_orc_i64);
break;
- case 0x077: /* VIS I fornot2s */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_orc_i32);
- break;
case 0x07a: /* VIS I fornot1 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_orc_i64);
break;
- case 0x07b: /* VIS I fornot1s */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_orc_i32);
- break;
case 0x07c: /* VIS I for */
CHECK_FPU_FEATURE(dc, VIS1);
gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_or_i64);
break;
- case 0x07d: /* VIS I fors */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_or_i32);
- break;
case 0x07e: /* VIS I fone */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_dst_64 = gen_dest_fpr_D(dc, rd);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 67/90] target/sparc: Move gen_ne_fop_DDD insns to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (65 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 66/90] target/sparc: Move gen_ne_fop_FFF insns to decodetree Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 68/90] target/sparc: Move PDIST " Richard Henderson
` (23 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move FMUL8x16, FMUL8x16AU, FMUL8x16AL, FMUL8SUx16, FMUL8ULx16,
FMULD8SUx16, FMULD8ULx16, FPMERGE, FEXPAND, FANDNOT1d, FANDNOT2d,
FANDd, FNANDd, FNORd, FORNOT1d, FORNOT2d, FORd, FPADD16d, FPADD32d,
FPSUB16d, FPSUB32d, FXNORd, FXORd.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 26 ++++++
target/sparc/translate.c | 178 +++++++++++++++-----------------------
2 files changed, 98 insertions(+), 106 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index d0301c929c..197d6a0db3 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -263,6 +263,17 @@ FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
BMASK 10 ..... 110110 ..... 0 0001 1001 ..... @r_r_r
+ FMUL8x16 10 ..... 110110 ..... 0 0011 0001 ..... @r_r_r
+ FMUL8x16AU 10 ..... 110110 ..... 0 0011 0011 ..... @r_r_r
+ FMUL8x16AL 10 ..... 110110 ..... 0 0011 0101 ..... @r_r_r
+ FMUL8SUx16 10 ..... 110110 ..... 0 0011 0110 ..... @r_r_r
+ FMUL8ULx16 10 ..... 110110 ..... 0 0011 0111 ..... @r_r_r
+ FMULD8SUx16 10 ..... 110110 ..... 0 0011 1000 ..... @r_r_r
+ FMULD8ULx16 10 ..... 110110 ..... 0 0011 1001 ..... @r_r_r
+
+ FPMERGE 10 ..... 110110 ..... 0 0100 1011 ..... @r_r_r
+ FEXPAND 10 ..... 110110 ..... 0 0100 1101 ..... @r_r_r
+
FSRCd 10 ..... 110110 ..... 0 0111 0100 00000 @r_r1 # FSRC1d
FSRCs 10 ..... 110110 ..... 0 0111 0101 00000 @r_r1 # FSRC1s
FSRCd 10 ..... 110110 00000 0 0111 1000 ..... @r_r2 # FSRC2d
@@ -272,19 +283,34 @@ FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
FNOTd 10 ..... 110110 00000 0 0110 0110 ..... @r_r2 # FNOT2d
FNOTs 10 ..... 110110 00000 0 0110 0111 ..... @r_r2 # FNOT2s
+ FPADD16 10 ..... 110110 ..... 0 0101 0000 ..... @r_r_r
FPADD16s 10 ..... 110110 ..... 0 0101 0001 ..... @r_r_r
+ FPADD32 10 ..... 110110 ..... 0 0101 0010 ..... @r_r_r
FPADD32s 10 ..... 110110 ..... 0 0101 0011 ..... @r_r_r
+ FPSUB16 10 ..... 110110 ..... 0 0101 0100 ..... @r_r_r
FPSUB16s 10 ..... 110110 ..... 0 0101 0101 ..... @r_r_r
+ FPSUB32 10 ..... 110110 ..... 0 0101 0110 ..... @r_r_r
FPSUB32s 10 ..... 110110 ..... 0 0101 0111 ..... @r_r_r
+
+ FNORd 10 ..... 110110 ..... 0 0110 0010 ..... @r_r_r
FNORs 10 ..... 110110 ..... 0 0110 0011 ..... @r_r_r
+ FANDNOTd 10 ..... 110110 ..... 0 0110 0100 ..... @r_r_r # FANDNOT2d
FANDNOTs 10 ..... 110110 ..... 0 0110 0101 ..... @r_r_r # FANDNOT2s
+ FANDNOTd 10 ..... 110110 ..... 0 0110 1000 ..... @r_r_r_swap # ... 1d
FANDNOTs 10 ..... 110110 ..... 0 0110 1001 ..... @r_r_r_swap # ... 1s
+ FXORd 10 ..... 110110 ..... 0 0110 1100 ..... @r_r_r
FXORs 10 ..... 110110 ..... 0 0110 1101 ..... @r_r_r
+ FNANDd 10 ..... 110110 ..... 0 0110 1110 ..... @r_r_r
FNANDs 10 ..... 110110 ..... 0 0110 1111 ..... @r_r_r
+ FANDd 10 ..... 110110 ..... 0 0111 0000 ..... @r_r_r
FANDs 10 ..... 110110 ..... 0 0111 0001 ..... @r_r_r
+ FXNORd 10 ..... 110110 ..... 0 0111 0010 ..... @r_r_r
FXNORs 10 ..... 110110 ..... 0 0111 0011 ..... @r_r_r
+ FORNOTd 10 ..... 110110 ..... 0 0111 0110 ..... @r_r_r # FORNOT2d
FORNOTs 10 ..... 110110 ..... 0 0111 0111 ..... @r_r_r # FORNOT2s
+ FORNOTd 10 ..... 110110 ..... 0 0111 1010 ..... @r_r_r_swap # ... 1d
FORNOTs 10 ..... 110110 ..... 0 0111 1011 ..... @r_r_r_swap # ... 1s
+ FORd 10 ..... 110110 ..... 0 0111 1100 ..... @r_r_r
FORs 10 ..... 110110 ..... 0 0111 1101 ..... @r_r_r
]
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 6f4406dbb3..a5901164f3 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -59,6 +59,15 @@
#define gen_helper_retry(E) qemu_build_not_reached()
#define gen_helper_udivx(D, E, A, B) qemu_build_not_reached()
#define gen_helper_sdivx(D, E, A, B) qemu_build_not_reached()
+#define gen_helper_fmul8x16 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fmul8x16au ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fmul8x16al ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fmul8sux16 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fmul8ulx16 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fmuld8sux16 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fmuld8ulx16 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fpmerge ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fexpand ({ g_assert_not_reached(); NULL; })
#define FSR_LDXFSR_MASK ({ qemu_build_not_reached(); 0; })
#define FSR_LDXFSR_OLDMASK ({ qemu_build_not_reached(); 0; })
# ifdef CONFIG_USER_ONLY
@@ -1612,20 +1621,6 @@ static void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
}
#ifdef TARGET_SPARC64
-static void gen_ne_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
- void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64))
-{
- TCGv_i64 dst, src1, src2;
-
- src1 = gen_load_fpr_D(dc, rs1);
- src2 = gen_load_fpr_D(dc, rs2);
- dst = gen_dest_fpr_D(dc, rd);
-
- gen(dst, src1, src2);
-
- gen_store_fpr_D(dc, rd, dst);
-}
-
static void gen_gsr_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
{
@@ -4954,6 +4949,46 @@ TRANS(FXNORs, VIS1, do_fff, a, tcg_gen_eqv_i32)
TRANS(FORNOTs, VIS1, do_fff, a, tcg_gen_orc_i32)
TRANS(FORs, VIS1, do_fff, a, tcg_gen_or_i32)
+static bool do_ddd(DisasContext *dc, arg_r_r_r *a,
+ void (*func)(TCGv_i64, TCGv_i64, TCGv_i64))
+{
+ TCGv_i64 dst, src1, src2;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ dst = gen_dest_fpr_D(dc, a->rd);
+ src1 = gen_load_fpr_D(dc, a->rs1);
+ src2 = gen_load_fpr_D(dc, a->rs2);
+ func(dst, src1, src2);
+ gen_store_fpr_D(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(FMUL8x16, VIS1, do_ddd, a, gen_helper_fmul8x16)
+TRANS(FMUL8x16AU, VIS1, do_ddd, a, gen_helper_fmul8x16au)
+TRANS(FMUL8x16AL, VIS1, do_ddd, a, gen_helper_fmul8x16al)
+TRANS(FMUL8SUx16, VIS1, do_ddd, a, gen_helper_fmul8sux16)
+TRANS(FMUL8ULx16, VIS1, do_ddd, a, gen_helper_fmul8ulx16)
+TRANS(FMULD8SUx16, VIS1, do_ddd, a, gen_helper_fmuld8sux16)
+TRANS(FMULD8ULx16, VIS1, do_ddd, a, gen_helper_fmuld8ulx16)
+TRANS(FPMERGE, VIS1, do_ddd, a, gen_helper_fpmerge)
+TRANS(FEXPAND, VIS1, do_ddd, a, gen_helper_fexpand)
+
+TRANS(FPADD16, VIS1, do_ddd, a, tcg_gen_vec_add16_i64)
+TRANS(FPADD32, VIS1, do_ddd, a, tcg_gen_vec_add32_i64)
+TRANS(FPSUB16, VIS1, do_ddd, a, tcg_gen_vec_sub16_i64)
+TRANS(FPSUB32, VIS1, do_ddd, a, tcg_gen_vec_sub32_i64)
+TRANS(FNORd, VIS1, do_ddd, a, tcg_gen_nor_i64)
+TRANS(FANDNOTd, VIS1, do_ddd, a, tcg_gen_andc_i64)
+TRANS(FXORd, VIS1, do_ddd, a, tcg_gen_xor_i64)
+TRANS(FNANDd, VIS1, do_ddd, a, tcg_gen_nand_i64)
+TRANS(FANDd, VIS1, do_ddd, a, tcg_gen_and_i64)
+TRANS(FXNORd, VIS1, do_ddd, a, tcg_gen_eqv_i64)
+TRANS(FORNOTd, VIS1, do_ddd, a, tcg_gen_orc_i64)
+TRANS(FORd, VIS1, do_ddd, a, tcg_gen_or_i64)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5340,6 +5375,29 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x077: /* VIS I fornot2s */
case 0x07b: /* VIS I fornot1s */
case 0x07d: /* VIS I fors */
+ case 0x050: /* VIS I fpadd16 */
+ case 0x052: /* VIS I fpadd32 */
+ case 0x054: /* VIS I fpsub16 */
+ case 0x056: /* VIS I fpsub32 */
+ case 0x062: /* VIS I fnor */
+ case 0x064: /* VIS I fandnot2 */
+ case 0x068: /* VIS I fandnot1 */
+ case 0x06c: /* VIS I fxor */
+ case 0x06e: /* VIS I fnand */
+ case 0x070: /* VIS I fand */
+ case 0x072: /* VIS I fxnor */
+ case 0x076: /* VIS I fornot2 */
+ case 0x07a: /* VIS I fornot1 */
+ case 0x07c: /* VIS I for */
+ case 0x031: /* VIS I fmul8x16 */
+ case 0x033: /* VIS I fmul8x16au */
+ case 0x035: /* VIS I fmul8x16al */
+ case 0x036: /* VIS I fmul8sux16 */
+ case 0x037: /* VIS I fmul8ulx16 */
+ case 0x038: /* VIS I fmuld8sux16 */
+ case 0x039: /* VIS I fmuld8ulx16 */
+ case 0x04b: /* VIS I fpmerge */
+ case 0x04d: /* VIS I fexpand */
g_assert_not_reached(); /* in decodetree */
case 0x020: /* VIS I fcmple16 */
CHECK_FPU_FEATURE(dc, VIS1);
@@ -5397,34 +5455,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
gen_helper_fcmpeq32(cpu_dst, cpu_src1_64, cpu_src2_64);
gen_store_gpr(dc, rd, cpu_dst);
break;
- case 0x031: /* VIS I fmul8x16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16);
- break;
- case 0x033: /* VIS I fmul8x16au */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16au);
- break;
- case 0x035: /* VIS I fmul8x16al */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16al);
- break;
- case 0x036: /* VIS I fmul8sux16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8sux16);
- break;
- case 0x037: /* VIS I fmul8ulx16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8ulx16);
- break;
- case 0x038: /* VIS I fmuld8sux16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld8sux16);
- break;
- case 0x039: /* VIS I fmuld8ulx16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld8ulx16);
- break;
case 0x03a: /* VIS I fpack32 */
CHECK_FPU_FEATURE(dc, VIS1);
gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpack32);
@@ -5451,34 +5481,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, VIS1);
gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_faligndata);
break;
- case 0x04b: /* VIS I fpmerge */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpmerge);
- break;
case 0x04c: /* VIS II bshuffle */
CHECK_FPU_FEATURE(dc, VIS2);
gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_bshuffle);
break;
- case 0x04d: /* VIS I fexpand */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fexpand);
- break;
- case 0x050: /* VIS I fpadd16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_add16_i64);
- break;
- case 0x052: /* VIS I fpadd32 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_add32_i64);
- break;
- case 0x054: /* VIS I fpsub16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_sub16_i64);
- break;
- case 0x056: /* VIS I fpsub32 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_vec_add32_i64);
- break;
case 0x060: /* VIS I fzero */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_dst_64 = gen_dest_fpr_D(dc, rd);
@@ -5491,46 +5497,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
tcg_gen_movi_i32(cpu_dst_32, 0);
gen_store_fpr_F(dc, rd, cpu_dst_32);
break;
- case 0x062: /* VIS I fnor */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nor_i64);
- break;
- case 0x064: /* VIS I fandnot2 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_andc_i64);
- break;
- case 0x068: /* VIS I fandnot1 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_andc_i64);
- break;
- case 0x06c: /* VIS I fxor */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_xor_i64);
- break;
- case 0x06e: /* VIS I fnand */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nand_i64);
- break;
- case 0x070: /* VIS I fand */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_and_i64);
- break;
- case 0x072: /* VIS I fxnor */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_eqv_i64);
- break;
- case 0x076: /* VIS I fornot2 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_orc_i64);
- break;
- case 0x07a: /* VIS I fornot1 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_orc_i64);
- break;
- case 0x07c: /* VIS I for */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_or_i64);
- break;
case 0x07e: /* VIS I fone */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_dst_64 = gen_dest_fpr_D(dc, rd);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 68/90] target/sparc: Move PDIST to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (66 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 67/90] target/sparc: Move gen_ne_fop_DDD " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 69/90] target/sparc: Move gen_gsr_fop_DDD insns " Richard Henderson
` (22 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 1 +
target/sparc/translate.c | 41 +++++++++++++++++++++------------------
2 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 197d6a0db3..64a7b3bd0b 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -270,6 +270,7 @@ FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
FMUL8ULx16 10 ..... 110110 ..... 0 0011 0111 ..... @r_r_r
FMULD8SUx16 10 ..... 110110 ..... 0 0011 1000 ..... @r_r_r
FMULD8ULx16 10 ..... 110110 ..... 0 0011 1001 ..... @r_r_r
+ PDIST 10 ..... 110110 ..... 0 0011 1110 ..... @r_r_r
FPMERGE 10 ..... 110110 ..... 0 0100 1011 ..... @r_r_r
FEXPAND 10 ..... 110110 ..... 0 0100 1101 ..... @r_r_r
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index a5901164f3..5d2c95841a 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -68,6 +68,7 @@
#define gen_helper_fmuld8ulx16 ({ g_assert_not_reached(); NULL; })
#define gen_helper_fpmerge ({ g_assert_not_reached(); NULL; })
#define gen_helper_fexpand ({ g_assert_not_reached(); NULL; })
+#define gen_helper_pdist ({ g_assert_not_reached(); NULL; })
#define FSR_LDXFSR_MASK ({ qemu_build_not_reached(); 0; })
#define FSR_LDXFSR_OLDMASK ({ qemu_build_not_reached(); 0; })
# ifdef CONFIG_USER_ONLY
@@ -1634,21 +1635,6 @@ static void gen_gsr_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
gen_store_fpr_D(dc, rd, dst);
}
-
-static void gen_ne_fop_DDDD(DisasContext *dc, int rd, int rs1, int rs2,
- void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
-{
- TCGv_i64 dst, src0, src1, src2;
-
- src1 = gen_load_fpr_D(dc, rs1);
- src2 = gen_load_fpr_D(dc, rs2);
- src0 = gen_load_fpr_D(dc, rd);
- dst = gen_dest_fpr_D(dc, rd);
-
- gen(dst, src0, src1, src2);
-
- gen_store_fpr_D(dc, rd, dst);
-}
#endif
static void gen_fop_QQ(DisasContext *dc, int rd, int rs,
@@ -4989,6 +4975,26 @@ TRANS(FXNORd, VIS1, do_ddd, a, tcg_gen_eqv_i64)
TRANS(FORNOTd, VIS1, do_ddd, a, tcg_gen_orc_i64)
TRANS(FORd, VIS1, do_ddd, a, tcg_gen_or_i64)
+static bool do_dddd(DisasContext *dc, arg_r_r_r *a,
+ void (*func)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
+{
+ TCGv_i64 dst, src0, src1, src2;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ dst = gen_dest_fpr_D(dc, a->rd);
+ src0 = gen_load_fpr_D(dc, a->rd);
+ src1 = gen_load_fpr_D(dc, a->rs1);
+ src2 = gen_load_fpr_D(dc, a->rs2);
+ func(dst, src0, src1, src2);
+ gen_store_fpr_D(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(PDIST, VIS1, do_dddd, a, gen_helper_pdist)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5398,6 +5404,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x039: /* VIS I fmuld8ulx16 */
case 0x04b: /* VIS I fpmerge */
case 0x04d: /* VIS I fexpand */
+ case 0x03e: /* VIS I pdist */
g_assert_not_reached(); /* in decodetree */
case 0x020: /* VIS I fcmple16 */
CHECK_FPU_FEATURE(dc, VIS1);
@@ -5473,10 +5480,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
gen_helper_fpackfix(cpu_dst_32, cpu_gsr, cpu_src1_64);
gen_store_fpr_F(dc, rd, cpu_dst_32);
break;
- case 0x03e: /* VIS I pdist */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_ne_fop_DDDD(dc, rd, rs1, rs2, gen_helper_pdist);
- break;
case 0x048: /* VIS I faligndata */
CHECK_FPU_FEATURE(dc, VIS1);
gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_faligndata);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 69/90] target/sparc: Move gen_gsr_fop_DDD insns to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (67 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 68/90] target/sparc: Move PDIST " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 70/90] target/sparc: Move gen_fop_FF " Richard Henderson
` (21 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move FPACK32, FALIGNDATA, BSHUFFLE.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 3 ++
target/sparc/translate.c | 101 ++++++++++++++++++++------------------
2 files changed, 55 insertions(+), 49 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 64a7b3bd0b..966cda6680 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -270,9 +270,12 @@ FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
FMUL8ULx16 10 ..... 110110 ..... 0 0011 0111 ..... @r_r_r
FMULD8SUx16 10 ..... 110110 ..... 0 0011 1000 ..... @r_r_r
FMULD8ULx16 10 ..... 110110 ..... 0 0011 1001 ..... @r_r_r
+ FPACK32 10 ..... 110110 ..... 0 0011 1010 ..... @r_r_r
PDIST 10 ..... 110110 ..... 0 0011 1110 ..... @r_r_r
+ FALIGNDATAg 10 ..... 110110 ..... 0 0100 1000 ..... @r_r_r
FPMERGE 10 ..... 110110 ..... 0 0100 1011 ..... @r_r_r
+ BSHUFFLE 10 ..... 110110 ..... 0 0100 1100 ..... @r_r_r
FEXPAND 10 ..... 110110 ..... 0 0100 1101 ..... @r_r_r
FSRCd 10 ..... 110110 ..... 0 0111 0100 00000 @r_r1 # FSRC1d
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 5d2c95841a..cd585b77bc 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -706,6 +706,51 @@ static void gen_op_array32(TCGv dst, TCGv src1, TCGv src2)
tcg_gen_shli_tl(dst, dst, 2);
}
+static void gen_op_fpack32(TCGv_i64 dst, TCGv_i64 src1, TCGv_i64 src2)
+{
+#ifdef TARGET_SPARC64
+ gen_helper_fpack32(dst, cpu_gsr, src1, src2);
+#else
+ g_assert_not_reached();
+#endif
+}
+
+static void gen_op_faligndata(TCGv_i64 dst, TCGv_i64 s1, TCGv_i64 s2)
+{
+#ifdef TARGET_SPARC64
+ TCGv t1, t2, shift;
+
+ t1 = tcg_temp_new();
+ t2 = tcg_temp_new();
+ shift = tcg_temp_new();
+
+ tcg_gen_andi_tl(shift, cpu_gsr, 7);
+ tcg_gen_shli_tl(shift, shift, 3);
+ tcg_gen_shl_tl(t1, s1, shift);
+
+ /*
+ * A shift of 64 does not produce 0 in TCG. Divide this into a
+ * shift of (up to 63) followed by a constant shift of 1.
+ */
+ tcg_gen_xori_tl(shift, shift, 63);
+ tcg_gen_shr_tl(t2, s2, shift);
+ tcg_gen_shri_tl(t2, t2, 1);
+
+ tcg_gen_or_tl(dst, t1, t2);
+#else
+ g_assert_not_reached();
+#endif
+}
+
+static void gen_op_bshuffle(TCGv_i64 dst, TCGv_i64 src1, TCGv_i64 src2)
+{
+#ifdef TARGET_SPARC64
+ gen_helper_bshuffle(dst, cpu_gsr, src1, src2);
+#else
+ g_assert_not_reached();
+#endif
+}
+
// 1
static void gen_op_eval_ba(TCGv dst)
{
@@ -1621,22 +1666,6 @@ static void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
gen_store_fpr_D(dc, rd, dst);
}
-#ifdef TARGET_SPARC64
-static void gen_gsr_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
- void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
-{
- TCGv_i64 dst, src1, src2;
-
- src1 = gen_load_fpr_D(dc, rs1);
- src2 = gen_load_fpr_D(dc, rs2);
- dst = gen_dest_fpr_D(dc, rd);
-
- gen(dst, cpu_gsr, src1, src2);
-
- gen_store_fpr_D(dc, rd, dst);
-}
-#endif
-
static void gen_fop_QQ(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_ptr))
{
@@ -2658,27 +2687,6 @@ static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr)
tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
}
}
-
-static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
-{
- TCGv t1, t2, shift;
-
- t1 = tcg_temp_new();
- t2 = tcg_temp_new();
- shift = tcg_temp_new();
-
- tcg_gen_andi_tl(shift, gsr, 7);
- tcg_gen_shli_tl(shift, shift, 3);
- tcg_gen_shl_tl(t1, s1, shift);
-
- /* A shift of 64 does not produce 0 in TCG. Divide this into a
- shift of (up to 63) followed by a constant shift of 1. */
- tcg_gen_xori_tl(shift, shift, 63);
- tcg_gen_shr_tl(t2, s2, shift);
- tcg_gen_shri_tl(t2, t2, 1);
-
- tcg_gen_or_tl(dst, t1, t2);
-}
#endif
static int extract_dfpreg(DisasContext *dc, int x)
@@ -4975,6 +4983,10 @@ TRANS(FXNORd, VIS1, do_ddd, a, tcg_gen_eqv_i64)
TRANS(FORNOTd, VIS1, do_ddd, a, tcg_gen_orc_i64)
TRANS(FORd, VIS1, do_ddd, a, tcg_gen_or_i64)
+TRANS(FPACK32, VIS1, do_ddd, a, gen_op_fpack32)
+TRANS(FALIGNDATAg, VIS1, do_ddd, a, gen_op_faligndata)
+TRANS(BSHUFFLE, VIS2, do_ddd, a, gen_op_bshuffle)
+
static bool do_dddd(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
{
@@ -5405,6 +5417,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x04b: /* VIS I fpmerge */
case 0x04d: /* VIS I fexpand */
case 0x03e: /* VIS I pdist */
+ case 0x03a: /* VIS I fpack32 */
+ case 0x048: /* VIS I faligndata */
+ case 0x04c: /* VIS II bshuffle */
g_assert_not_reached(); /* in decodetree */
case 0x020: /* VIS I fcmple16 */
CHECK_FPU_FEATURE(dc, VIS1);
@@ -5462,10 +5477,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
gen_helper_fcmpeq32(cpu_dst, cpu_src1_64, cpu_src2_64);
gen_store_gpr(dc, rd, cpu_dst);
break;
- case 0x03a: /* VIS I fpack32 */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpack32);
- break;
case 0x03b: /* VIS I fpack16 */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_src1_64 = gen_load_fpr_D(dc, rs2);
@@ -5480,14 +5491,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
gen_helper_fpackfix(cpu_dst_32, cpu_gsr, cpu_src1_64);
gen_store_fpr_F(dc, rd, cpu_dst_32);
break;
- case 0x048: /* VIS I faligndata */
- CHECK_FPU_FEATURE(dc, VIS1);
- gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_faligndata);
- break;
- case 0x04c: /* VIS II bshuffle */
- CHECK_FPU_FEATURE(dc, VIS2);
- gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_bshuffle);
- break;
case 0x060: /* VIS I fzero */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_dst_64 = gen_dest_fpr_D(dc, rd);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 70/90] target/sparc: Move gen_fop_FF insns to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (68 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 69/90] target/sparc: Move gen_gsr_fop_DDD insns " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 71/90] target/sparc: Move gen_fop_DD " Richard Henderson
` (20 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move FSQRTs, FiTOs, FsTOi.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 3 +++
target/sparc/translate.c | 47 ++++++++++++++++++++-------------------
2 files changed, 27 insertions(+), 23 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 966cda6680..4f10809e98 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -238,6 +238,9 @@ FNEGs 10 ..... 110100 00000 0 0000 0101 ..... @r_r2
FNEGd 10 ..... 110100 00000 0 0000 0110 ..... @r_r2
FABSs 10 ..... 110100 00000 0 0000 1001 ..... @r_r2
FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
+FSQRTs 10 ..... 110100 00000 0 0010 1001 ..... @r_r2
+FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
+FsTOi 10 ..... 110100 00000 0 1101 0001 ..... @r_r2
{
[
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index cd585b77bc..6707164207 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1608,20 +1608,6 @@ static int gen_trap_ifnofpu(DisasContext *dc)
return 0;
}
-static void gen_fop_FF(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32))
-{
- TCGv_i32 dst, src;
-
- src = gen_load_fpr_F(dc, rs);
- dst = gen_dest_fpr_F(dc);
-
- gen(dst, tcg_env, src);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_store_fpr_F(dc, rd, dst);
-}
-
static void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32))
{
@@ -4892,6 +4878,27 @@ TRANS(FABSs, ALL, do_ff, a, gen_op_fabss)
TRANS(FSRCs, VIS1, do_ff, a, tcg_gen_mov_i32)
TRANS(FNOTs, VIS1, do_ff, a, tcg_gen_not_i32)
+static bool do_env_ff(DisasContext *dc, arg_r_r *a,
+ void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
+{
+ TCGv_i32 tmp;
+
+ if (gen_trap_ifnofpu(dc)) {
+ 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);
+ gen_store_fpr_F(dc, a->rd, tmp);
+ return advance_pc(dc);
+}
+
+TRANS(FSQRTs, ALL, do_env_ff, a, gen_helper_fsqrts)
+TRANS(FiTOs, ALL, do_env_ff, a, gen_helper_fitos)
+TRANS(FsTOi, ALL, do_env_ff, a, gen_helper_fstoi)
+
static bool do_dd(DisasContext *dc, arg_r_r *a,
void (*func)(TCGv_i64, TCGv_i64))
{
@@ -5053,10 +5060,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x2: /* V9 fmovd */
case 0x6: /* V9 fnegd */
case 0xa: /* V9 fabsd */
- g_assert_not_reached(); /* in decodetree */
case 0x29: /* fsqrts */
- gen_fop_FF(dc, rd, rs2, gen_helper_fsqrts);
- break;
+ case 0xc4: /* fitos */
+ case 0xd1: /* fstoi */
+ g_assert_not_reached(); /* in decodetree */
case 0x2a: /* fsqrtd */
gen_fop_DD(dc, rd, rs2, gen_helper_fsqrtd);
break;
@@ -5112,9 +5119,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_QDD(dc, rd, rs1, rs2, gen_helper_fdmulq);
break;
- case 0xc4: /* fitos */
- gen_fop_FF(dc, rd, rs2, gen_helper_fitos);
- break;
case 0xc6: /* fdtos */
gen_fop_FD(dc, rd, rs2, gen_helper_fdtos);
break;
@@ -5144,9 +5148,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QD(dc, rd, rs2, gen_helper_fdtoq);
break;
- case 0xd1: /* fstoi */
- gen_fop_FF(dc, rd, rs2, gen_helper_fstoi);
- break;
case 0xd2: /* fdtoi */
gen_fop_FD(dc, rd, rs2, gen_helper_fdtoi);
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 71/90] target/sparc: Move gen_fop_DD insns to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (69 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 70/90] target/sparc: Move gen_fop_FF " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 72/90] target/sparc: Move FSQRTq " Richard Henderson
` (19 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move FSQRTd, FxTOd, FdTOx.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 3 +++
target/sparc/translate.c | 50 +++++++++++++++++++++------------------
2 files changed, 30 insertions(+), 23 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 4f10809e98..fa95ca056a 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -239,6 +239,9 @@ FNEGd 10 ..... 110100 00000 0 0000 0110 ..... @r_r2
FABSs 10 ..... 110100 00000 0 0000 1001 ..... @r_r2
FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
FSQRTs 10 ..... 110100 00000 0 0010 1001 ..... @r_r2
+FSQRTd 10 ..... 110100 00000 0 0010 1010 ..... @r_r2
+FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
+FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
FsTOi 10 ..... 110100 00000 0 1101 0001 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 6707164207..b7eac4a6e5 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -53,6 +53,8 @@
#define gen_helper_write_softint(E, S) qemu_build_not_reached()
#define gen_helper_saved ({ qemu_build_not_reached(); NULL; })
#define gen_helper_restored ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_fdtox ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_fxtod ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fnegd(D, S) qemu_build_not_reached()
#define gen_helper_fabsd(D, S) qemu_build_not_reached()
#define gen_helper_done(E) qemu_build_not_reached()
@@ -1623,20 +1625,6 @@ static void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
gen_store_fpr_F(dc, rd, dst);
}
-static void gen_fop_DD(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64))
-{
- TCGv_i64 dst, src;
-
- src = gen_load_fpr_D(dc, rs);
- dst = gen_dest_fpr_D(dc, rd);
-
- gen(dst, tcg_env, src);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_store_fpr_D(dc, rd, dst);
-}
-
static void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64))
{
@@ -4921,6 +4909,28 @@ TRANS(FABSd, 64, do_dd, a, gen_op_fabsd)
TRANS(FSRCd, VIS1, do_dd, a, tcg_gen_mov_i64)
TRANS(FNOTd, VIS1, do_dd, a, tcg_gen_not_i64)
+static bool do_env_dd(DisasContext *dc, arg_r_r *a,
+ void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
+{
+ TCGv_i64 dst, src;
+
+ if (gen_trap_ifnofpu(dc)) {
+ 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);
+ gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
+ gen_store_fpr_D(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(FSQRTd, ALL, do_env_dd, a, gen_helper_fsqrtd)
+TRANS(FxTOd, 64, do_env_dd, a, gen_helper_fxtod)
+TRANS(FdTOx, 64, do_env_dd, a, gen_helper_fdtox)
+
static bool do_fff(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i32, TCGv_i32, TCGv_i32))
{
@@ -5063,10 +5073,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x29: /* fsqrts */
case 0xc4: /* fitos */
case 0xd1: /* fstoi */
- g_assert_not_reached(); /* in decodetree */
case 0x2a: /* fsqrtd */
- gen_fop_DD(dc, rd, rs2, gen_helper_fsqrtd);
- break;
+ case 0x82: /* V9 fdtox */
+ case 0x88: /* V9 fxtod */
+ g_assert_not_reached(); /* in decodetree */
case 0x2b: /* fsqrtq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_QQ(dc, rd, rs2, gen_helper_fsqrtq);
@@ -5171,9 +5181,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x81: /* V9 fstox */
gen_fop_DF(dc, rd, rs2, gen_helper_fstox);
break;
- case 0x82: /* V9 fdtox */
- gen_fop_DD(dc, rd, rs2, gen_helper_fdtox);
- break;
case 0x83: /* V9 fqtox */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_DQ(dc, rd, rs2, gen_helper_fqtox);
@@ -5181,9 +5188,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x84: /* V9 fxtos */
gen_fop_FD(dc, rd, rs2, gen_helper_fxtos);
break;
- case 0x88: /* V9 fxtod */
- gen_fop_DD(dc, rd, rs2, gen_helper_fxtod);
- break;
case 0x8c: /* V9 fxtoq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QD(dc, rd, rs2, gen_helper_fxtoq);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 72/90] target/sparc: Move FSQRTq to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (70 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 71/90] target/sparc: Move gen_fop_DD " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 73/90] target/sparc: Move gen_fop_FFF insns " Richard Henderson
` (18 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 1 +
target/sparc/translate.c | 39 +++++++++++++++++++++++----------------
2 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index fa95ca056a..7fdd8e37d1 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -240,6 +240,7 @@ FABSs 10 ..... 110100 00000 0 0000 1001 ..... @r_r2
FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
FSQRTs 10 ..... 110100 00000 0 0010 1001 ..... @r_r2
FSQRTd 10 ..... 110100 00000 0 0010 1010 ..... @r_r2
+FSQRTq 10 ..... 110100 00000 0 0010 1011 ..... @r_r2
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index b7eac4a6e5..ffcd630a91 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -71,6 +71,7 @@
#define gen_helper_fpmerge ({ g_assert_not_reached(); NULL; })
#define gen_helper_fexpand ({ g_assert_not_reached(); NULL; })
#define gen_helper_pdist ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fsqrtq ({ g_assert_not_reached(); NULL; })
#define FSR_LDXFSR_MASK ({ qemu_build_not_reached(); 0; })
#define FSR_LDXFSR_OLDMASK ({ qemu_build_not_reached(); 0; })
# ifdef CONFIG_USER_ONLY
@@ -1640,18 +1641,6 @@ static void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
gen_store_fpr_D(dc, rd, dst);
}
-static void gen_fop_QQ(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_ptr))
-{
- gen_op_load_fpr_QT1(QFPREG(rs));
-
- gen(tcg_env);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_op_store_QT0_fpr(QFPREG(rd));
- gen_update_fprs_dirty(dc, QFPREG(rd));
-}
-
#ifdef TARGET_SPARC64
static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_ptr))
@@ -4931,6 +4920,27 @@ TRANS(FSQRTd, ALL, do_env_dd, a, gen_helper_fsqrtd)
TRANS(FxTOd, 64, do_env_dd, a, gen_helper_fxtod)
TRANS(FdTOx, 64, do_env_dd, a, gen_helper_fdtox)
+static bool do_env_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_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
+ gen_op_store_QT0_fpr(QFPREG(a->rd));
+ gen_update_fprs_dirty(dc, QFPREG(a->rd));
+ return advance_pc(dc);
+}
+
+TRANS(FSQRTq, ALL, do_env_qq, a, gen_helper_fsqrtq)
+
static bool do_fff(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i32, TCGv_i32, TCGv_i32))
{
@@ -5076,11 +5086,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x2a: /* fsqrtd */
case 0x82: /* V9 fdtox */
case 0x88: /* V9 fxtod */
- g_assert_not_reached(); /* in decodetree */
case 0x2b: /* fsqrtq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_fop_QQ(dc, rd, rs2, gen_helper_fsqrtq);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x41: /* fadds */
gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fadds);
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 73/90] target/sparc: Move gen_fop_FFF insns to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (71 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 72/90] target/sparc: Move FSQRTq " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 74/90] target/sparc: Move gen_fop_DDD " Richard Henderson
` (17 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move FADDs, FSUBs, FMULs, FDIVs.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 +++
target/sparc/translate.c | 54 +++++++++++++++++++--------------------
2 files changed, 31 insertions(+), 27 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 7fdd8e37d1..d70f193883 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -241,6 +241,10 @@ FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
FSQRTs 10 ..... 110100 00000 0 0010 1001 ..... @r_r2
FSQRTd 10 ..... 110100 00000 0 0010 1010 ..... @r_r2
FSQRTq 10 ..... 110100 00000 0 0010 1011 ..... @r_r2
+FADDs 10 ..... 110100 ..... 0 0100 0001 ..... @r_r_r
+FSUBs 10 ..... 110100 ..... 0 0100 0101 ..... @r_r_r
+FMULs 10 ..... 110100 ..... 0 0100 1001 ..... @r_r_r
+FDIVs 10 ..... 110100 ..... 0 0100 1101 ..... @r_r_r
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index ffcd630a91..6b3b60fb22 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1611,21 +1611,6 @@ static int gen_trap_ifnofpu(DisasContext *dc)
return 0;
}
-static void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
- void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32))
-{
- TCGv_i32 dst, src1, src2;
-
- src1 = gen_load_fpr_F(dc, rs1);
- src2 = gen_load_fpr_F(dc, rs2);
- dst = gen_dest_fpr_F(dc);
-
- gen(dst, tcg_env, src1, src2);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_store_fpr_F(dc, rd, dst);
-}
-
static void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64))
{
@@ -4970,6 +4955,29 @@ TRANS(FXNORs, VIS1, do_fff, a, tcg_gen_eqv_i32)
TRANS(FORNOTs, VIS1, do_fff, a, tcg_gen_orc_i32)
TRANS(FORs, VIS1, do_fff, a, tcg_gen_or_i32)
+static bool do_env_fff(DisasContext *dc, arg_r_r_r *a,
+ void (*func)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
+{
+ TCGv_i32 src1, src2;
+
+ if (gen_trap_ifnofpu(dc)) {
+ 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);
+ gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
+ gen_store_fpr_F(dc, a->rd, src1);
+ return advance_pc(dc);
+}
+
+TRANS(FADDs, ALL, do_env_fff, a, gen_helper_fadds)
+TRANS(FSUBs, ALL, do_env_fff, a, gen_helper_fsubs)
+TRANS(FMULs, ALL, do_env_fff, a, gen_helper_fmuls)
+TRANS(FDIVs, ALL, do_env_fff, a, gen_helper_fdivs)
+
static bool do_ddd(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i64, TCGv_i64, TCGv_i64))
{
@@ -5087,10 +5095,11 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x82: /* V9 fdtox */
case 0x88: /* V9 fxtod */
case 0x2b: /* fsqrtq */
- g_assert_not_reached(); /* in decodetree */
case 0x41: /* fadds */
- gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fadds);
- break;
+ case 0x45: /* fsubs */
+ case 0x49: /* fmuls */
+ case 0x4d: /* fdivs */
+ g_assert_not_reached(); /* in decodetree */
case 0x42: /* faddd */
gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_faddd);
break;
@@ -5098,9 +5107,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_faddq);
break;
- case 0x45: /* fsubs */
- gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fsubs);
- break;
case 0x46: /* fsubd */
gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fsubd);
break;
@@ -5108,9 +5114,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fsubq);
break;
- case 0x49: /* fmuls */
- gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fmuls);
- break;
case 0x4a: /* fmuld */
gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld);
break;
@@ -5118,9 +5121,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fmulq);
break;
- case 0x4d: /* fdivs */
- gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fdivs);
- break;
case 0x4e: /* fdivd */
gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fdivd);
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 74/90] target/sparc: Move gen_fop_DDD insns to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (72 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 73/90] target/sparc: Move gen_fop_FFF insns " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 75/90] target/sparc: Move gen_fop_QQQ " Richard Henderson
` (16 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move FADDd, FSUBd, FMULd, FDIVd.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 +++
target/sparc/translate.c | 55 ++++++++++++++++++++-------------------
2 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index d70f193883..a86c9c85f7 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -242,9 +242,13 @@ FSQRTs 10 ..... 110100 00000 0 0010 1001 ..... @r_r2
FSQRTd 10 ..... 110100 00000 0 0010 1010 ..... @r_r2
FSQRTq 10 ..... 110100 00000 0 0010 1011 ..... @r_r2
FADDs 10 ..... 110100 ..... 0 0100 0001 ..... @r_r_r
+FADDd 10 ..... 110100 ..... 0 0100 0010 ..... @r_r_r
FSUBs 10 ..... 110100 ..... 0 0100 0101 ..... @r_r_r
+FSUBd 10 ..... 110100 ..... 0 0100 0110 ..... @r_r_r
FMULs 10 ..... 110100 ..... 0 0100 1001 ..... @r_r_r
+FMULd 10 ..... 110100 ..... 0 0100 1010 ..... @r_r_r
FDIVs 10 ..... 110100 ..... 0 0100 1101 ..... @r_r_r
+FDIVd 10 ..... 110100 ..... 0 0100 1110 ..... @r_r_r
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 6b3b60fb22..a875ca716b 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1611,21 +1611,6 @@ static int gen_trap_ifnofpu(DisasContext *dc)
return 0;
}
-static void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
- void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64))
-{
- TCGv_i64 dst, src1, src2;
-
- src1 = gen_load_fpr_D(dc, rs1);
- src2 = gen_load_fpr_D(dc, rs2);
- dst = gen_dest_fpr_D(dc, rd);
-
- gen(dst, tcg_env, src1, src2);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_store_fpr_D(dc, rd, dst);
-}
-
#ifdef TARGET_SPARC64
static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_ptr))
@@ -5022,6 +5007,30 @@ TRANS(FPACK32, VIS1, do_ddd, a, gen_op_fpack32)
TRANS(FALIGNDATAg, VIS1, do_ddd, a, gen_op_faligndata)
TRANS(BSHUFFLE, VIS2, do_ddd, a, gen_op_bshuffle)
+static bool do_env_ddd(DisasContext *dc, arg_r_r_r *a,
+ void (*func)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64))
+{
+ TCGv_i64 dst, src1, src2;
+
+ if (gen_trap_ifnofpu(dc)) {
+ 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);
+ 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);
+}
+
+TRANS(FADDd, ALL, do_env_ddd, a, gen_helper_faddd)
+TRANS(FSUBd, ALL, do_env_ddd, a, gen_helper_fsubd)
+TRANS(FMULd, ALL, do_env_ddd, a, gen_helper_fmuld)
+TRANS(FDIVd, ALL, do_env_ddd, a, gen_helper_fdivd)
+
static bool do_dddd(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
{
@@ -5099,31 +5108,23 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x45: /* fsubs */
case 0x49: /* fmuls */
case 0x4d: /* fdivs */
- g_assert_not_reached(); /* in decodetree */
case 0x42: /* faddd */
- gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_faddd);
- break;
+ case 0x46: /* fsubd */
+ case 0x4a: /* fmuld */
+ case 0x4e: /* fdivd */
+ g_assert_not_reached(); /* in decodetree */
case 0x43: /* faddq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_faddq);
break;
- case 0x46: /* fsubd */
- gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fsubd);
- break;
case 0x47: /* fsubq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fsubq);
break;
- case 0x4a: /* fmuld */
- gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld);
- break;
case 0x4b: /* fmulq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fmulq);
break;
- case 0x4e: /* fdivd */
- gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fdivd);
- break;
case 0x4f: /* fdivq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fdivq);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 75/90] target/sparc: Move gen_fop_QQQ insns to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (73 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 74/90] target/sparc: Move gen_fop_DDD " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 76/90] target/sparc: Move FSMULD " Richard Henderson
` (15 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move FADDq, FSUBq, FMULq, FDIVq.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 4 +++
target/sparc/translate.c | 52 +++++++++++++++++++--------------------
2 files changed, 30 insertions(+), 26 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index a86c9c85f7..0f7d898071 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -243,12 +243,16 @@ FSQRTd 10 ..... 110100 00000 0 0010 1010 ..... @r_r2
FSQRTq 10 ..... 110100 00000 0 0010 1011 ..... @r_r2
FADDs 10 ..... 110100 ..... 0 0100 0001 ..... @r_r_r
FADDd 10 ..... 110100 ..... 0 0100 0010 ..... @r_r_r
+FADDq 10 ..... 110100 ..... 0 0100 0011 ..... @r_r_r
FSUBs 10 ..... 110100 ..... 0 0100 0101 ..... @r_r_r
FSUBd 10 ..... 110100 ..... 0 0100 0110 ..... @r_r_r
+FSUBq 10 ..... 110100 ..... 0 0100 0111 ..... @r_r_r
FMULs 10 ..... 110100 ..... 0 0100 1001 ..... @r_r_r
FMULd 10 ..... 110100 ..... 0 0100 1010 ..... @r_r_r
+FMULq 10 ..... 110100 ..... 0 0100 1011 ..... @r_r_r
FDIVs 10 ..... 110100 ..... 0 0100 1101 ..... @r_r_r
FDIVd 10 ..... 110100 ..... 0 0100 1110 ..... @r_r_r
+FDIVq 10 ..... 110100 ..... 0 0100 1111 ..... @r_r_r
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index a875ca716b..f1bc85c1d7 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1624,19 +1624,6 @@ static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
}
#endif
-static void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2,
- void (*gen)(TCGv_ptr))
-{
- gen_op_load_fpr_QT0(QFPREG(rs1));
- gen_op_load_fpr_QT1(QFPREG(rs2));
-
- gen(tcg_env);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_op_store_QT0_fpr(QFPREG(rd));
- gen_update_fprs_dirty(dc, QFPREG(rd));
-}
-
static void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2,
void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32, TCGv_i32))
{
@@ -5051,6 +5038,31 @@ 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))
+{
+ 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_QT0(QFPREG(a->rs1));
+ gen_op_load_fpr_QT1(QFPREG(a->rs2));
+ func(tcg_env);
+ 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));
+ return advance_pc(dc);
+}
+
+TRANS(FADDq, ALL, do_env_qqq, a, gen_helper_faddq)
+TRANS(FSUBq, ALL, do_env_qqq, a, gen_helper_fsubq)
+TRANS(FMULq, ALL, do_env_qqq, a, gen_helper_fmulq)
+TRANS(FDIVq, ALL, do_env_qqq, a, gen_helper_fdivq)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5112,23 +5124,11 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x46: /* fsubd */
case 0x4a: /* fmuld */
case 0x4e: /* fdivd */
- g_assert_not_reached(); /* in decodetree */
case 0x43: /* faddq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_faddq);
- break;
case 0x47: /* fsubq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fsubq);
- break;
case 0x4b: /* fmulq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fmulq);
- break;
case 0x4f: /* fdivq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fdivq);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x69: /* fsmuld */
CHECK_FPU_FEATURE(dc, FSMULD);
gen_fop_DFF(dc, rd, rs1, rs2, gen_helper_fsmuld);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 76/90] target/sparc: Move FSMULD to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (74 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 75/90] target/sparc: Move gen_fop_QQQ " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 77/90] target/sparc: Move FDMULQ " Richard Henderson
` (14 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 1 +
target/sparc/translate.c | 43 +++++++++++++++++++++------------------
2 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 0f7d898071..96d9139d21 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -253,6 +253,7 @@ FMULq 10 ..... 110100 ..... 0 0100 1011 ..... @r_r_r
FDIVs 10 ..... 110100 ..... 0 0100 1101 ..... @r_r_r
FDIVd 10 ..... 110100 ..... 0 0100 1110 ..... @r_r_r
FDIVq 10 ..... 110100 ..... 0 0100 1111 ..... @r_r_r
+FsMULd 10 ..... 110100 ..... 0 0110 1001 ..... @r_r_r
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index f1bc85c1d7..7f94bb99e0 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1624,22 +1624,6 @@ static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
}
#endif
-static void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2,
- void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32, TCGv_i32))
-{
- TCGv_i64 dst;
- TCGv_i32 src1, src2;
-
- src1 = gen_load_fpr_F(dc, rs1);
- src2 = gen_load_fpr_F(dc, rs2);
- dst = gen_dest_fpr_D(dc, rd);
-
- gen(dst, tcg_env, src1, src2);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_store_fpr_D(dc, rd, dst);
-}
-
static void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2,
void (*gen)(TCGv_ptr, TCGv_i64, TCGv_i64))
{
@@ -5018,6 +5002,28 @@ TRANS(FSUBd, ALL, do_env_ddd, a, gen_helper_fsubd)
TRANS(FMULd, ALL, do_env_ddd, a, gen_helper_fmuld)
TRANS(FDIVd, ALL, do_env_ddd, a, gen_helper_fdivd)
+static bool trans_FsMULd(DisasContext *dc, arg_r_r_r *a)
+{
+ TCGv_i64 dst;
+ TCGv_i32 src1, src2;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if (!(dc->def->features & CPU_FEATURE_FSMULD)) {
+ 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);
+ 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);
+}
+
static bool do_dddd(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
{
@@ -5128,11 +5134,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x47: /* fsubq */
case 0x4b: /* fmulq */
case 0x4f: /* fdivq */
- g_assert_not_reached(); /* in decodetree */
case 0x69: /* fsmuld */
- CHECK_FPU_FEATURE(dc, FSMULD);
- gen_fop_DFF(dc, rd, rs1, rs2, gen_helper_fsmuld);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x6e: /* fdmulq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_QDD(dc, rd, rs1, rs2, gen_helper_fdmulq);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 77/90] target/sparc: Move FDMULQ to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (75 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 76/90] target/sparc: Move FSMULD " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 78/90] target/sparc: Move gen_fop_FD insns " Richard Henderson
` (13 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 1 +
target/sparc/translate.c | 41 +++++++++++++++++++++------------------
2 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 96d9139d21..a98b3b2bdd 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -254,6 +254,7 @@ FDIVs 10 ..... 110100 ..... 0 0100 1101 ..... @r_r_r
FDIVd 10 ..... 110100 ..... 0 0100 1110 ..... @r_r_r
FDIVq 10 ..... 110100 ..... 0 0100 1111 ..... @r_r_r
FsMULd 10 ..... 110100 ..... 0 0110 1001 ..... @r_r_r
+FdMULq 10 ..... 110100 ..... 0 0110 1110 ..... @r_r_r
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 7f94bb99e0..28d63c9915 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1624,21 +1624,6 @@ static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
}
#endif
-static void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2,
- void (*gen)(TCGv_ptr, TCGv_i64, TCGv_i64))
-{
- TCGv_i64 src1, src2;
-
- src1 = gen_load_fpr_D(dc, rs1);
- src2 = gen_load_fpr_D(dc, rs2);
-
- gen(tcg_env, src1, src2);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_op_store_QT0_fpr(QFPREG(rd));
- gen_update_fprs_dirty(dc, QFPREG(rd));
-}
-
#ifdef TARGET_SPARC64
static void gen_fop_DF(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32))
@@ -5069,6 +5054,27 @@ TRANS(FSUBq, ALL, do_env_qqq, a, gen_helper_fsubq)
TRANS(FMULq, ALL, do_env_qqq, a, gen_helper_fmulq)
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;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if (gen_trap_float128(dc)) {
+ 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);
+ gen_helper_fdmulq(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));
+ return advance_pc(dc);
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5135,11 +5141,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x4b: /* fmulq */
case 0x4f: /* fdivq */
case 0x69: /* fsmuld */
- g_assert_not_reached(); /* in decodetree */
case 0x6e: /* fdmulq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_fop_QDD(dc, rd, rs1, rs2, gen_helper_fdmulq);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0xc6: /* fdtos */
gen_fop_FD(dc, rd, rs2, gen_helper_fdtos);
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 78/90] target/sparc: Move gen_fop_FD insns to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (76 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 77/90] target/sparc: Move FDMULQ " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 79/90] target/sparc: Move FiTOd, FsTOd, FsTOx " Richard Henderson
` (12 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Move FdTOs, FdTOi, FxTOs.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 3 +++
target/sparc/translate.c | 51 +++++++++++++++++++++------------------
2 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index a98b3b2bdd..a0af20f042 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -256,9 +256,12 @@ FDIVq 10 ..... 110100 ..... 0 0100 1111 ..... @r_r_r
FsMULd 10 ..... 110100 ..... 0 0110 1001 ..... @r_r_r
FdMULq 10 ..... 110100 ..... 0 0110 1110 ..... @r_r_r
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
+FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
+FdTOs 10 ..... 110100 00000 0 1100 0110 ..... @r_r2
FsTOi 10 ..... 110100 00000 0 1101 0001 ..... @r_r2
+FdTOi 10 ..... 110100 00000 0 1101 0010 ..... @r_r2
{
[
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 28d63c9915..acb9e58319 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -55,6 +55,7 @@
#define gen_helper_restored ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fdtox ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fxtod ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_fxtos ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fnegd(D, S) qemu_build_not_reached()
#define gen_helper_fabsd(D, S) qemu_build_not_reached()
#define gen_helper_done(E) qemu_build_not_reached()
@@ -1655,21 +1656,6 @@ static void gen_ne_fop_DF(DisasContext *dc, int rd, int rs,
gen_store_fpr_D(dc, rd, dst);
}
-static void gen_fop_FD(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i64))
-{
- TCGv_i32 dst;
- TCGv_i64 src;
-
- src = gen_load_fpr_D(dc, rs);
- dst = gen_dest_fpr_F(dc);
-
- gen(dst, tcg_env, src);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_store_fpr_F(dc, rd, dst);
-}
-
static void gen_fop_FQ(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_i32, TCGv_ptr))
{
@@ -4802,6 +4788,29 @@ TRANS(FSQRTs, ALL, do_env_ff, a, gen_helper_fsqrts)
TRANS(FiTOs, ALL, do_env_ff, a, gen_helper_fitos)
TRANS(FsTOi, ALL, do_env_ff, a, gen_helper_fstoi)
+static bool do_env_fd(DisasContext *dc, arg_r_r *a,
+ void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
+{
+ TCGv_i32 dst;
+ TCGv_i64 src;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ gen_op_clear_ieee_excp_and_FTT();
+ dst = gen_dest_fpr_F(dc);
+ 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);
+}
+
+TRANS(FdTOs, ALL, do_env_fd, a, gen_helper_fdtos)
+TRANS(FdTOi, ALL, do_env_fd, a, gen_helper_fdtoi)
+TRANS(FxTOs, 64, do_env_fd, a, gen_helper_fxtos)
+
static bool do_dd(DisasContext *dc, arg_r_r *a,
void (*func)(TCGv_i64, TCGv_i64))
{
@@ -5142,10 +5151,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x4f: /* fdivq */
case 0x69: /* fsmuld */
case 0x6e: /* fdmulq */
- g_assert_not_reached(); /* in decodetree */
case 0xc6: /* fdtos */
- gen_fop_FD(dc, rd, rs2, gen_helper_fdtos);
- break;
+ case 0xd2: /* fdtoi */
+ case 0x84: /* V9 fxtos */
+ g_assert_not_reached(); /* in decodetree */
case 0xc7: /* fqtos */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_FQ(dc, rd, rs2, gen_helper_fqtos);
@@ -5172,9 +5181,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QD(dc, rd, rs2, gen_helper_fdtoq);
break;
- case 0xd2: /* fdtoi */
- gen_fop_FD(dc, rd, rs2, gen_helper_fdtoi);
- break;
case 0xd3: /* fqtoi */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_FQ(dc, rd, rs2, gen_helper_fqtoi);
@@ -5199,9 +5205,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_DQ(dc, rd, rs2, gen_helper_fqtox);
break;
- case 0x84: /* V9 fxtos */
- gen_fop_FD(dc, rd, rs2, gen_helper_fxtos);
- break;
case 0x8c: /* V9 fxtoq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QD(dc, rd, rs2, gen_helper_fxtoq);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 79/90] target/sparc: Move FiTOd, FsTOd, FsTOx to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (77 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 78/90] target/sparc: Move gen_fop_FD insns " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 80/90] target/sparc: Move FqTOs, FqTOi " Richard Henderson
` (11 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Note that gen_ne_fop_DF was incorrectly named and does pass env.
The two sets of helpers should have been unified.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 3 ++
target/sparc/translate.c | 67 ++++++++++++++++-----------------------
2 files changed, 30 insertions(+), 40 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index a0af20f042..1965084fb8 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -255,11 +255,14 @@ FDIVd 10 ..... 110100 ..... 0 0100 1110 ..... @r_r_r
FDIVq 10 ..... 110100 ..... 0 0100 1111 ..... @r_r_r
FsMULd 10 ..... 110100 ..... 0 0110 1001 ..... @r_r_r
FdMULq 10 ..... 110100 ..... 0 0110 1110 ..... @r_r_r
+FsTOx 10 ..... 110100 00000 0 1000 0001 ..... @r_r2
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
FdTOs 10 ..... 110100 00000 0 1100 0110 ..... @r_r2
+FiTOd 10 ..... 110100 00000 0 1100 1000 ..... @r_r2
+FsTOd 10 ..... 110100 00000 0 1100 1001 ..... @r_r2
FsTOi 10 ..... 110100 00000 0 1101 0001 ..... @r_r2
FdTOi 10 ..... 110100 00000 0 1101 0010 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index acb9e58319..395674d901 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -54,6 +54,7 @@
#define gen_helper_saved ({ qemu_build_not_reached(); NULL; })
#define gen_helper_restored ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fdtox ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_fstox ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fxtod ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fxtos ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fnegd(D, S) qemu_build_not_reached()
@@ -1625,37 +1626,6 @@ static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
}
#endif
-#ifdef TARGET_SPARC64
-static void gen_fop_DF(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32))
-{
- TCGv_i64 dst;
- TCGv_i32 src;
-
- src = gen_load_fpr_F(dc, rs);
- dst = gen_dest_fpr_D(dc, rd);
-
- gen(dst, tcg_env, src);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_store_fpr_D(dc, rd, dst);
-}
-#endif
-
-static void gen_ne_fop_DF(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32))
-{
- TCGv_i64 dst;
- TCGv_i32 src;
-
- src = gen_load_fpr_F(dc, rs);
- dst = gen_dest_fpr_D(dc, rd);
-
- gen(dst, tcg_env, src);
-
- gen_store_fpr_D(dc, rd, dst);
-}
-
static void gen_fop_FQ(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_i32, TCGv_ptr))
{
@@ -4855,6 +4825,29 @@ TRANS(FSQRTd, ALL, do_env_dd, a, gen_helper_fsqrtd)
TRANS(FxTOd, 64, do_env_dd, a, gen_helper_fxtod)
TRANS(FdTOx, 64, do_env_dd, a, gen_helper_fdtox)
+static bool do_env_df(DisasContext *dc, arg_r_r *a,
+ void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
+{
+ TCGv_i64 dst;
+ TCGv_i32 src;
+
+ if (gen_trap_ifnofpu(dc)) {
+ 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);
+ gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
+ gen_store_fpr_D(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+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 do_env_qq(DisasContext *dc, arg_r_r *a,
void (*func)(TCGv_env))
{
@@ -5154,17 +5147,14 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0xc6: /* fdtos */
case 0xd2: /* fdtoi */
case 0x84: /* V9 fxtos */
+ case 0xc8: /* fitod */
+ case 0xc9: /* fstod */
+ case 0x81: /* V9 fstox */
g_assert_not_reached(); /* in decodetree */
case 0xc7: /* fqtos */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_FQ(dc, rd, rs2, gen_helper_fqtos);
break;
- case 0xc8: /* fitod */
- gen_ne_fop_DF(dc, rd, rs2, gen_helper_fitod);
- break;
- case 0xc9: /* fstod */
- gen_ne_fop_DF(dc, rd, rs2, gen_helper_fstod);
- break;
case 0xcb: /* fqtod */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_DQ(dc, rd, rs2, gen_helper_fqtod);
@@ -5198,9 +5188,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fabsq);
break;
- case 0x81: /* V9 fstox */
- gen_fop_DF(dc, rd, rs2, gen_helper_fstox);
- break;
case 0x83: /* V9 fqtox */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_DQ(dc, rd, rs2, gen_helper_fqtox);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 80/90] target/sparc: Move FqTOs, FqTOi to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (78 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 79/90] target/sparc: Move FiTOd, FsTOd, FsTOx " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 81/90] target/sparc: Move FqTOd, FqTOx " Richard Henderson
` (10 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 48 +++++++++++++++++++++------------------
2 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 1965084fb8..d890d97f12 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -261,10 +261,12 @@ FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
FdTOs 10 ..... 110100 00000 0 1100 0110 ..... @r_r2
+FqTOs 10 ..... 110100 00000 0 1100 0111 ..... @r_r2
FiTOd 10 ..... 110100 00000 0 1100 1000 ..... @r_r2
FsTOd 10 ..... 110100 00000 0 1100 1001 ..... @r_r2
FsTOi 10 ..... 110100 00000 0 1101 0001 ..... @r_r2
FdTOi 10 ..... 110100 00000 0 1101 0010 ..... @r_r2
+FqTOi 10 ..... 110100 00000 0 1101 0011 ..... @r_r2
{
[
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 395674d901..3d073c8b22 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1626,20 +1626,6 @@ static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
}
#endif
-static void gen_fop_FQ(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_i32, TCGv_ptr))
-{
- TCGv_i32 dst;
-
- gen_op_load_fpr_QT1(QFPREG(rs));
- dst = gen_dest_fpr_F(dc);
-
- gen(dst, tcg_env);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_store_fpr_F(dc, rd, dst);
-}
-
static void gen_fop_DQ(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_i64, TCGv_ptr))
{
@@ -4869,6 +4855,30 @@ 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))
+{
+ TCGv_i32 dst;
+
+ 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));
+ dst = gen_dest_fpr_F(dc);
+ func(dst, tcg_env);
+ gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
+ gen_store_fpr_F(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(FqTOs, ALL, do_env_fq, a, gen_helper_fqtos)
+TRANS(FqTOi, ALL, do_env_fq, a, gen_helper_fqtoi)
+
static bool do_fff(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i32, TCGv_i32, TCGv_i32))
{
@@ -5150,11 +5160,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0xc8: /* fitod */
case 0xc9: /* fstod */
case 0x81: /* V9 fstox */
- g_assert_not_reached(); /* in decodetree */
case 0xc7: /* fqtos */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_fop_FQ(dc, rd, rs2, gen_helper_fqtos);
- break;
+ case 0xd3: /* fqtoi */
+ g_assert_not_reached(); /* in decodetree */
case 0xcb: /* fqtod */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_fop_DQ(dc, rd, rs2, gen_helper_fqtod);
@@ -5171,10 +5179,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QD(dc, rd, rs2, gen_helper_fdtoq);
break;
- case 0xd3: /* fqtoi */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_fop_FQ(dc, rd, rs2, gen_helper_fqtoi);
- break;
#ifdef TARGET_SPARC64
case 0x3: /* V9 fmovq */
CHECK_FPU_FEATURE(dc, FLOAT128);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 81/90] target/sparc: Move FqTOd, FqTOx to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (79 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 80/90] target/sparc: Move FqTOs, FqTOi " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 82/90] target/sparc: Move FiTOq, FsTOq " Richard Henderson
` (9 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 49 +++++++++++++++++++++------------------
2 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index d890d97f12..249f03a075 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -257,6 +257,7 @@ FsMULd 10 ..... 110100 ..... 0 0110 1001 ..... @r_r_r
FdMULq 10 ..... 110100 ..... 0 0110 1110 ..... @r_r_r
FsTOx 10 ..... 110100 00000 0 1000 0001 ..... @r_r2
FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
+FqTOx 10 ..... 110100 00000 0 1000 0011 ..... @r_r2
FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
@@ -264,6 +265,7 @@ FdTOs 10 ..... 110100 00000 0 1100 0110 ..... @r_r2
FqTOs 10 ..... 110100 00000 0 1100 0111 ..... @r_r2
FiTOd 10 ..... 110100 00000 0 1100 1000 ..... @r_r2
FsTOd 10 ..... 110100 00000 0 1100 1001 ..... @r_r2
+FqTOd 10 ..... 110100 00000 0 1100 1011 ..... @r_r2
FsTOi 10 ..... 110100 00000 0 1101 0001 ..... @r_r2
FdTOi 10 ..... 110100 00000 0 1101 0010 ..... @r_r2
FqTOi 10 ..... 110100 00000 0 1101 0011 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 3d073c8b22..a0506a91f0 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -55,6 +55,7 @@
#define gen_helper_restored ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fdtox ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fstox ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_fqtox ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fxtod ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fxtos ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fnegd(D, S) qemu_build_not_reached()
@@ -1626,20 +1627,6 @@ static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
}
#endif
-static void gen_fop_DQ(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_i64, TCGv_ptr))
-{
- TCGv_i64 dst;
-
- gen_op_load_fpr_QT1(QFPREG(rs));
- dst = gen_dest_fpr_D(dc, rd);
-
- gen(dst, tcg_env);
- gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
-
- gen_store_fpr_D(dc, rd, dst);
-}
-
static void gen_ne_fop_QF(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_ptr, TCGv_i32))
{
@@ -4879,6 +4866,30 @@ static bool do_env_fq(DisasContext *dc, arg_r_r *a,
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))
+{
+ TCGv_i64 dst;
+
+ 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));
+ dst = gen_dest_fpr_D(dc, a->rd);
+ func(dst, tcg_env);
+ gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
+ gen_store_fpr_D(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(FqTOd, ALL, do_env_dq, a, gen_helper_fqtod)
+TRANS(FqTOx, 64, do_env_dq, a, gen_helper_fqtox)
+
static bool do_fff(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i32, TCGv_i32, TCGv_i32))
{
@@ -5162,11 +5173,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x81: /* V9 fstox */
case 0xc7: /* fqtos */
case 0xd3: /* fqtoi */
- g_assert_not_reached(); /* in decodetree */
case 0xcb: /* fqtod */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_fop_DQ(dc, rd, rs2, gen_helper_fqtod);
- break;
+ case 0x83: /* V9 fqtox */
+ g_assert_not_reached(); /* in decodetree */
case 0xcc: /* fitoq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QF(dc, rd, rs2, gen_helper_fitoq);
@@ -5192,10 +5201,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fabsq);
break;
- case 0x83: /* V9 fqtox */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_fop_DQ(dc, rd, rs2, gen_helper_fqtox);
- break;
case 0x8c: /* V9 fxtoq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QD(dc, rd, rs2, gen_helper_fxtoq);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 82/90] target/sparc: Move FiTOq, FsTOq to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (80 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 81/90] target/sparc: Move FqTOd, FqTOx " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 83/90] target/sparc: Move FdTOq, FxTOq " Richard Henderson
` (8 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 44 +++++++++++++++++++++------------------
2 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 249f03a075..0b54384af7 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -266,6 +266,8 @@ FqTOs 10 ..... 110100 00000 0 1100 0111 ..... @r_r2
FiTOd 10 ..... 110100 00000 0 1100 1000 ..... @r_r2
FsTOd 10 ..... 110100 00000 0 1100 1001 ..... @r_r2
FqTOd 10 ..... 110100 00000 0 1100 1011 ..... @r_r2
+FiTOq 10 ..... 110100 00000 0 1100 1100 ..... @r_r2
+FsTOq 10 ..... 110100 00000 0 1100 1101 ..... @r_r2
FsTOi 10 ..... 110100 00000 0 1101 0001 ..... @r_r2
FdTOi 10 ..... 110100 00000 0 1101 0010 ..... @r_r2
FqTOi 10 ..... 110100 00000 0 1101 0011 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index a0506a91f0..ecaf1c02bd 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -1627,19 +1627,6 @@ static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
}
#endif
-static void gen_ne_fop_QF(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_ptr, TCGv_i32))
-{
- TCGv_i32 src;
-
- src = gen_load_fpr_F(dc, rs);
-
- gen(tcg_env, src);
-
- gen_op_store_QT0_fpr(QFPREG(rd));
- gen_update_fprs_dirty(dc, QFPREG(rd));
-}
-
static void gen_ne_fop_QD(DisasContext *dc, int rd, int rs,
void (*gen)(TCGv_ptr, TCGv_i64))
{
@@ -4890,6 +4877,29 @@ static bool do_env_dq(DisasContext *dc, arg_r_r *a,
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))
+{
+ TCGv_i32 src;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if (gen_trap_float128(dc)) {
+ return true;
+ }
+
+ 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));
+ return advance_pc(dc);
+}
+
+TRANS(FiTOq, ALL, do_env_qf, a, gen_helper_fitoq)
+TRANS(FsTOq, ALL, do_env_qf, a, gen_helper_fstoq)
+
static bool do_fff(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i32, TCGv_i32, TCGv_i32))
{
@@ -5175,15 +5185,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0xd3: /* fqtoi */
case 0xcb: /* fqtod */
case 0x83: /* V9 fqtox */
- g_assert_not_reached(); /* in decodetree */
case 0xcc: /* fitoq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_ne_fop_QF(dc, rd, rs2, gen_helper_fitoq);
- break;
case 0xcd: /* fstoq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_ne_fop_QF(dc, rd, rs2, gen_helper_fstoq);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0xce: /* fdtoq */
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QD(dc, rd, rs2, gen_helper_fdtoq);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 83/90] target/sparc: Move FdTOq, FxTOq to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (81 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 82/90] target/sparc: Move FiTOq, FsTOq " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 84/90] target/sparc: Move FMOVq, FNEGq, FABSq " Richard Henderson
` (7 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 47 ++++++++++++++++++++++-----------------
2 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 0b54384af7..0bb5b3fca6 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -260,6 +260,7 @@ FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_r2
FqTOx 10 ..... 110100 00000 0 1000 0011 ..... @r_r2
FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_r2
FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @r_r2
+FxTOq 10 ..... 110100 00000 0 1000 1100 ..... @r_r2
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
FdTOs 10 ..... 110100 00000 0 1100 0110 ..... @r_r2
FqTOs 10 ..... 110100 00000 0 1100 0111 ..... @r_r2
@@ -268,6 +269,7 @@ FsTOd 10 ..... 110100 00000 0 1100 1001 ..... @r_r2
FqTOd 10 ..... 110100 00000 0 1100 1011 ..... @r_r2
FiTOq 10 ..... 110100 00000 0 1100 1100 ..... @r_r2
FsTOq 10 ..... 110100 00000 0 1100 1101 ..... @r_r2
+FdTOq 10 ..... 110100 00000 0 1100 1110 ..... @r_r2
FsTOi 10 ..... 110100 00000 0 1101 0001 ..... @r_r2
FdTOi 10 ..... 110100 00000 0 1101 0010 ..... @r_r2
FqTOi 10 ..... 110100 00000 0 1101 0011 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index ecaf1c02bd..86d77c62da 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -58,6 +58,7 @@
#define gen_helper_fqtox ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fxtod ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fxtos ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_fxtoq ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fnegd(D, S) qemu_build_not_reached()
#define gen_helper_fabsd(D, S) qemu_build_not_reached()
#define gen_helper_done(E) qemu_build_not_reached()
@@ -1627,19 +1628,6 @@ static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
}
#endif
-static void gen_ne_fop_QD(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_ptr, TCGv_i64))
-{
- TCGv_i64 src;
-
- src = gen_load_fpr_D(dc, rs);
-
- gen(tcg_env, src);
-
- gen_op_store_QT0_fpr(QFPREG(rd));
- gen_update_fprs_dirty(dc, QFPREG(rd));
-}
-
/* asi moves */
typedef enum {
GET_ASI_HELPER,
@@ -4900,6 +4888,29 @@ static bool do_env_qf(DisasContext *dc, arg_r_r *a,
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))
+{
+ TCGv_i64 src;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if (gen_trap_float128(dc)) {
+ return true;
+ }
+
+ 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));
+ return advance_pc(dc);
+}
+
+TRANS(FdTOq, ALL, do_env_qd, a, gen_helper_fdtoq)
+TRANS(FxTOq, 64, do_env_qd, a, gen_helper_fxtoq)
+
static bool do_fff(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i32, TCGv_i32, TCGv_i32))
{
@@ -5187,11 +5198,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x83: /* V9 fqtox */
case 0xcc: /* fitoq */
case 0xcd: /* fstoq */
- g_assert_not_reached(); /* in decodetree */
case 0xce: /* fdtoq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_ne_fop_QD(dc, rd, rs2, gen_helper_fdtoq);
- break;
+ case 0x8c: /* V9 fxtoq */
+ g_assert_not_reached(); /* in decodetree */
#ifdef TARGET_SPARC64
case 0x3: /* V9 fmovq */
CHECK_FPU_FEATURE(dc, FLOAT128);
@@ -5205,10 +5214,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
CHECK_FPU_FEATURE(dc, FLOAT128);
gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fabsq);
break;
- case 0x8c: /* V9 fxtoq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_ne_fop_QD(dc, rd, rs2, gen_helper_fxtoq);
- break;
#endif
default:
goto illegal_insn;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 84/90] target/sparc: Move FMOVq, FNEGq, FABSq to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (82 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 83/90] target/sparc: Move FdTOq, FxTOq " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 85/90] target/sparc: Move FMOVR, FMOVcc, FMOVfcc " Richard Henderson
` (6 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 3 +
target/sparc/translate.c | 140 +++++++++++++-------------------------
2 files changed, 50 insertions(+), 93 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 0bb5b3fca6..23db453617 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -234,10 +234,13 @@ RETRY 10 00001 111110 00000 0 0000000000000
FMOVs 10 ..... 110100 00000 0 0000 0001 ..... @r_r2
FMOVd 10 ..... 110100 00000 0 0000 0010 ..... @r_r2
+FMOVq 10 ..... 110100 00000 0 0000 0011 ..... @r_r2
FNEGs 10 ..... 110100 00000 0 0000 0101 ..... @r_r2
FNEGd 10 ..... 110100 00000 0 0000 0110 ..... @r_r2
+FNEGq 10 ..... 110100 00000 0 0000 0111 ..... @r_r2
FABSs 10 ..... 110100 00000 0 0000 1001 ..... @r_r2
FABSd 10 ..... 110100 00000 0 0000 1010 ..... @r_r2
+FABSq 10 ..... 110100 00000 0 0000 1011 ..... @r_r2
FSQRTs 10 ..... 110100 00000 0 0010 1001 ..... @r_r2
FSQRTd 10 ..... 110100 00000 0 0010 1010 ..... @r_r2
FSQRTq 10 ..... 110100 00000 0 0010 1011 ..... @r_r2
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 86d77c62da..7baf8f5cff 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -59,6 +59,8 @@
#define gen_helper_fxtod ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fxtos ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fxtoq ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_fabsq ({ qemu_build_not_reached(); NULL; })
+#define gen_helper_fnegq ({ qemu_build_not_reached(); NULL; })
#define gen_helper_fnegd(D, S) qemu_build_not_reached()
#define gen_helper_fabsd(D, S) qemu_build_not_reached()
#define gen_helper_done(E) qemu_build_not_reached()
@@ -271,18 +273,6 @@ static void gen_op_store_QT0_fpr(unsigned int dst)
offsetof(CPU_QuadU, ll.lower));
}
-#ifdef TARGET_SPARC64
-static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
-{
- rd = QFPREG(rd);
- rs = QFPREG(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);
-}
-#endif
-
/* moves */
#ifdef CONFIG_USER_ONLY
#define supervisor(dc) 0
@@ -1615,19 +1605,6 @@ static int gen_trap_ifnofpu(DisasContext *dc)
return 0;
}
-#ifdef TARGET_SPARC64
-static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
- void (*gen)(TCGv_ptr))
-{
- gen_op_load_fpr_QT1(QFPREG(rs));
-
- gen(tcg_env);
-
- gen_op_store_QT0_fpr(QFPREG(rd));
- gen_update_fprs_dirty(dc, QFPREG(rd));
-}
-#endif
-
/* asi moves */
typedef enum {
GET_ASI_HELPER,
@@ -4796,6 +4773,50 @@ 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)
+{
+ int rd, rs;
+
+ if (!avail_64(dc)) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if (gen_trap_float128(dc)) {
+ return true;
+ }
+
+ 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);
+ 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)
+
static bool do_env_qq(DisasContext *dc, arg_r_r *a,
void (*func)(TCGv_env))
{
@@ -5150,74 +5171,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv cpu_dst __attribute__((unused)) = tcg_temp_new();
if (xop == 0x34) { /* FPU Operations */
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- gen_op_clear_ieee_excp_and_FTT();
- rs1 = GET_FIELD(insn, 13, 17);
- rs2 = GET_FIELD(insn, 27, 31);
- xop = GET_FIELD(insn, 18, 26);
-
- switch (xop) {
- case 0x1: /* fmovs */
- case 0x5: /* fnegs */
- case 0x9: /* fabss */
- case 0x2: /* V9 fmovd */
- case 0x6: /* V9 fnegd */
- case 0xa: /* V9 fabsd */
- case 0x29: /* fsqrts */
- case 0xc4: /* fitos */
- case 0xd1: /* fstoi */
- case 0x2a: /* fsqrtd */
- case 0x82: /* V9 fdtox */
- case 0x88: /* V9 fxtod */
- case 0x2b: /* fsqrtq */
- case 0x41: /* fadds */
- case 0x45: /* fsubs */
- case 0x49: /* fmuls */
- case 0x4d: /* fdivs */
- case 0x42: /* faddd */
- case 0x46: /* fsubd */
- case 0x4a: /* fmuld */
- case 0x4e: /* fdivd */
- case 0x43: /* faddq */
- case 0x47: /* fsubq */
- case 0x4b: /* fmulq */
- case 0x4f: /* fdivq */
- case 0x69: /* fsmuld */
- case 0x6e: /* fdmulq */
- case 0xc6: /* fdtos */
- case 0xd2: /* fdtoi */
- case 0x84: /* V9 fxtos */
- case 0xc8: /* fitod */
- case 0xc9: /* fstod */
- case 0x81: /* V9 fstox */
- case 0xc7: /* fqtos */
- case 0xd3: /* fqtoi */
- case 0xcb: /* fqtod */
- case 0x83: /* V9 fqtox */
- case 0xcc: /* fitoq */
- case 0xcd: /* fstoq */
- case 0xce: /* fdtoq */
- case 0x8c: /* V9 fxtoq */
- g_assert_not_reached(); /* in decodetree */
-#ifdef TARGET_SPARC64
- case 0x3: /* V9 fmovq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_move_Q(dc, rd, rs2);
- break;
- case 0x7: /* V9 fnegq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fnegq);
- break;
- case 0xb: /* V9 fabsq */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fabsq);
- break;
-#endif
- default:
- goto illegal_insn;
- }
+ goto illegal_insn; /* in decodetree */
} else if (xop == 0x35) { /* FPU Operations */
#ifdef TARGET_SPARC64
int cond;
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 85/90] target/sparc: Move FMOVR, FMOVcc, FMOVfcc to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (83 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 84/90] target/sparc: Move FMOVq, FNEGq, FABSq " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 86/90] target/sparc: Convert FCMP, FCMPE " Richard Henderson
` (5 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 12 +++
target/sparc/translate.c | 192 ++++++++++++++++----------------------
2 files changed, 91 insertions(+), 113 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 23db453617..88d4b8529d 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -277,6 +277,18 @@ FsTOi 10 ..... 110100 00000 0 1101 0001 ..... @r_r2
FdTOi 10 ..... 110100 00000 0 1101 0010 ..... @r_r2
FqTOi 10 ..... 110100 00000 0 1101 0011 ..... @r_r2
+FMOVscc 10 rd:5 110101 0 cond:4 1 cc:1 0 000001 rs2:5
+FMOVdcc 10 rd:5 110101 0 cond:4 1 cc:1 0 000010 rs2:5
+FMOVqcc 10 rd:5 110101 0 cond:4 1 cc:1 0 000011 rs2:5
+
+FMOVsfcc 10 rd:5 110101 0 cond:4 0 cc:2 000001 rs2:5
+FMOVdfcc 10 rd:5 110101 0 cond:4 0 cc:2 000010 rs2:5
+FMOVqfcc 10 rd:5 110101 0 cond:4 0 cc:2 000011 rs2:5
+
+FMOVRs 10 rd:5 110101 rs1:5 0 cond:3 00101 rs2:5
+FMOVRd 10 rd:5 110101 rs1:5 0 cond:3 00110 rs2:5
+FMOVRq 10 rd:5 110101 rs1:5 0 cond:3 00111 rs2:5
+
{
[
EDGE8cc 10 ..... 110110 ..... 0 0000 0000 ..... @r_r_r
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 7baf8f5cff..84b67ac1a8 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2381,15 +2381,9 @@ static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
}
}
-#ifdef TARGET_SPARC64
-static TCGv get_src1(DisasContext *dc, unsigned int insn)
-{
- unsigned int rs1 = GET_FIELD(insn, 13, 17);
- return gen_load_gpr(dc, rs1);
-}
-
static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
{
+#ifdef TARGET_SPARC64
TCGv_i32 c32, zero, dst, s1, s2;
/* We have two choices here: extend the 32 bit data and use movcond_i64,
@@ -2412,19 +2406,27 @@ static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
tcg_gen_movcond_i32(TCG_COND_NE, dst, c32, zero, s1, s2);
gen_store_fpr_F(dc, rd, dst);
+#else
+ qemu_build_not_reached();
+#endif
}
static void gen_fmovd(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
{
+#ifdef TARGET_SPARC64
TCGv_i64 dst = gen_dest_fpr_D(dc, rd);
tcg_gen_movcond_i64(cmp->cond, dst, cmp->c1, cmp->c2,
gen_load_fpr_D(dc, rs),
gen_load_fpr_D(dc, rd));
gen_store_fpr_D(dc, rd, dst);
+#else
+ qemu_build_not_reached();
+#endif
}
static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
{
+#ifdef TARGET_SPARC64
int qd = QFPREG(rd);
int qs = QFPREG(rs);
@@ -2434,8 +2436,12 @@ static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
cpu_fpr[qs / 2 + 1], cpu_fpr[qd / 2 + 1]);
gen_update_fprs_dirty(dc, qd);
+#else
+ qemu_build_not_reached();
+#endif
}
+#ifdef TARGET_SPARC64
static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr)
{
TCGv_i32 r_tl = tcg_temp_new_i32();
@@ -5140,6 +5146,72 @@ static bool trans_FdMULq(DisasContext *dc, arg_r_r_r *a)
return advance_pc(dc);
}
+static bool do_fmovr(DisasContext *dc, arg_FMOVRs *a, bool is_128,
+ void (*func)(DisasContext *, DisasCompare *, int, int))
+{
+ DisasCompare cmp;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if (is_128 && gen_trap_float128(dc)) {
+ return true;
+ }
+
+ gen_op_clear_ieee_excp_and_FTT();
+ gen_compare_reg(&cmp, a->cond, gen_load_gpr(dc, a->rs1));
+ func(dc, &cmp, a->rd, a->rs2);
+ return advance_pc(dc);
+}
+
+TRANS(FMOVRs, 64, do_fmovr, a, false, gen_fmovs)
+TRANS(FMOVRd, 64, do_fmovr, a, false, gen_fmovd)
+TRANS(FMOVRq, 64, do_fmovr, a, true, gen_fmovq)
+
+static bool do_fmovcc(DisasContext *dc, arg_FMOVscc *a, bool is_128,
+ void (*func)(DisasContext *, DisasCompare *, int, int))
+{
+ DisasCompare cmp;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if (is_128 && gen_trap_float128(dc)) {
+ return true;
+ }
+
+ gen_op_clear_ieee_excp_and_FTT();
+ gen_compare(&cmp, a->cc, a->cond, dc);
+ func(dc, &cmp, a->rd, a->rs2);
+ return advance_pc(dc);
+}
+
+TRANS(FMOVscc, 64, do_fmovcc, a, false, gen_fmovs)
+TRANS(FMOVdcc, 64, do_fmovcc, a, false, gen_fmovd)
+TRANS(FMOVqcc, 64, do_fmovcc, a, true, gen_fmovq)
+
+static bool do_fmovfcc(DisasContext *dc, arg_FMOVsfcc *a, bool is_128,
+ void (*func)(DisasContext *, DisasCompare *, int, int))
+{
+ DisasCompare cmp;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+ if (is_128 && gen_trap_float128(dc)) {
+ return true;
+ }
+
+ gen_op_clear_ieee_excp_and_FTT();
+ gen_fcompare(&cmp, a->cc, a->cond);
+ func(dc, &cmp, a->rd, a->rs2);
+ return advance_pc(dc);
+}
+
+TRANS(FMOVsfcc, 64, do_fmovfcc, a, false, gen_fmovs)
+TRANS(FMOVdfcc, 64, do_fmovfcc, a, false, gen_fmovd)
+TRANS(FMOVqfcc, 64, do_fmovfcc, a, true, gen_fmovq)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5173,9 +5245,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
if (xop == 0x34) { /* FPU Operations */
goto illegal_insn; /* in decodetree */
} else if (xop == 0x35) { /* FPU Operations */
-#ifdef TARGET_SPARC64
- int cond;
-#endif
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
@@ -5184,110 +5253,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
rs2 = GET_FIELD(insn, 27, 31);
xop = GET_FIELD(insn, 18, 26);
-#ifdef TARGET_SPARC64
-#define FMOVR(sz) \
- do { \
- DisasCompare cmp; \
- cond = GET_FIELD_SP(insn, 10, 12); \
- cpu_src1 = get_src1(dc, insn); \
- gen_compare_reg(&cmp, cond, cpu_src1); \
- gen_fmov##sz(dc, &cmp, rd, rs2); \
- } while (0)
-
- if ((xop & 0x11f) == 0x005) { /* V9 fmovsr */
- FMOVR(s);
- break;
- } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
- FMOVR(d);
- break;
- } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
- CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVR(q);
- break;
- }
-#undef FMOVR
-#endif
switch (xop) {
-#ifdef TARGET_SPARC64
-#define FMOVCC(fcc, sz) \
- do { \
- DisasCompare cmp; \
- cond = GET_FIELD_SP(insn, 14, 17); \
- gen_fcompare(&cmp, fcc, cond); \
- gen_fmov##sz(dc, &cmp, rd, rs2); \
- } while (0)
-
- case 0x001: /* V9 fmovscc %fcc0 */
- FMOVCC(0, s);
- break;
- case 0x002: /* V9 fmovdcc %fcc0 */
- FMOVCC(0, d);
- break;
- case 0x003: /* V9 fmovqcc %fcc0 */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVCC(0, q);
- break;
- case 0x041: /* V9 fmovscc %fcc1 */
- FMOVCC(1, s);
- break;
- case 0x042: /* V9 fmovdcc %fcc1 */
- FMOVCC(1, d);
- break;
- case 0x043: /* V9 fmovqcc %fcc1 */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVCC(1, q);
- break;
- case 0x081: /* V9 fmovscc %fcc2 */
- FMOVCC(2, s);
- break;
- case 0x082: /* V9 fmovdcc %fcc2 */
- FMOVCC(2, d);
- break;
- case 0x083: /* V9 fmovqcc %fcc2 */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVCC(2, q);
- break;
- case 0x0c1: /* V9 fmovscc %fcc3 */
- FMOVCC(3, s);
- break;
- case 0x0c2: /* V9 fmovdcc %fcc3 */
- FMOVCC(3, d);
- break;
- case 0x0c3: /* V9 fmovqcc %fcc3 */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVCC(3, q);
- break;
-#undef FMOVCC
-#define FMOVCC(xcc, sz) \
- do { \
- DisasCompare cmp; \
- cond = GET_FIELD_SP(insn, 14, 17); \
- gen_compare(&cmp, xcc, cond, dc); \
- gen_fmov##sz(dc, &cmp, rd, rs2); \
- } while (0)
-
- case 0x101: /* V9 fmovscc %icc */
- FMOVCC(0, s);
- break;
- case 0x102: /* V9 fmovdcc %icc */
- FMOVCC(0, d);
- break;
- case 0x103: /* V9 fmovqcc %icc */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVCC(0, q);
- break;
- case 0x181: /* V9 fmovscc %xcc */
- FMOVCC(1, s);
- break;
- case 0x182: /* V9 fmovdcc %xcc */
- FMOVCC(1, d);
- break;
- case 0x183: /* V9 fmovqcc %xcc */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- FMOVCC(1, q);
- break;
-#undef FMOVCC
-#endif
case 0x51: /* fcmps, V9 %fcc */
cpu_src1_32 = gen_load_fpr_F(dc, rs1);
cpu_src2_32 = gen_load_fpr_F(dc, rs2);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 86/90] target/sparc: Convert FCMP, FCMPE to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (84 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 85/90] target/sparc: Move FMOVR, FMOVcc, FMOVfcc " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 87/90] target/sparc: Move FPCMP* " Richard Henderson
` (4 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 7 ++
target/sparc/translate.c | 145 +++++++++++++++++++++++---------------
2 files changed, 96 insertions(+), 56 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 88d4b8529d..3167797854 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -289,6 +289,13 @@ FMOVRs 10 rd:5 110101 rs1:5 0 cond:3 00101 rs2:5
FMOVRd 10 rd:5 110101 rs1:5 0 cond:3 00110 rs2:5
FMOVRq 10 rd:5 110101 rs1:5 0 cond:3 00111 rs2:5
+FCMPs 10 000 cc:2 110101 rs1:5 0 0101 0001 rs2:5
+FCMPd 10 000 cc:2 110101 rs1:5 0 0101 0010 rs2:5
+FCMPq 10 000 cc:2 110101 rs1:5 0 0101 0011 rs2:5
+FCMPEs 10 000 cc:2 110101 rs1:5 0 0101 0101 rs2:5
+FCMPEd 10 000 cc:2 110101 rs1:5 0 0101 0110 rs2:5
+FCMPEq 10 000 cc:2 110101 rs1:5 0 0101 0111 rs2:5
+
{
[
EDGE8cc 10 ..... 110110 ..... 0 0000 0000 ..... @r_r_r
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 84b67ac1a8..8dd5ef0c92 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -5212,6 +5212,82 @@ TRANS(FMOVsfcc, 64, do_fmovfcc, a, false, gen_fmovs)
TRANS(FMOVdfcc, 64, do_fmovfcc, a, false, gen_fmovd)
TRANS(FMOVqfcc, 64, do_fmovfcc, a, true, gen_fmovq)
+static bool do_fcmps(DisasContext *dc, arg_FCMPs *a, bool e)
+{
+ TCGv_i32 src1, src2;
+
+ if (avail_32(dc) && a->cc != 0) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ 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) {
+ gen_op_fcmpes(a->cc, src1, src2);
+ } else {
+ gen_op_fcmps(a->cc, src1, src2);
+ }
+ return advance_pc(dc);
+}
+
+TRANS(FCMPs, ALL, do_fcmps, a, false)
+TRANS(FCMPEs, ALL, do_fcmps, a, true)
+
+static bool do_fcmpd(DisasContext *dc, arg_FCMPd *a, bool e)
+{
+ TCGv_i64 src1, src2;
+
+ if (avail_32(dc) && a->cc != 0) {
+ return false;
+ }
+ if (gen_trap_ifnofpu(dc)) {
+ 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) {
+ gen_op_fcmped(a->cc, src1, src2);
+ } else {
+ gen_op_fcmpd(a->cc, src1, src2);
+ }
+ return advance_pc(dc);
+}
+
+TRANS(FCMPd, ALL, do_fcmpd, a, false)
+TRANS(FCMPEd, ALL, do_fcmpd, a, true)
+
+static bool do_fcmpq(DisasContext *dc, arg_FCMPq *a, bool e)
+{
+ if (avail_32(dc) && a->cc != 0) {
+ return false;
+ }
+ 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_QT0(QFPREG(a->rs1));
+ gen_op_load_fpr_QT1(QFPREG(a->rs2));
+ if (e) {
+ gen_op_fcmpeq(a->cc);
+ } else {
+ gen_op_fcmpq(a->cc);
+ }
+ return advance_pc(dc);
+}
+
+TRANS(FCMPq, ALL, do_fcmpq, a, false)
+TRANS(FCMPEq, ALL, do_fcmpq, a, true)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -5222,15 +5298,7 @@ TRANS(FMOVqfcc, 64, do_fmovfcc, a, true, gen_fmovq)
/* before an instruction, dc->pc must be static */
static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
{
- unsigned int opc, rs1, rs2, rd;
- TCGv cpu_src1 __attribute__((unused));
- TCGv_i32 cpu_src1_32, cpu_src2_32;
- TCGv_i64 cpu_src1_64, cpu_src2_64;
- TCGv_i32 cpu_dst_32 __attribute__((unused));
- TCGv_i64 cpu_dst_64 __attribute__((unused));
-
- opc = GET_FIELD(insn, 0, 1);
- rd = GET_FIELD(insn, 2, 6);
+ unsigned int opc = GET_FIELD(insn, 0, 1);
switch (opc) {
case 0:
@@ -5240,61 +5308,22 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 2: /* FPU & Logical Operations */
{
unsigned int xop = GET_FIELD(insn, 7, 12);
- TCGv cpu_dst __attribute__((unused)) = tcg_temp_new();
if (xop == 0x34) { /* FPU Operations */
goto illegal_insn; /* in decodetree */
} else if (xop == 0x35) { /* FPU Operations */
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
- gen_op_clear_ieee_excp_and_FTT();
- rs1 = GET_FIELD(insn, 13, 17);
- rs2 = GET_FIELD(insn, 27, 31);
- xop = GET_FIELD(insn, 18, 26);
-
- switch (xop) {
- case 0x51: /* fcmps, V9 %fcc */
- cpu_src1_32 = gen_load_fpr_F(dc, rs1);
- cpu_src2_32 = gen_load_fpr_F(dc, rs2);
- gen_op_fcmps(rd & 3, cpu_src1_32, cpu_src2_32);
- break;
- case 0x52: /* fcmpd, V9 %fcc */
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_op_fcmpd(rd & 3, cpu_src1_64, cpu_src2_64);
- break;
- case 0x53: /* fcmpq, V9 %fcc */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_op_load_fpr_QT0(QFPREG(rs1));
- gen_op_load_fpr_QT1(QFPREG(rs2));
- gen_op_fcmpq(rd & 3);
- break;
- case 0x55: /* fcmpes, V9 %fcc */
- cpu_src1_32 = gen_load_fpr_F(dc, rs1);
- cpu_src2_32 = gen_load_fpr_F(dc, rs2);
- gen_op_fcmpes(rd & 3, cpu_src1_32, cpu_src2_32);
- break;
- case 0x56: /* fcmped, V9 %fcc */
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_op_fcmped(rd & 3, cpu_src1_64, cpu_src2_64);
- break;
- case 0x57: /* fcmpeq, V9 %fcc */
- CHECK_FPU_FEATURE(dc, FLOAT128);
- gen_op_load_fpr_QT0(QFPREG(rs1));
- gen_op_load_fpr_QT1(QFPREG(rs2));
- gen_op_fcmpeq(rd & 3);
- break;
- default:
- goto illegal_insn;
- }
+ goto illegal_insn; /* in decodetree */
} else if (xop == 0x36) {
#ifdef TARGET_SPARC64
/* VIS */
+ TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
+ TCGv_i32 cpu_dst_32;
+ TCGv cpu_dst = tcg_temp_new();
int opf = GET_FIELD_SP(insn, 5, 13);
- rs1 = GET_FIELD(insn, 13, 17);
- rs2 = GET_FIELD(insn, 27, 31);
+ int rs1 = GET_FIELD(insn, 13, 17);
+ int rs2 = GET_FIELD(insn, 27, 31);
+ int rd = GET_FIELD(insn, 2, 6);
+
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
@@ -5479,14 +5508,18 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
goto illegal_insn; /* in decodetree */
}
advance_pc(dc);
+#ifdef TARGET_SPARC64
jmp_insn:
+#endif
return;
illegal_insn:
gen_exception(dc, TT_ILL_INSN);
return;
+#ifdef TARGET_SPARC64
nfpu_insn:
gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
return;
+#endif
}
static void sparc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 87/90] target/sparc: Move FPCMP* to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (85 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 86/90] target/sparc: Convert FCMP, FCMPE " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 88/90] target/sparc: Move FPACK16, FPACKFIX " Richard Henderson
` (3 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 9 ++++
target/sparc/translate.c | 94 +++++++++++++++++----------------------
2 files changed, 50 insertions(+), 53 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 3167797854..0a0c5b2505 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -320,6 +320,15 @@ FCMPEq 10 000 cc:2 110101 rs1:5 0 0101 0111 rs2:5
BMASK 10 ..... 110110 ..... 0 0001 1001 ..... @r_r_r
+ FPCMPLE16 10 ..... 110110 ..... 0 0010 0000 ..... @r_r_r
+ FPCMPNE16 10 ..... 110110 ..... 0 0010 0010 ..... @r_r_r
+ FPCMPGT16 10 ..... 110110 ..... 0 0010 1000 ..... @r_r_r
+ FPCMPEQ16 10 ..... 110110 ..... 0 0010 1010 ..... @r_r_r
+ FPCMPLE32 10 ..... 110110 ..... 0 0010 0100 ..... @r_r_r
+ FPCMPNE32 10 ..... 110110 ..... 0 0010 0110 ..... @r_r_r
+ FPCMPGT32 10 ..... 110110 ..... 0 0010 1100 ..... @r_r_r
+ FPCMPEQ32 10 ..... 110110 ..... 0 0010 1110 ..... @r_r_r
+
FMUL8x16 10 ..... 110110 ..... 0 0011 0001 ..... @r_r_r
FMUL8x16AU 10 ..... 110110 ..... 0 0011 0011 ..... @r_r_r
FMUL8x16AL 10 ..... 110110 ..... 0 0011 0101 ..... @r_r_r
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 8dd5ef0c92..01063afa30 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -77,7 +77,14 @@
#define gen_helper_fpmerge ({ g_assert_not_reached(); NULL; })
#define gen_helper_fexpand ({ g_assert_not_reached(); NULL; })
#define gen_helper_pdist ({ g_assert_not_reached(); NULL; })
-#define gen_helper_fsqrtq ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fcmpeq16 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fcmpne16 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fcmple16 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fcmpgt16 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fcmpeq32 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fcmpne32 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fcmple32 ({ g_assert_not_reached(); NULL; })
+#define gen_helper_fcmpgt32 ({ g_assert_not_reached(); NULL; })
#define FSR_LDXFSR_MASK ({ qemu_build_not_reached(); 0; })
#define FSR_LDXFSR_OLDMASK ({ qemu_build_not_reached(); 0; })
# ifdef CONFIG_USER_ONLY
@@ -5034,6 +5041,37 @@ TRANS(FPACK32, VIS1, do_ddd, a, gen_op_fpack32)
TRANS(FALIGNDATAg, VIS1, do_ddd, a, gen_op_faligndata)
TRANS(BSHUFFLE, VIS2, do_ddd, a, gen_op_bshuffle)
+static bool do_rdd(DisasContext *dc, arg_r_r_r *a,
+ void (*func)(TCGv_i64, TCGv_i64, TCGv_i64))
+{
+#ifdef TARGET_SPARC64
+ TCGv_i64 dst, src1, src2;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ dst = gen_dest_gpr(dc, a->rd);
+ src1 = gen_load_fpr_D(dc, a->rs1);
+ src2 = gen_load_fpr_D(dc, a->rs2);
+ func(dst, src1, src2);
+ gen_store_gpr(dc, a->rd, dst);
+ return advance_pc(dc);
+#else
+ g_assert_not_reached();
+#endif
+}
+
+TRANS(FPCMPLE16, VIS1, do_rdd, a, gen_helper_fcmple16)
+TRANS(FPCMPNE16, VIS1, do_rdd, a, gen_helper_fcmpne16)
+TRANS(FPCMPGT16, VIS1, do_rdd, a, gen_helper_fcmpgt16)
+TRANS(FPCMPEQ16, VIS1, do_rdd, a, gen_helper_fcmpeq16)
+
+TRANS(FPCMPLE32, VIS1, do_rdd, a, gen_helper_fcmple32)
+TRANS(FPCMPNE32, VIS1, do_rdd, a, gen_helper_fcmpne32)
+TRANS(FPCMPGT32, VIS1, do_rdd, a, gen_helper_fcmpgt32)
+TRANS(FPCMPEQ32, VIS1, do_rdd, a, gen_helper_fcmpeq32)
+
static bool do_env_ddd(DisasContext *dc, arg_r_r_r *a,
void (*func)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64))
{
@@ -5316,11 +5354,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
} else if (xop == 0x36) {
#ifdef TARGET_SPARC64
/* VIS */
- TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
+ TCGv_i64 cpu_src1_64, cpu_dst_64;
TCGv_i32 cpu_dst_32;
- TCGv cpu_dst = tcg_temp_new();
int opf = GET_FIELD_SP(insn, 5, 13);
- int rs1 = GET_FIELD(insn, 13, 17);
int rs2 = GET_FIELD(insn, 27, 31);
int rd = GET_FIELD(insn, 2, 6);
@@ -5396,63 +5432,15 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x03a: /* VIS I fpack32 */
case 0x048: /* VIS I faligndata */
case 0x04c: /* VIS II bshuffle */
- g_assert_not_reached(); /* in decodetree */
case 0x020: /* VIS I fcmple16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_helper_fcmple16(cpu_dst, cpu_src1_64, cpu_src2_64);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x022: /* VIS I fcmpne16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_helper_fcmpne16(cpu_dst, cpu_src1_64, cpu_src2_64);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x024: /* VIS I fcmple32 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_helper_fcmple32(cpu_dst, cpu_src1_64, cpu_src2_64);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x026: /* VIS I fcmpne32 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_helper_fcmpne32(cpu_dst, cpu_src1_64, cpu_src2_64);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x028: /* VIS I fcmpgt16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_helper_fcmpgt16(cpu_dst, cpu_src1_64, cpu_src2_64);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x02a: /* VIS I fcmpeq16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_helper_fcmpeq16(cpu_dst, cpu_src1_64, cpu_src2_64);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x02c: /* VIS I fcmpgt32 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_helper_fcmpgt32(cpu_dst, cpu_src1_64, cpu_src2_64);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
case 0x02e: /* VIS I fcmpeq32 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs1);
- cpu_src2_64 = gen_load_fpr_D(dc, rs2);
- gen_helper_fcmpeq32(cpu_dst, cpu_src1_64, cpu_src2_64);
- gen_store_gpr(dc, rd, cpu_dst);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x03b: /* VIS I fpack16 */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_src1_64 = gen_load_fpr_D(dc, rs2);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 88/90] target/sparc: Move FPACK16, FPACKFIX to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (86 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 87/90] target/sparc: Move FPCMP* " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 89/90] target/sparc: Convert FZERO, FONE " Richard Henderson
` (2 subsequent siblings)
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 55 ++++++++++++++++++++++++++++-----------
2 files changed, 42 insertions(+), 15 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index 0a0c5b2505..c9fe45adff 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -337,6 +337,8 @@ FCMPEq 10 000 cc:2 110101 rs1:5 0 0101 0111 rs2:5
FMULD8SUx16 10 ..... 110110 ..... 0 0011 1000 ..... @r_r_r
FMULD8ULx16 10 ..... 110110 ..... 0 0011 1001 ..... @r_r_r
FPACK32 10 ..... 110110 ..... 0 0011 1010 ..... @r_r_r
+ FPACK16 10 ..... 110110 00000 0 0011 1011 ..... @r_r2
+ FPACKFIX 10 ..... 110110 00000 0 0011 1101 ..... @r_r2
PDIST 10 ..... 110110 ..... 0 0011 1110 ..... @r_r_r
FALIGNDATAg 10 ..... 110110 ..... 0 0100 1000 ..... @r_r_r
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 01063afa30..bee9212ba2 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -710,6 +710,24 @@ static void gen_op_array32(TCGv dst, TCGv src1, TCGv src2)
tcg_gen_shli_tl(dst, dst, 2);
}
+static void gen_op_fpack16(TCGv_i32 dst, TCGv_i64 src)
+{
+#ifdef TARGET_SPARC64
+ gen_helper_fpack16(dst, cpu_gsr, src);
+#else
+ g_assert_not_reached();
+#endif
+}
+
+static void gen_op_fpackfix(TCGv_i32 dst, TCGv_i64 src)
+{
+#ifdef TARGET_SPARC64
+ gen_helper_fpackfix(dst, cpu_gsr, src);
+#else
+ g_assert_not_reached();
+#endif
+}
+
static void gen_op_fpack32(TCGv_i64 dst, TCGv_i64 src1, TCGv_i64 src2)
{
#ifdef TARGET_SPARC64
@@ -4675,6 +4693,26 @@ TRANS(FABSs, ALL, do_ff, a, gen_op_fabss)
TRANS(FSRCs, VIS1, do_ff, a, tcg_gen_mov_i32)
TRANS(FNOTs, VIS1, do_ff, a, tcg_gen_not_i32)
+static bool do_fd(DisasContext *dc, arg_r_r *a,
+ void (*func)(TCGv_i32, TCGv_i64))
+{
+ TCGv_i32 dst;
+ TCGv_i64 src;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ dst = gen_dest_fpr_F(dc);
+ src = gen_load_fpr_D(dc, a->rs);
+ func(dst, src);
+ gen_store_fpr_F(dc, a->rd, dst);
+ return advance_pc(dc);
+}
+
+TRANS(FPACK16, VIS1, do_fd, a, gen_op_fpack16)
+TRANS(FPACKFIX, VIS1, do_fd, a, gen_op_fpackfix)
+
static bool do_env_ff(DisasContext *dc, arg_r_r *a,
void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
{
@@ -5354,10 +5392,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
} else if (xop == 0x36) {
#ifdef TARGET_SPARC64
/* VIS */
- TCGv_i64 cpu_src1_64, cpu_dst_64;
+ TCGv_i64 cpu_dst_64;
TCGv_i32 cpu_dst_32;
int opf = GET_FIELD_SP(insn, 5, 13);
- int rs2 = GET_FIELD(insn, 27, 31);
int rd = GET_FIELD(insn, 2, 6);
if (gen_trap_ifnofpu(dc)) {
@@ -5440,21 +5477,9 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x02a: /* VIS I fcmpeq16 */
case 0x02c: /* VIS I fcmpgt32 */
case 0x02e: /* VIS I fcmpeq32 */
- g_assert_not_reached(); /* in decodetree */
case 0x03b: /* VIS I fpack16 */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs2);
- cpu_dst_32 = gen_dest_fpr_F(dc);
- gen_helper_fpack16(cpu_dst_32, cpu_gsr, cpu_src1_64);
- gen_store_fpr_F(dc, rd, cpu_dst_32);
- break;
case 0x03d: /* VIS I fpackfix */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_src1_64 = gen_load_fpr_D(dc, rs2);
- cpu_dst_32 = gen_dest_fpr_F(dc);
- gen_helper_fpackfix(cpu_dst_32, cpu_gsr, cpu_src1_64);
- gen_store_fpr_F(dc, rd, cpu_dst_32);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x060: /* VIS I fzero */
CHECK_FPU_FEATURE(dc, VIS1);
cpu_dst_64 = gen_dest_fpr_D(dc, rd);
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 89/90] target/sparc: Convert FZERO, FONE to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (87 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 88/90] target/sparc: Move FPACK16, FPACKFIX " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 6:12 ` [PATCH v2 90/90] target/sparc: Remove disas_sparc_legacy Richard Henderson
2023-10-17 21:17 ` [PATCH v2 00/90] target/sparc: Convert to decodetree Mark Cave-Ayland
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/insns.decode | 5 +++
target/sparc/translate.c | 69 +++++++++++++++++++++++----------------
2 files changed, 45 insertions(+), 29 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
index c9fe45adff..22d7e7fc09 100644
--- a/target/sparc/insns.decode
+++ b/target/sparc/insns.decode
@@ -384,6 +384,11 @@ FCMPEq 10 000 cc:2 110101 rs1:5 0 0101 0111 rs2:5
FORNOTs 10 ..... 110110 ..... 0 0111 1011 ..... @r_r_r_swap # ... 1s
FORd 10 ..... 110110 ..... 0 0111 1100 ..... @r_r_r
FORs 10 ..... 110110 ..... 0 0111 1101 ..... @r_r_r
+
+ FZEROd 10 rd:5 110110 00000 0 0110 0000 00000
+ FZEROs 10 rd:5 110110 00000 0 0110 0001 00000
+ FONEd 10 rd:5 110110 00000 0 0111 1110 00000
+ FONEs 10 rd:5 110110 00000 0 0111 1111 00000
]
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
}
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index bee9212ba2..ba41cfda3d 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4672,6 +4672,45 @@ static bool do_stfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop)
TRANS(STFSR, ALL, do_stfsr, a, MO_TEUL)
TRANS(STXFSR, 64, do_stfsr, a, MO_TEUQ)
+static bool do_fc(DisasContext *dc, int rd, bool c)
+{
+ uint64_t mask;
+
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ if (rd & 1) {
+ mask = MAKE_64BIT_MASK(0, 32);
+ } else {
+ mask = MAKE_64BIT_MASK(32, 32);
+ }
+ if (c) {
+ tcg_gen_ori_i64(cpu_fpr[rd / 2], cpu_fpr[rd / 2], mask);
+ } else {
+ tcg_gen_andi_i64(cpu_fpr[rd / 2], cpu_fpr[rd / 2], ~mask);
+ }
+ gen_update_fprs_dirty(dc, rd);
+ return advance_pc(dc);
+}
+
+TRANS(FZEROs, VIS1, do_fc, a->rd, 0)
+TRANS(FONEs, VIS1, do_fc, a->rd, 1)
+
+static bool do_dc(DisasContext *dc, int rd, int64_t c)
+{
+ if (gen_trap_ifnofpu(dc)) {
+ return true;
+ }
+
+ tcg_gen_movi_i64(cpu_fpr[rd / 2], c);
+ gen_update_fprs_dirty(dc, rd);
+ return advance_pc(dc);
+}
+
+TRANS(FZEROd, VIS1, do_dc, a->rd, 0)
+TRANS(FONEd, VIS1, do_dc, a->rd, -1)
+
static bool do_ff(DisasContext *dc, arg_r_r *a,
void (*func)(TCGv_i32, TCGv_i32))
{
@@ -5392,10 +5431,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
} else if (xop == 0x36) {
#ifdef TARGET_SPARC64
/* VIS */
- TCGv_i64 cpu_dst_64;
- TCGv_i32 cpu_dst_32;
int opf = GET_FIELD_SP(insn, 5, 13);
- int rd = GET_FIELD(insn, 2, 6);
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
@@ -5479,31 +5515,11 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x02e: /* VIS I fcmpeq32 */
case 0x03b: /* VIS I fpack16 */
case 0x03d: /* VIS I fpackfix */
- g_assert_not_reached(); /* in decodetree */
case 0x060: /* VIS I fzero */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_dst_64 = gen_dest_fpr_D(dc, rd);
- tcg_gen_movi_i64(cpu_dst_64, 0);
- gen_store_fpr_D(dc, rd, cpu_dst_64);
- break;
case 0x061: /* VIS I fzeros */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_dst_32 = gen_dest_fpr_F(dc);
- tcg_gen_movi_i32(cpu_dst_32, 0);
- gen_store_fpr_F(dc, rd, cpu_dst_32);
- break;
case 0x07e: /* VIS I fone */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_dst_64 = gen_dest_fpr_D(dc, rd);
- tcg_gen_movi_i64(cpu_dst_64, -1);
- gen_store_fpr_D(dc, rd, cpu_dst_64);
- break;
case 0x07f: /* VIS I fones */
- CHECK_FPU_FEATURE(dc, VIS1);
- cpu_dst_32 = gen_dest_fpr_F(dc);
- tcg_gen_movi_i32(cpu_dst_32, -1);
- gen_store_fpr_F(dc, rd, cpu_dst_32);
- break;
+ g_assert_not_reached(); /* in decodetree */
case 0x080: /* VIS I shutdown */
case 0x081: /* VIS II siam */
// XXX
@@ -5528,11 +5544,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
illegal_insn:
gen_exception(dc, TT_ILL_INSN);
return;
-#ifdef TARGET_SPARC64
- nfpu_insn:
- gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
- return;
-#endif
}
static void sparc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* [PATCH v2 90/90] target/sparc: Remove disas_sparc_legacy
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (88 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 89/90] target/sparc: Convert FZERO, FONE " Richard Henderson
@ 2023-10-17 6:12 ` Richard Henderson
2023-10-17 21:17 ` [PATCH v2 00/90] target/sparc: Convert to decodetree Mark Cave-Ayland
90 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2023-10-17 6:12 UTC (permalink / raw)
To: qemu-devel; +Cc: mark.cave-ayland
All instructions are now converted.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 145 +--------------------------------------
1 file changed, 1 insertion(+), 144 deletions(-)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index ba41cfda3d..c458de2103 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -5403,149 +5403,6 @@ static bool do_fcmpq(DisasContext *dc, arg_FCMPq *a, bool e)
TRANS(FCMPq, ALL, do_fcmpq, a, false)
TRANS(FCMPEq, ALL, do_fcmpq, a, true)
-#define CHECK_IU_FEATURE(dc, FEATURE) \
- if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
- goto illegal_insn;
-#define CHECK_FPU_FEATURE(dc, FEATURE) \
- if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
- goto nfpu_insn;
-
-/* before an instruction, dc->pc must be static */
-static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
-{
- unsigned int opc = GET_FIELD(insn, 0, 1);
-
- switch (opc) {
- case 0:
- goto illegal_insn; /* in decodetree */
- case 1:
- g_assert_not_reached(); /* in decodetree */
- case 2: /* FPU & Logical Operations */
- {
- unsigned int xop = GET_FIELD(insn, 7, 12);
-
- if (xop == 0x34) { /* FPU Operations */
- goto illegal_insn; /* in decodetree */
- } else if (xop == 0x35) { /* FPU Operations */
- goto illegal_insn; /* in decodetree */
- } else if (xop == 0x36) {
-#ifdef TARGET_SPARC64
- /* VIS */
- int opf = GET_FIELD_SP(insn, 5, 13);
-
- if (gen_trap_ifnofpu(dc)) {
- goto jmp_insn;
- }
-
- switch (opf) {
- case 0x000: /* VIS I edge8cc */
- case 0x001: /* VIS II edge8n */
- case 0x002: /* VIS I edge8lcc */
- case 0x003: /* VIS II edge8ln */
- case 0x004: /* VIS I edge16cc */
- case 0x005: /* VIS II edge16n */
- case 0x006: /* VIS I edge16lcc */
- case 0x007: /* VIS II edge16ln */
- case 0x008: /* VIS I edge32cc */
- case 0x009: /* VIS II edge32n */
- case 0x00a: /* VIS I edge32lcc */
- case 0x00b: /* VIS II edge32ln */
- case 0x010: /* VIS I array8 */
- case 0x012: /* VIS I array16 */
- case 0x014: /* VIS I array32 */
- case 0x018: /* VIS I alignaddr */
- case 0x01a: /* VIS I alignaddrl */
- case 0x019: /* VIS II bmask */
- case 0x067: /* VIS I fnot2s */
- case 0x06b: /* VIS I fnot1s */
- case 0x075: /* VIS I fsrc1s */
- case 0x079: /* VIS I fsrc2s */
- case 0x066: /* VIS I fnot2 */
- case 0x06a: /* VIS I fnot1 */
- case 0x074: /* VIS I fsrc1 */
- case 0x078: /* VIS I fsrc2 */
- case 0x051: /* VIS I fpadd16s */
- case 0x053: /* VIS I fpadd32s */
- case 0x055: /* VIS I fpsub16s */
- case 0x057: /* VIS I fpsub32s */
- case 0x063: /* VIS I fnors */
- case 0x065: /* VIS I fandnot2s */
- case 0x069: /* VIS I fandnot1s */
- case 0x06d: /* VIS I fxors */
- case 0x06f: /* VIS I fnands */
- case 0x071: /* VIS I fands */
- case 0x073: /* VIS I fxnors */
- case 0x077: /* VIS I fornot2s */
- case 0x07b: /* VIS I fornot1s */
- case 0x07d: /* VIS I fors */
- case 0x050: /* VIS I fpadd16 */
- case 0x052: /* VIS I fpadd32 */
- case 0x054: /* VIS I fpsub16 */
- case 0x056: /* VIS I fpsub32 */
- case 0x062: /* VIS I fnor */
- case 0x064: /* VIS I fandnot2 */
- case 0x068: /* VIS I fandnot1 */
- case 0x06c: /* VIS I fxor */
- case 0x06e: /* VIS I fnand */
- case 0x070: /* VIS I fand */
- case 0x072: /* VIS I fxnor */
- case 0x076: /* VIS I fornot2 */
- case 0x07a: /* VIS I fornot1 */
- case 0x07c: /* VIS I for */
- case 0x031: /* VIS I fmul8x16 */
- case 0x033: /* VIS I fmul8x16au */
- case 0x035: /* VIS I fmul8x16al */
- case 0x036: /* VIS I fmul8sux16 */
- case 0x037: /* VIS I fmul8ulx16 */
- case 0x038: /* VIS I fmuld8sux16 */
- case 0x039: /* VIS I fmuld8ulx16 */
- case 0x04b: /* VIS I fpmerge */
- case 0x04d: /* VIS I fexpand */
- case 0x03e: /* VIS I pdist */
- case 0x03a: /* VIS I fpack32 */
- case 0x048: /* VIS I faligndata */
- case 0x04c: /* VIS II bshuffle */
- case 0x020: /* VIS I fcmple16 */
- case 0x022: /* VIS I fcmpne16 */
- case 0x024: /* VIS I fcmple32 */
- case 0x026: /* VIS I fcmpne32 */
- case 0x028: /* VIS I fcmpgt16 */
- case 0x02a: /* VIS I fcmpeq16 */
- case 0x02c: /* VIS I fcmpgt32 */
- case 0x02e: /* VIS I fcmpeq32 */
- case 0x03b: /* VIS I fpack16 */
- case 0x03d: /* VIS I fpackfix */
- case 0x060: /* VIS I fzero */
- case 0x061: /* VIS I fzeros */
- case 0x07e: /* VIS I fone */
- case 0x07f: /* VIS I fones */
- g_assert_not_reached(); /* in decodetree */
- case 0x080: /* VIS I shutdown */
- case 0x081: /* VIS II siam */
- // XXX
- goto illegal_insn;
- default:
- goto illegal_insn;
- }
-#endif
- } else {
- goto illegal_insn; /* in decodetree */
- }
- }
- break;
- case 3: /* load/store instructions */
- goto illegal_insn; /* in decodetree */
- }
- advance_pc(dc);
-#ifdef TARGET_SPARC64
- jmp_insn:
-#endif
- return;
- illegal_insn:
- gen_exception(dc, TT_ILL_INSN);
- return;
-}
-
static void sparc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
@@ -5613,7 +5470,7 @@ static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
dc->base.pc_next += 4;
if (!decode(dc, insn)) {
- disas_sparc_legacy(dc, insn);
+ gen_exception(dc, TT_ILL_INSN);
}
if (dc->base.is_jmp == DISAS_NORETURN) {
--
2.34.1
^ permalink raw reply related [flat|nested] 92+ messages in thread
* Re: [PATCH v2 00/90] target/sparc: Convert to decodetree
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
` (89 preceding siblings ...)
2023-10-17 6:12 ` [PATCH v2 90/90] target/sparc: Remove disas_sparc_legacy Richard Henderson
@ 2023-10-17 21:17 ` Mark Cave-Ayland
90 siblings, 0 replies; 92+ messages in thread
From: Mark Cave-Ayland @ 2023-10-17 21:17 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 17/10/2023 07:11, Richard Henderson wrote:
> While doing some other testing the other day, I noticed my sparc64
> chroot running particularly slowly. I think I know what the problem
> is there, but fixing that was going to be particularly ugly with the
> existing sparc translator.
>
> So I've converted the translator to something more managable. :-)
>
> Changes for v2:
> * Fixes for JMPL, RETT, SAVE and RESTORE.
> * Fixes for FMOV etc, which had lost gen_op_clear_ieee_excp_and_FTT.
> * Allow conditional exceptions to be raised out of line
> Use this for gen_check_align and conditional trap.
> * Keep properties and feature bits in sync.
>
> r~
>
> Richard Henderson (90):
> target/sparc: Clear may_lookup for npc == DYNAMIC_PC
> target/sparc: Implement check_align inline
> target/sparc: Avoid helper_raise_exception in helper_st_asi
> target/sparc: Set TCG_GUEST_DEFAULT_MO
> configs: Enable MTTCG for sparc, sparc64
> target/sparc: Define features via cpu-feature.h.inc
> target/sparc: Use CPU_FEATURE_BIT_* for cpu properties
> target/sparc: Remove sparcv7 cpu features
> target/sparc: Add decodetree infrastructure
> target/sparc: Define AM_CHECK for sparc32
> target/sparc: Move CALL to decodetree
> target/sparc: Move BPcc and Bicc to decodetree
> target/sparc: Move BPr to decodetree
> target/sparc: Move FBPfcc and FBfcc to decodetree
> target/sparc: Merge gen_cond with only caller
> target/sparc: Merge gen_fcond with only caller
> target/sparc: Merge gen_branch_[an] with only caller
> target/sparc: Pass DisasCompare to advance_jump_cond
> target/sparc: Move SETHI to decodetree
> target/sparc: Move Tcc to decodetree
> target/sparc: Move RDASR, STBAR, MEMBAR to decodetree
> target/sparc: Move RDPSR, RDHPR to decodetree
> target/sparc: Move RDWIM, RDPR to decodetree
> target/sparc: Move RDTBR, FLUSHW to decodetree
> target/sparc: Move WRASR to decodetree
> target/sparc: Move WRPSR, SAVED, RESTORED to decodetree
> target/sparc: Move WRWIM, WRPR to decodetree
> target/sparc: Move WRTBR, WRHPR to decodetree
> target/sparc: Move basic arithmetic to decodetree
> target/sparc: Move ADDC to decodetree
> target/sparc: Move MULX to decodetree
> target/sparc: Move UMUL, SMUL to decodetree
> target/sparc: Move SUBC to decodetree
> target/sparc: Move UDIVX, SDIVX to decodetree
> target/sparc: Move UDIV, SDIV to decodetree
> target/sparc: Move TADD, TSUB, MULS to decodetree
> target/sparc: Move SLL, SRL, SRA to decodetree
> target/sparc: Move MOVcc, MOVR to decodetree
> target/sparc: Move POPC to decodetree
> target/sparc: Convert remaining v8 coproc insns to decodetree
> target/sparc: Move JMPL, RETT, RETURN to decodetree
> target/sparc: Move FLUSH, SAVE, RESTORE to decodetree
> target/sparc: Move DONE, RETRY to decodetree
> target/sparc: Split out resolve_asi
> target/sparc: Drop ifdef around get_asi and friends
> target/sparc: Split out ldst functions with asi pre-computed
> target/sparc: Use tcg_gen_qemu_{ld,st}_i128 for GET_ASI_DTWINX
> target/sparc: Move simple integer load/store to decodetree
> target/sparc: Move asi integer load/store to decodetree
> target/sparc: Move LDSTUB, LDSTUBA to decodetree
> target/sparc: Move SWAP, SWAPA to decodetree
> target/sparc: Move CASA, CASXA to decodetree
> target/sparc: Move PREFETCH, PREFETCHA to decodetree
> target/sparc: Split out fp ldst functions with asi precomputed
> target/sparc: Move simple fp load/store to decodetree
> target/sparc: Move asi fp load/store to decodetree
> target/sparc: Move LDFSR, STFSR to decodetree
> target/sparc: Merge LDFSR, LDXFSR implementations
> target/sparc: Move EDGE* to decodetree
> target/sparc: Move ARRAY* to decodetree
> target/sparc: Move ADDRALIGN* to decodetree
> target/sparc: Move BMASK to decodetree
> target/sparc: Move FMOVS, FNEGS, FABSS, FSRC*S, FNOT*S to decodetree
> target/sparc: Move FMOVD, FNEGD, FABSD, FSRC*D, FNOT*D to decodetree
> target/sparc: Use tcg_gen_vec_{add,sub}*
> target/sparc: Move gen_ne_fop_FFF insns to decodetree
> target/sparc: Move gen_ne_fop_DDD insns to decodetree
> target/sparc: Move PDIST to decodetree
> target/sparc: Move gen_gsr_fop_DDD insns to decodetree
> target/sparc: Move gen_fop_FF insns to decodetree
> target/sparc: Move gen_fop_DD insns to decodetree
> target/sparc: Move FSQRTq to decodetree
> target/sparc: Move gen_fop_FFF insns to decodetree
> target/sparc: Move gen_fop_DDD insns to decodetree
> target/sparc: Move gen_fop_QQQ insns to decodetree
> target/sparc: Move FSMULD to decodetree
> target/sparc: Move FDMULQ to decodetree
> target/sparc: Move gen_fop_FD insns to decodetree
> target/sparc: Move FiTOd, FsTOd, FsTOx to decodetree
> target/sparc: Move FqTOs, FqTOi to decodetree
> target/sparc: Move FqTOd, FqTOx to decodetree
> target/sparc: Move FiTOq, FsTOq to decodetree
> target/sparc: Move FdTOq, FxTOq to decodetree
> target/sparc: Move FMOVq, FNEGq, FABSq to decodetree
> target/sparc: Move FMOVR, FMOVcc, FMOVfcc to decodetree
> target/sparc: Convert FCMP, FCMPE to decodetree
> target/sparc: Move FPCMP* to decodetree
> target/sparc: Move FPACK16, FPACKFIX to decodetree
> target/sparc: Convert FZERO, FONE to decodetree
> target/sparc: Remove disas_sparc_legacy
>
> configs/targets/sparc-softmmu.mak | 1 +
> configs/targets/sparc64-softmmu.mak | 1 +
> linux-user/sparc/target_syscall.h | 6 +-
> target/sparc/cpu.h | 76 +-
> target/sparc/helper.h | 16 +-
> target/sparc/cpu-feature.h.inc | 14 +
> target/sparc/insns.decode | 540 +++
> target/sparc/cpu.c | 41 +-
> target/sparc/fop_helper.c | 17 +-
> target/sparc/ldst_helper.c | 17 +-
> target/sparc/translate.c | 6833 +++++++++++++--------------
> target/sparc/vis_helper.c | 59 -
> target/sparc/meson.build | 3 +
> 13 files changed, 3985 insertions(+), 3639 deletions(-)
> create mode 100644 target/sparc/cpu-feature.h.inc
> create mode 100644 target/sparc/insns.decode
Thanks again for working on this :) I've done a re-run of my 32-bit SPARC tests and
things are looking fairly good now, although there were still a small number of failures:
[1] ./qemu-system-sparc -bios ss5.bin
-> Now traps immediately on startup
qemu: fatal: Trap 0x02 (Illegal Instruction) while interrupts disabled, Error state
pc: ffeff020 npc: ffeff024
%g0-7: 00000000 ffffffff ffd15a00 ffef0000 00000002 ffd17384 ffefefd8 ffefebd0
%o0-7: 7000cbcf 0007ffff 00080000 00000000 0000001e 07fee5fc 00000000 0000caf0
%l0-7: 07fff000 ffd173f0 ffd173f4 07fef000 07feec00 00000000 00000000 00000000
%i0-7: 01fee000 00001000 00000000 00000000 00000000 0000beec 0002aa2c ffd1e080
%f00: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
%f08: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
%f16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
%f24: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
psr: 04000fc7 (icc: ---- SPE: SP-) wim: 00000000
fsr: 00000000 y: 00000000
Aborted (core dumped)
-> Bisected to:
6c8bf6bbe369c7cda82aaba63a19508e8cff5085 is the first bad commit
commit 6c8bf6bbe369c7cda82aaba63a19508e8cff5085
Author: Richard Henderson <richard.henderson@linaro.org>
Date: Mon Oct 16 23:11:34 2023 -0700
target/sparc: Move Tcc to decodetree
Use the new delay_exceptionv function in the implementation.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20231017061244.681584-21-richard.henderson@linaro.org>
target/sparc/insns.decode | 2 +
target/sparc/translate.c | 143 +++++++++++++++++++++-------------------------
2 files changed, 66 insertions(+), 79 deletions(-)
[2] ./qemu-system-sparc -hda net702.qcow -snapshot (NetBSD 7)
-> Hangs after displaying "Starting network"
-> Bisected to:
db639ccbdce25dde5e767f3da1ff40e29067610c is the first bad commit
commit db639ccbdce25dde5e767f3da1ff40e29067610c
Author: Richard Henderson <richard.henderson@linaro.org>
Date: Mon Oct 16 23:11:44 2023 -0700
target/sparc: Move ADDC to decodetree
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20231017061244.681584-31-richard.henderson@linaro.org>
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 41 +++++++++++++++++++++++++++++++++++++----
2 files changed, 39 insertions(+), 4 deletions(-)
[3] ./qemu-system-sparc -cdrom NetBSD-6.1.3-sparc.iso -boot d
-> Displays "write failed, filesystem full" and "Segmentation Fault" error messages
during boot
-> Bisected to:
db639ccbdce25dde5e767f3da1ff40e29067610c is the first bad commit
commit db639ccbdce25dde5e767f3da1ff40e29067610c
Author: Richard Henderson <richard.henderson@linaro.org>
Date: Mon Oct 16 23:11:44 2023 -0700
target/sparc: Move ADDC to decodetree
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20231017061244.681584-31-richard.henderson@linaro.org>
target/sparc/insns.decode | 2 ++
target/sparc/translate.c | 41 +++++++++++++++++++++++++++++++++++++----
2 files changed, 39 insertions(+), 4 deletions(-)
ATB,
Mark.
^ permalink raw reply [flat|nested] 92+ messages in thread
end of thread, other threads:[~2023-10-17 21:19 UTC | newest]
Thread overview: 92+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-17 6:11 [PATCH v2 00/90] target/sparc: Convert to decodetree Richard Henderson
2023-10-17 6:11 ` [PATCH v2 01/90] target/sparc: Clear may_lookup for npc == DYNAMIC_PC Richard Henderson
2023-10-17 6:11 ` [PATCH v2 02/90] target/sparc: Implement check_align inline Richard Henderson
2023-10-17 6:11 ` [PATCH v2 03/90] target/sparc: Avoid helper_raise_exception in helper_st_asi Richard Henderson
2023-10-17 6:11 ` [PATCH v2 04/90] target/sparc: Set TCG_GUEST_DEFAULT_MO Richard Henderson
2023-10-17 6:11 ` [PATCH v2 05/90] configs: Enable MTTCG for sparc, sparc64 Richard Henderson
2023-10-17 6:11 ` [PATCH v2 06/90] target/sparc: Define features via cpu-feature.h.inc Richard Henderson
2023-10-17 6:11 ` [PATCH v2 07/90] target/sparc: Use CPU_FEATURE_BIT_* for cpu properties Richard Henderson
2023-10-17 6:11 ` [PATCH v2 08/90] target/sparc: Remove sparcv7 cpu features Richard Henderson
2023-10-17 6:11 ` [PATCH v2 09/90] target/sparc: Add decodetree infrastructure Richard Henderson
2023-10-17 6:11 ` [PATCH v2 10/90] target/sparc: Define AM_CHECK for sparc32 Richard Henderson
2023-10-17 6:11 ` [PATCH v2 11/90] target/sparc: Move CALL to decodetree Richard Henderson
2023-10-17 6:11 ` [PATCH v2 12/90] target/sparc: Move BPcc and Bicc " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 13/90] target/sparc: Move BPr " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 14/90] target/sparc: Move FBPfcc and FBfcc " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 15/90] target/sparc: Merge gen_cond with only caller Richard Henderson
2023-10-17 6:11 ` [PATCH v2 16/90] target/sparc: Merge gen_fcond " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 17/90] target/sparc: Merge gen_branch_[an] " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 18/90] target/sparc: Pass DisasCompare to advance_jump_cond Richard Henderson
2023-10-17 6:11 ` [PATCH v2 19/90] target/sparc: Move SETHI to decodetree Richard Henderson
2023-10-17 6:11 ` [PATCH v2 20/90] target/sparc: Move Tcc " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 21/90] target/sparc: Move RDASR, STBAR, MEMBAR " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 22/90] target/sparc: Move RDPSR, RDHPR " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 23/90] target/sparc: Move RDWIM, RDPR " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 24/90] target/sparc: Move RDTBR, FLUSHW " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 25/90] target/sparc: Move WRASR " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 26/90] target/sparc: Move WRPSR, SAVED, RESTORED " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 27/90] target/sparc: Move WRWIM, WRPR " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 28/90] target/sparc: Move WRTBR, WRHPR " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 29/90] target/sparc: Move basic arithmetic " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 30/90] target/sparc: Move ADDC " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 31/90] target/sparc: Move MULX " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 32/90] target/sparc: Move UMUL, SMUL " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 33/90] target/sparc: Move SUBC " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 34/90] target/sparc: Move UDIVX, SDIVX " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 35/90] target/sparc: Move UDIV, SDIV " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 36/90] target/sparc: Move TADD, TSUB, MULS " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 37/90] target/sparc: Move SLL, SRL, SRA " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 38/90] target/sparc: Move MOVcc, MOVR " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 39/90] target/sparc: Move POPC " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 40/90] target/sparc: Convert remaining v8 coproc insns " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 41/90] target/sparc: Move JMPL, RETT, RETURN " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 42/90] target/sparc: Move FLUSH, SAVE, RESTORE " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 43/90] target/sparc: Move DONE, RETRY " Richard Henderson
2023-10-17 6:11 ` [PATCH v2 44/90] target/sparc: Split out resolve_asi Richard Henderson
2023-10-17 6:11 ` [PATCH v2 45/90] target/sparc: Drop ifdef around get_asi and friends Richard Henderson
2023-10-17 6:12 ` [PATCH v2 46/90] target/sparc: Split out ldst functions with asi pre-computed Richard Henderson
2023-10-17 6:12 ` [PATCH v2 47/90] target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for GET_ASI_DTWINX Richard Henderson
2023-10-17 6:12 ` [PATCH v2 48/90] target/sparc: Move simple integer load/store to decodetree Richard Henderson
2023-10-17 6:12 ` [PATCH v2 49/90] target/sparc: Move asi " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 50/90] target/sparc: Move LDSTUB, LDSTUBA " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 51/90] target/sparc: Move SWAP, SWAPA " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 52/90] target/sparc: Move CASA, CASXA " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 53/90] target/sparc: Move PREFETCH, PREFETCHA " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 54/90] target/sparc: Split out fp ldst functions with asi precomputed Richard Henderson
2023-10-17 6:12 ` [PATCH v2 55/90] target/sparc: Move simple fp load/store to decodetree Richard Henderson
2023-10-17 6:12 ` [PATCH v2 56/90] target/sparc: Move asi " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 57/90] target/sparc: Move LDFSR, STFSR " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 58/90] target/sparc: Merge LDFSR, LDXFSR implementations Richard Henderson
2023-10-17 6:12 ` [PATCH v2 59/90] target/sparc: Move EDGE* to decodetree Richard Henderson
2023-10-17 6:12 ` [PATCH v2 60/90] target/sparc: Move ARRAY* " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 61/90] target/sparc: Move ADDRALIGN* " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 62/90] target/sparc: Move BMASK " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 63/90] target/sparc: Move FMOVS, FNEGS, FABSS, FSRC*S, FNOT*S " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 64/90] target/sparc: Move FMOVD, FNEGD, FABSD, FSRC*D, FNOT*D " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 65/90] target/sparc: Use tcg_gen_vec_{add,sub}* Richard Henderson
2023-10-17 6:12 ` [PATCH v2 66/90] target/sparc: Move gen_ne_fop_FFF insns to decodetree Richard Henderson
2023-10-17 6:12 ` [PATCH v2 67/90] target/sparc: Move gen_ne_fop_DDD " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 68/90] target/sparc: Move PDIST " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 69/90] target/sparc: Move gen_gsr_fop_DDD insns " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 70/90] target/sparc: Move gen_fop_FF " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 71/90] target/sparc: Move gen_fop_DD " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 72/90] target/sparc: Move FSQRTq " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 73/90] target/sparc: Move gen_fop_FFF insns " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 74/90] target/sparc: Move gen_fop_DDD " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 75/90] target/sparc: Move gen_fop_QQQ " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 76/90] target/sparc: Move FSMULD " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 77/90] target/sparc: Move FDMULQ " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 78/90] target/sparc: Move gen_fop_FD insns " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 79/90] target/sparc: Move FiTOd, FsTOd, FsTOx " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 80/90] target/sparc: Move FqTOs, FqTOi " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 81/90] target/sparc: Move FqTOd, FqTOx " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 82/90] target/sparc: Move FiTOq, FsTOq " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 83/90] target/sparc: Move FdTOq, FxTOq " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 84/90] target/sparc: Move FMOVq, FNEGq, FABSq " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 85/90] target/sparc: Move FMOVR, FMOVcc, FMOVfcc " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 86/90] target/sparc: Convert FCMP, FCMPE " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 87/90] target/sparc: Move FPCMP* " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 88/90] target/sparc: Move FPACK16, FPACKFIX " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 89/90] target/sparc: Convert FZERO, FONE " Richard Henderson
2023-10-17 6:12 ` [PATCH v2 90/90] target/sparc: Remove disas_sparc_legacy Richard Henderson
2023-10-17 21:17 ` [PATCH v2 00/90] target/sparc: Convert to decodetree Mark Cave-Ayland
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.