* [PULL 00/18] target/hppa patch queue
@ 2024-03-29 22:30 Richard Henderson
2024-03-29 22:30 ` [PULL 01/18] target/hppa: Fix BE,L set of sr0 Richard Henderson
` (18 more replies)
0 siblings, 19 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:30 UTC (permalink / raw)
To: qemu-devel
The following changes since commit 5012e522aca161be5c141596c66e5cc6082538a9:
Update version for v9.0.0-rc1 release (2024-03-26 19:46:55 +0000)
are available in the Git repository at:
https://gitlab.com/rth7680/qemu.git tags/pull-pa-20240329
for you to fetch changes up to 4a3aa11e1fb25c28c24a43fd2835c429b00a463d:
target/hppa: Clear psw_n for BE on use_nullify_skip path (2024-03-29 08:15:01 -1000)
----------------------------------------------------------------
target/hppa: Fix BE,L set of sr0
target/hppa: Fix B,GATE for wide mode
target/hppa: Mark interval timer write as io
target/hppa: Fix EIRR, EIEM versus icount
target/hppa: Fix DCOR reconstruction of carry bits
target/hppa: Fix unit carry conditions
target/hppa: Fix overflow computation for shladd
target/hppa: Add diag instructions to set/restore shadow registers
target/hppa: Clear psw_n for BE on use_nullify_skip path
----------------------------------------------------------------
Helge Deller (1):
target/hppa: Add diag instructions to set/restore shadow registers
Richard Henderson (14):
target/hppa: Fix BE,L set of sr0
target/hppa: Fix B,GATE for wide mode
target/hppa: Mark interval timer write as io
target/hppa: Tidy read of interval timer
target/hppa: Fix EIRR, EIEM versus icount
target/hppa: Fix DCOR reconstruction of carry bits
target/hppa: Optimize UADDCM with no condition
target/hppa: Fix unit carry conditions
target/hppa: Squash d for pa1.x during decode
target/hppa: Replace c with uv in do_cond
target/hppa: Fix overflow computation for shladd
target/hppa: Generate getshadowregs inline
target/hppa: Move diag argument handling to decodetree
target/hppa: Clear psw_n for BE on use_nullify_skip path
Sven Schnelle (3):
target/hppa: Handle unit conditions for wide mode
target/hppa: Fix ADD/SUB trap on overflow for narrow mode
target/hppa: Use gva_offset_mask() everywhere
target/hppa/cpu.h | 10 +-
target/hppa/helper.h | 2 -
target/hppa/insns.decode | 38 +++-
target/hppa/int_helper.c | 14 +-
target/hppa/sys_helper.c | 4 +-
target/hppa/translate.c | 488 +++++++++++++++++++++++++++++++----------------
6 files changed, 364 insertions(+), 192 deletions(-)
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PULL 01/18] target/hppa: Fix BE,L set of sr0
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
@ 2024-03-29 22:30 ` Richard Henderson
2024-03-29 22:30 ` [PULL 02/18] target/hppa: Fix B,GATE for wide mode Richard Henderson
` (17 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
The return address comes from IA*Q_Next, and IASQ_Next
is always equal to IASQ_Back, not IASQ_Front.
Tested-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 19594f917e..1766a63001 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3817,7 +3817,7 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
load_spr(ctx, new_spc, a->sp);
if (a->l) {
copy_iaoq_entry(ctx, cpu_gr[31], ctx->iaoq_n, ctx->iaoq_n_var);
- tcg_gen_mov_i64(cpu_sr[0], cpu_iasq_f);
+ tcg_gen_mov_i64(cpu_sr[0], cpu_iasq_b);
}
if (a->n && use_nullify_skip(ctx)) {
copy_iaoq_entry(ctx, cpu_iaoq_f, -1, tmp);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 02/18] target/hppa: Fix B,GATE for wide mode
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
2024-03-29 22:30 ` [PULL 01/18] target/hppa: Fix BE,L set of sr0 Richard Henderson
@ 2024-03-29 22:30 ` Richard Henderson
2024-03-29 22:30 ` [PULL 03/18] target/hppa: Handle unit conditions " Richard Henderson
` (16 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller, Philippe Mathieu-Daudé
Do not clobber the high bits of the address by using a 32-bit deposit.
Reviewed-by: Helge Deller <deller@gmx.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 1766a63001..f875d76a23 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3880,7 +3880,7 @@ static bool trans_b_gate(DisasContext *ctx, arg_b_gate *a)
}
/* No change for non-gateway pages or for priv decrease. */
if (type >= 4 && type - 4 < ctx->privilege) {
- dest = deposit32(dest, 0, 2, type - 4);
+ dest = deposit64(dest, 0, 2, type - 4);
}
} else {
dest &= -4; /* priv = 0 */
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 03/18] target/hppa: Handle unit conditions for wide mode
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
2024-03-29 22:30 ` [PULL 01/18] target/hppa: Fix BE,L set of sr0 Richard Henderson
2024-03-29 22:30 ` [PULL 02/18] target/hppa: Fix B,GATE for wide mode Richard Henderson
@ 2024-03-29 22:30 ` Richard Henderson
2024-03-29 22:30 ` [PULL 04/18] target/hppa: Fix ADD/SUB trap on overflow for narrow mode Richard Henderson
` (15 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Sven Schnelle
From: Sven Schnelle <svens@stackframe.org>
Wide mode provides two more conditions, add them.
Fixes: 59963d8fdf42 ("target/hppa: Pass d to do_unit_cond")
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240321184228.611897-1-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index f875d76a23..2cb91956da 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -967,11 +967,22 @@ static DisasCond do_unit_cond(unsigned cf, bool d, TCGv_i64 res,
switch (cf >> 1) {
case 0: /* never / TR */
- case 1: /* undefined */
- case 5: /* undefined */
cond = cond_make_f();
break;
+ case 1: /* SBW / NBW */
+ if (d) {
+ tmp = tcg_temp_new_i64();
+ tcg_gen_subi_i64(tmp, res, d_repl * 0x00000001u);
+ tcg_gen_andc_i64(tmp, tmp, res);
+ tcg_gen_andi_i64(tmp, tmp, d_repl * 0x80000000u);
+ cond = cond_make_0(TCG_COND_NE, tmp);
+ } else {
+ /* undefined */
+ cond = cond_make_f();
+ }
+ break;
+
case 2: /* SBZ / NBZ */
/* See hasless(v,1) from
* https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
@@ -996,6 +1007,16 @@ static DisasCond do_unit_cond(unsigned cf, bool d, TCGv_i64 res,
cond = cond_make_0(TCG_COND_NE, cb);
break;
+ case 5: /* SWC / NWC */
+ if (d) {
+ tcg_gen_andi_i64(cb, cb, d_repl * 0x80000000u);
+ cond = cond_make_0(TCG_COND_NE, cb);
+ } else {
+ /* undefined */
+ cond = cond_make_f();
+ }
+ break;
+
case 6: /* SBC / NBC */
tcg_gen_andi_i64(cb, cb, d_repl * 0x80808080u);
cond = cond_make_0(TCG_COND_NE, cb);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 04/18] target/hppa: Fix ADD/SUB trap on overflow for narrow mode
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (2 preceding siblings ...)
2024-03-29 22:30 ` [PULL 03/18] target/hppa: Handle unit conditions " Richard Henderson
@ 2024-03-29 22:30 ` Richard Henderson
2024-03-29 22:30 ` [PULL 05/18] target/hppa: Mark interval timer write as io Richard Henderson
` (14 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Sven Schnelle
From: Sven Schnelle <svens@stackframe.org>
Fixes: c53e401ed9ff ("target/hppa: Remove TARGET_REGISTER_BITS")
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240321184228.611897-2-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 2cb91956da..ceb739c54a 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1126,6 +1126,9 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
if (is_tsv || cond_need_sv(c)) {
sv = do_add_sv(ctx, dest, in1, in2);
if (is_tsv) {
+ if (!d) {
+ tcg_gen_ext32s_i64(sv, sv);
+ }
/* ??? Need to include overflow from shift. */
gen_helper_tsv(tcg_env, sv);
}
@@ -1217,6 +1220,9 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
if (is_tsv || cond_need_sv(c)) {
sv = do_sub_sv(ctx, dest, in1, in2);
if (is_tsv) {
+ if (!d) {
+ tcg_gen_ext32s_i64(sv, sv);
+ }
gen_helper_tsv(tcg_env, sv);
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 05/18] target/hppa: Mark interval timer write as io
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (3 preceding siblings ...)
2024-03-29 22:30 ` [PULL 04/18] target/hppa: Fix ADD/SUB trap on overflow for narrow mode Richard Henderson
@ 2024-03-29 22:30 ` Richard Henderson
2024-03-29 22:30 ` [PULL 06/18] target/hppa: Tidy read of interval timer Richard Henderson
` (13 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
Reviewed-by: Helge Deller <deller@gmx.de>
Tested-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index ceb739c54a..8c1a564c5d 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2162,6 +2162,9 @@ static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a)
switch (ctl) {
case CR_IT:
+ if (translator_io_start(&ctx->base)) {
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE;
+ }
gen_helper_write_interval_timer(tcg_env, reg);
break;
case CR_EIRR:
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 06/18] target/hppa: Tidy read of interval timer
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (4 preceding siblings ...)
2024-03-29 22:30 ` [PULL 05/18] target/hppa: Mark interval timer write as io Richard Henderson
@ 2024-03-29 22:30 ` Richard Henderson
2024-03-29 22:31 ` [PULL 07/18] target/hppa: Fix EIRR, EIEM versus icount Richard Henderson
` (12 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
The call to gen_helper_read_interval_timer is
identical on both sides of the IF.
Reviewed-by: Helge Deller <deller@gmx.de>
Tested-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 8c1a564c5d..5b8c1b06c3 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2082,11 +2082,9 @@ static bool trans_mfctl(DisasContext *ctx, arg_mfctl *a)
nullify_over(ctx);
tmp = dest_gpr(ctx, rt);
if (translator_io_start(&ctx->base)) {
- gen_helper_read_interval_timer(tmp);
ctx->base.is_jmp = DISAS_IAQ_N_STALE;
- } else {
- gen_helper_read_interval_timer(tmp);
}
+ gen_helper_read_interval_timer(tmp);
save_gpr(ctx, rt, tmp);
return nullify_end(ctx);
case 26:
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 07/18] target/hppa: Fix EIRR, EIEM versus icount
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (5 preceding siblings ...)
2024-03-29 22:30 ` [PULL 06/18] target/hppa: Tidy read of interval timer Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 08/18] target/hppa: Use gva_offset_mask() everywhere Richard Henderson
` (11 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
Call translator_io_start before write to EIRR.
Move evaluation of EIRR vs EIEM to hppa_cpu_exec_interrupt.
Exit TB after write to EIEM, but otherwise use a straight store.
Reviewed-by: Helge Deller <deller@gmx.de>
Tested-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/helper.h | 1 -
target/hppa/int_helper.c | 14 ++++----------
target/hppa/translate.c | 10 +++++++---
3 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 1bdbcd8f98..8fd7ba65d8 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -91,7 +91,6 @@ DEF_HELPER_1(rfi, void, env)
DEF_HELPER_1(rfi_r, void, env)
DEF_HELPER_FLAGS_2(write_interval_timer, TCG_CALL_NO_RWG, void, env, tl)
DEF_HELPER_FLAGS_2(write_eirr, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_2(write_eiem, TCG_CALL_NO_RWG, void, env, tl)
DEF_HELPER_FLAGS_2(swap_system_mask, TCG_CALL_NO_RWG, tl, env, tl)
DEF_HELPER_FLAGS_3(itlba_pa11, TCG_CALL_NO_RWG, void, env, tl, tl)
DEF_HELPER_FLAGS_3(itlbp_pa11, TCG_CALL_NO_RWG, void, env, tl, tl)
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index efe638b36e..90437a92cd 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -28,7 +28,7 @@
static void eval_interrupt(HPPACPU *cpu)
{
CPUState *cs = CPU(cpu);
- if (cpu->env.cr[CR_EIRR] & cpu->env.cr[CR_EIEM]) {
+ if (cpu->env.cr[CR_EIRR]) {
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
} else {
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
@@ -89,14 +89,6 @@ void HELPER(write_eirr)(CPUHPPAState *env, target_ulong val)
bql_unlock();
}
-void HELPER(write_eiem)(CPUHPPAState *env, target_ulong val)
-{
- env->cr[CR_EIEM] = val;
- bql_lock();
- eval_interrupt(env_archcpu(env));
- bql_unlock();
-}
-
void hppa_cpu_do_interrupt(CPUState *cs)
{
HPPACPU *cpu = HPPA_CPU(cs);
@@ -280,7 +272,9 @@ bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
}
/* If interrupts are requested and enabled, raise them. */
- if ((env->psw & PSW_I) && (interrupt_request & CPU_INTERRUPT_HARD)) {
+ if ((interrupt_request & CPU_INTERRUPT_HARD)
+ && (env->psw & PSW_I)
+ && (env->cr[CR_EIRR] & env->cr[CR_EIEM])) {
cs->exception_index = EXCP_EXT_INTERRUPT;
hppa_cpu_do_interrupt(cs);
return true;
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 5b8c1b06c3..46b2d6508d 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2166,10 +2166,10 @@ static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a)
gen_helper_write_interval_timer(tcg_env, reg);
break;
case CR_EIRR:
+ /* Helper modifies interrupt lines and is therefore IO. */
+ translator_io_start(&ctx->base);
gen_helper_write_eirr(tcg_env, reg);
- break;
- case CR_EIEM:
- gen_helper_write_eiem(tcg_env, reg);
+ /* Exit to re-evaluate interrupts in the main loop. */
ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
break;
@@ -2195,6 +2195,10 @@ static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a)
#endif
break;
+ case CR_EIEM:
+ /* Exit to re-evaluate interrupts in the main loop. */
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
+ /* FALLTHRU */
default:
tcg_gen_st_i64(reg, tcg_env, offsetof(CPUHPPAState, cr[ctl]));
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 08/18] target/hppa: Use gva_offset_mask() everywhere
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (6 preceding siblings ...)
2024-03-29 22:31 ` [PULL 07/18] target/hppa: Fix EIRR, EIEM versus icount Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 09/18] target/hppa: Fix DCOR reconstruction of carry bits Richard Henderson
` (10 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Sven Schnelle, Helge Deller
From: Sven Schnelle <svens@stackframe.org>
Move it to cpu.h, so it can also be used in hppa_form_gva_psw().
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Helge Deller <deller@gmx.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240324080945.991100-2-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/cpu.h | 10 ++++++++--
target/hppa/translate.c | 12 +++---------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index a92dc352cb..a072d0bb63 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -285,14 +285,20 @@ void hppa_translate_init(void);
#define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
+static inline uint64_t gva_offset_mask(target_ulong psw)
+{
+ return (psw & PSW_W
+ ? MAKE_64BIT_MASK(0, 62)
+ : MAKE_64BIT_MASK(0, 32));
+}
+
static inline target_ulong hppa_form_gva_psw(target_ulong psw, uint64_t spc,
target_ulong off)
{
#ifdef CONFIG_USER_ONLY
return off;
#else
- off &= psw & PSW_W ? MAKE_64BIT_MASK(0, 62) : MAKE_64BIT_MASK(0, 32);
- return spc | off;
+ return spc | (off & gva_offset_mask(psw));
#endif
}
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 46b2d6508d..e041310207 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -586,17 +586,10 @@ static bool nullify_end(DisasContext *ctx)
return true;
}
-static uint64_t gva_offset_mask(DisasContext *ctx)
-{
- return (ctx->tb_flags & PSW_W
- ? MAKE_64BIT_MASK(0, 62)
- : MAKE_64BIT_MASK(0, 32));
-}
-
static void copy_iaoq_entry(DisasContext *ctx, TCGv_i64 dest,
uint64_t ival, TCGv_i64 vval)
{
- uint64_t mask = gva_offset_mask(ctx);
+ uint64_t mask = gva_offset_mask(ctx->tb_flags);
if (ival != -1) {
tcg_gen_movi_i64(dest, ival & mask);
@@ -1430,7 +1423,8 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, TCGv_i64 *pofs,
*pofs = ofs;
*pgva = addr = tcg_temp_new_i64();
- tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base, gva_offset_mask(ctx));
+ tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base,
+ gva_offset_mask(ctx->tb_flags));
#ifndef CONFIG_USER_ONLY
if (!is_phys) {
tcg_gen_or_i64(addr, addr, space_select(ctx, sp, base));
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 09/18] target/hppa: Fix DCOR reconstruction of carry bits
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (7 preceding siblings ...)
2024-03-29 22:31 ` [PULL 08/18] target/hppa: Use gva_offset_mask() everywhere Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 10/18] target/hppa: Optimize UADDCM with no condition Richard Henderson
` (9 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
The carry bits for each nibble N are located in bit (N+1)*4,
so the shift by 3 was off by one. Furthermore, the carry bit
for the most significant carry bit is indeed located in bit 64,
which is located in a different storage word.
Use a double-word shift-right to reassemble into a single word
and place them all at bit 0 of their respective nibbles.
Tested-by: Helge Deller <deller@gmx.de>
Reviewed-by: Helge Deller <deller@gmx.de>
Fixes: b2167459ae4 ("target-hppa: Implement basic arithmetic")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index e041310207..a3f425d861 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2791,7 +2791,7 @@ static bool do_dcor(DisasContext *ctx, arg_rr_cf_d *a, bool is_i)
nullify_over(ctx);
tmp = tcg_temp_new_i64();
- tcg_gen_shri_i64(tmp, cpu_psw_cb, 3);
+ tcg_gen_extract2_i64(tmp, cpu_psw_cb, cpu_psw_cb_msb, 4);
if (!is_i) {
tcg_gen_not_i64(tmp, tmp);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 10/18] target/hppa: Optimize UADDCM with no condition
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (8 preceding siblings ...)
2024-03-29 22:31 ` [PULL 09/18] target/hppa: Fix DCOR reconstruction of carry bits Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 11/18] target/hppa: Fix unit carry conditions Richard Henderson
` (8 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
With r1 as zero is by far the most common usage of UADDCM, as the
easiest way to invert a register. The compiler does occasionally
use the addition step as well, and we can simplify that to avoid
a temp and write directly into the destination.
Tested-by: Helge Deller <deller@gmx.de>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index a3f425d861..3fc3e7754c 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2763,9 +2763,29 @@ static bool do_uaddcm(DisasContext *ctx, arg_rrr_cf_d *a, bool is_tc)
{
TCGv_i64 tcg_r1, tcg_r2, tmp;
- if (a->cf) {
- nullify_over(ctx);
+ if (a->cf == 0) {
+ tcg_r2 = load_gpr(ctx, a->r2);
+ tmp = dest_gpr(ctx, a->t);
+
+ if (a->r1 == 0) {
+ /* UADDCM r0,src,dst is the common idiom for dst = ~src. */
+ tcg_gen_not_i64(tmp, tcg_r2);
+ } else {
+ /*
+ * Recall that r1 - r2 == r1 + ~r2 + 1.
+ * Thus r1 + ~r2 == r1 - r2 - 1,
+ * which does not require an extra temporary.
+ */
+ tcg_r1 = load_gpr(ctx, a->r1);
+ tcg_gen_sub_i64(tmp, tcg_r1, tcg_r2);
+ tcg_gen_subi_i64(tmp, tmp, 1);
+ }
+ save_gpr(ctx, a->t, tmp);
+ cond_free(&ctx->null_cond);
+ return true;
}
+
+ nullify_over(ctx);
tcg_r1 = load_gpr(ctx, a->r1);
tcg_r2 = load_gpr(ctx, a->r2);
tmp = tcg_temp_new_i64();
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 11/18] target/hppa: Fix unit carry conditions
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (9 preceding siblings ...)
2024-03-29 22:31 ` [PULL 10/18] target/hppa: Optimize UADDCM with no condition Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 12/18] target/hppa: Squash d for pa1.x during decode Richard Henderson
` (7 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
Split do_unit_cond to do_unit_zero_cond to only handle conditions
versus zero. These are the only ones that are legal for UXOR.
Simplify trans_uxor accordingly.
Rename do_unit to do_unit_addsub, since xor has been split.
Properly compute carry-out bits for add and subtract, mirroring
the code in do_add and do_sub.
Tested-by: Helge Deller <deller@gmx.de>
Reviewed-by: Helge Deller <deller@gmx.de>
Fixes: b2167459ae4 ("target-hppa: Implement basic arithmetic")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 218 +++++++++++++++++++++-------------------
1 file changed, 113 insertions(+), 105 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 3fc3e7754c..99c5c4cbca 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -936,98 +936,44 @@ static DisasCond do_sed_cond(DisasContext *ctx, unsigned orig, bool d,
return do_log_cond(ctx, c * 2 + f, d, res);
}
-/* Similar, but for unit conditions. */
-
-static DisasCond do_unit_cond(unsigned cf, bool d, TCGv_i64 res,
- TCGv_i64 in1, TCGv_i64 in2)
+/* Similar, but for unit zero conditions. */
+static DisasCond do_unit_zero_cond(unsigned cf, bool d, TCGv_i64 res)
{
- DisasCond cond;
- TCGv_i64 tmp, cb = NULL;
+ TCGv_i64 tmp;
uint64_t d_repl = d ? 0x0000000100000001ull : 1;
-
- if (cf & 8) {
- /* Since we want to test lots of carry-out bits all at once, do not
- * do our normal thing and compute carry-in of bit B+1 since that
- * leaves us with carry bits spread across two words.
- */
- cb = tcg_temp_new_i64();
- tmp = tcg_temp_new_i64();
- tcg_gen_or_i64(cb, in1, in2);
- tcg_gen_and_i64(tmp, in1, in2);
- tcg_gen_andc_i64(cb, cb, res);
- tcg_gen_or_i64(cb, cb, tmp);
- }
+ uint64_t ones = 0, sgns = 0;
switch (cf >> 1) {
- case 0: /* never / TR */
- cond = cond_make_f();
- break;
-
case 1: /* SBW / NBW */
if (d) {
- tmp = tcg_temp_new_i64();
- tcg_gen_subi_i64(tmp, res, d_repl * 0x00000001u);
- tcg_gen_andc_i64(tmp, tmp, res);
- tcg_gen_andi_i64(tmp, tmp, d_repl * 0x80000000u);
- cond = cond_make_0(TCG_COND_NE, tmp);
- } else {
- /* undefined */
- cond = cond_make_f();
+ ones = d_repl;
+ sgns = d_repl << 31;
}
break;
-
case 2: /* SBZ / NBZ */
- /* See hasless(v,1) from
- * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
- */
- tmp = tcg_temp_new_i64();
- tcg_gen_subi_i64(tmp, res, d_repl * 0x01010101u);
- tcg_gen_andc_i64(tmp, tmp, res);
- tcg_gen_andi_i64(tmp, tmp, d_repl * 0x80808080u);
- cond = cond_make_0(TCG_COND_NE, tmp);
+ ones = d_repl * 0x01010101u;
+ sgns = ones << 7;
break;
-
case 3: /* SHZ / NHZ */
- tmp = tcg_temp_new_i64();
- tcg_gen_subi_i64(tmp, res, d_repl * 0x00010001u);
- tcg_gen_andc_i64(tmp, tmp, res);
- tcg_gen_andi_i64(tmp, tmp, d_repl * 0x80008000u);
- cond = cond_make_0(TCG_COND_NE, tmp);
+ ones = d_repl * 0x00010001u;
+ sgns = ones << 15;
break;
-
- case 4: /* SDC / NDC */
- tcg_gen_andi_i64(cb, cb, d_repl * 0x88888888u);
- cond = cond_make_0(TCG_COND_NE, cb);
- break;
-
- case 5: /* SWC / NWC */
- if (d) {
- tcg_gen_andi_i64(cb, cb, d_repl * 0x80000000u);
- cond = cond_make_0(TCG_COND_NE, cb);
- } else {
- /* undefined */
- cond = cond_make_f();
- }
- break;
-
- case 6: /* SBC / NBC */
- tcg_gen_andi_i64(cb, cb, d_repl * 0x80808080u);
- cond = cond_make_0(TCG_COND_NE, cb);
- break;
-
- case 7: /* SHC / NHC */
- tcg_gen_andi_i64(cb, cb, d_repl * 0x80008000u);
- cond = cond_make_0(TCG_COND_NE, cb);
- break;
-
- default:
- g_assert_not_reached();
}
- if (cf & 1) {
- cond.c = tcg_invert_cond(cond.c);
+ if (ones == 0) {
+ /* Undefined, or 0/1 (never/always). */
+ return cf & 1 ? cond_make_t() : cond_make_f();
}
- return cond;
+ /*
+ * See hasless(v,1) from
+ * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
+ */
+ tmp = tcg_temp_new_i64();
+ tcg_gen_subi_i64(tmp, res, ones);
+ tcg_gen_andc_i64(tmp, tmp, res);
+ tcg_gen_andi_i64(tmp, tmp, sgns);
+
+ return cond_make_0_tmp(cf & 1 ? TCG_COND_EQ : TCG_COND_NE, tmp);
}
static TCGv_i64 get_carry(DisasContext *ctx, bool d,
@@ -1330,34 +1276,86 @@ static bool do_log_reg(DisasContext *ctx, arg_rrr_cf_d *a,
return nullify_end(ctx);
}
-static void do_unit(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
- TCGv_i64 in2, unsigned cf, bool d, bool is_tc,
- void (*fn)(TCGv_i64, TCGv_i64, TCGv_i64))
+static void do_unit_addsub(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
+ TCGv_i64 in2, unsigned cf, bool d,
+ bool is_tc, bool is_add)
{
- TCGv_i64 dest;
+ TCGv_i64 dest = tcg_temp_new_i64();
+ uint64_t test_cb = 0;
DisasCond cond;
- if (cf == 0) {
- dest = dest_gpr(ctx, rt);
- fn(dest, in1, in2);
- save_gpr(ctx, rt, dest);
- cond_free(&ctx->null_cond);
- } else {
- dest = tcg_temp_new_i64();
- fn(dest, in1, in2);
-
- cond = do_unit_cond(cf, d, dest, in1, in2);
-
- if (is_tc) {
- TCGv_i64 tmp = tcg_temp_new_i64();
- tcg_gen_setcond_i64(cond.c, tmp, cond.a0, cond.a1);
- gen_helper_tcond(tcg_env, tmp);
+ /* Select which carry-out bits to test. */
+ switch (cf >> 1) {
+ case 4: /* NDC / SDC -- 4-bit carries */
+ test_cb = dup_const(MO_8, 0x88);
+ break;
+ case 5: /* NWC / SWC -- 32-bit carries */
+ if (d) {
+ test_cb = dup_const(MO_32, INT32_MIN);
+ } else {
+ cf &= 1; /* undefined -- map to never/always */
}
- save_gpr(ctx, rt, dest);
-
- cond_free(&ctx->null_cond);
- ctx->null_cond = cond;
+ break;
+ case 6: /* NBC / SBC -- 8-bit carries */
+ test_cb = dup_const(MO_8, INT8_MIN);
+ break;
+ case 7: /* NHC / SHC -- 16-bit carries */
+ test_cb = dup_const(MO_16, INT16_MIN);
+ break;
}
+ if (!d) {
+ test_cb = (uint32_t)test_cb;
+ }
+
+ if (!test_cb) {
+ /* No need to compute carries if we don't need to test them. */
+ if (is_add) {
+ tcg_gen_add_i64(dest, in1, in2);
+ } else {
+ tcg_gen_sub_i64(dest, in1, in2);
+ }
+ cond = do_unit_zero_cond(cf, d, dest);
+ } else {
+ TCGv_i64 cb = tcg_temp_new_i64();
+
+ if (d) {
+ TCGv_i64 cb_msb = tcg_temp_new_i64();
+ if (is_add) {
+ tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero);
+ tcg_gen_xor_i64(cb, in1, in2);
+ } else {
+ /* See do_sub, !is_b. */
+ TCGv_i64 one = tcg_constant_i64(1);
+ tcg_gen_sub2_i64(dest, cb_msb, in1, one, in2, ctx->zero);
+ tcg_gen_eqv_i64(cb, in1, in2);
+ }
+ tcg_gen_xor_i64(cb, cb, dest);
+ tcg_gen_extract2_i64(cb, cb, cb_msb, 1);
+ } else {
+ if (is_add) {
+ tcg_gen_add_i64(dest, in1, in2);
+ tcg_gen_xor_i64(cb, in1, in2);
+ } else {
+ tcg_gen_sub_i64(dest, in1, in2);
+ tcg_gen_eqv_i64(cb, in1, in2);
+ }
+ tcg_gen_xor_i64(cb, cb, dest);
+ tcg_gen_shri_i64(cb, cb, 1);
+ }
+
+ tcg_gen_andi_i64(cb, cb, test_cb);
+ cond = cond_make_0_tmp(cf & 1 ? TCG_COND_EQ : TCG_COND_NE, cb);
+ }
+
+ if (is_tc) {
+ TCGv_i64 tmp = tcg_temp_new_i64();
+ tcg_gen_setcond_i64(cond.c, tmp, cond.a0, cond.a1);
+ gen_helper_tcond(tcg_env, tmp);
+ }
+ save_gpr(ctx, rt, dest);
+
+ cond_free(&ctx->null_cond);
+ ctx->null_cond = cond;
}
#ifndef CONFIG_USER_ONLY
@@ -2748,14 +2746,24 @@ static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf_d *a)
static bool trans_uxor(DisasContext *ctx, arg_rrr_cf_d *a)
{
- TCGv_i64 tcg_r1, tcg_r2;
+ TCGv_i64 tcg_r1, tcg_r2, dest;
if (a->cf) {
nullify_over(ctx);
}
+
tcg_r1 = load_gpr(ctx, a->r1);
tcg_r2 = load_gpr(ctx, a->r2);
- do_unit(ctx, a->t, tcg_r1, tcg_r2, a->cf, a->d, false, tcg_gen_xor_i64);
+ dest = dest_gpr(ctx, a->t);
+
+ tcg_gen_xor_i64(dest, tcg_r1, tcg_r2);
+ save_gpr(ctx, a->t, dest);
+
+ cond_free(&ctx->null_cond);
+ if (a->cf) {
+ ctx->null_cond = do_unit_zero_cond(a->cf, a->d, dest);
+ }
+
return nullify_end(ctx);
}
@@ -2790,7 +2798,7 @@ static bool do_uaddcm(DisasContext *ctx, arg_rrr_cf_d *a, bool is_tc)
tcg_r2 = load_gpr(ctx, a->r2);
tmp = tcg_temp_new_i64();
tcg_gen_not_i64(tmp, tcg_r2);
- do_unit(ctx, a->t, tcg_r1, tmp, a->cf, a->d, is_tc, tcg_gen_add_i64);
+ do_unit_addsub(ctx, a->t, tcg_r1, tmp, a->cf, a->d, is_tc, true);
return nullify_end(ctx);
}
@@ -2817,8 +2825,8 @@ static bool do_dcor(DisasContext *ctx, arg_rr_cf_d *a, bool is_i)
}
tcg_gen_andi_i64(tmp, tmp, (uint64_t)0x1111111111111111ull);
tcg_gen_muli_i64(tmp, tmp, 6);
- do_unit(ctx, a->t, load_gpr(ctx, a->r), tmp, a->cf, a->d, false,
- is_i ? tcg_gen_add_i64 : tcg_gen_sub_i64);
+ do_unit_addsub(ctx, a->t, load_gpr(ctx, a->r), tmp,
+ a->cf, a->d, false, is_i);
return nullify_end(ctx);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 12/18] target/hppa: Squash d for pa1.x during decode
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (10 preceding siblings ...)
2024-03-29 22:31 ` [PULL 11/18] target/hppa: Fix unit carry conditions Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 13/18] target/hppa: Replace c with uv in do_cond Richard Henderson
` (6 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
The cond_need_ext predicate was created while we still had a
32-bit compilation mode. It now makes more sense to treat D
as an absolute indicator of a 64-bit operation.
Tested-by: Helge Deller <deller@gmx.de>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/insns.decode | 20 +++++++++++++-------
target/hppa/translate.c | 38 ++++++++++++++++++++------------------
2 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index f58455dfdb..6a74cf23cd 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -57,6 +57,9 @@
%neg_to_m 0:1 !function=neg_to_m
%a_to_m 2:1 !function=neg_to_m
%cmpbid_c 13:2 !function=cmpbid_c
+%d_5 5:1 !function=pa20_d
+%d_11 11:1 !function=pa20_d
+%d_13 13:1 !function=pa20_d
####
# Argument set definitions
@@ -84,15 +87,16 @@
# Format definitions
####
-@rr_cf_d ...... r:5 ..... cf:4 ...... d:1 t:5 &rr_cf_d
+@rr_cf_d ...... r:5 ..... cf:4 ...... . t:5 &rr_cf_d d=%d_5
@rrr ...... r2:5 r1:5 .... ....... t:5 &rrr
@rrr_cf ...... r2:5 r1:5 cf:4 ....... t:5 &rrr_cf
-@rrr_cf_d ...... r2:5 r1:5 cf:4 ...... d:1 t:5 &rrr_cf_d
+@rrr_cf_d ...... r2:5 r1:5 cf:4 ...... . t:5 &rrr_cf_d d=%d_5
@rrr_sh ...... r2:5 r1:5 ........ sh:2 . t:5 &rrr_sh
-@rrr_cf_d_sh ...... r2:5 r1:5 cf:4 .... sh:2 d:1 t:5 &rrr_cf_d_sh
-@rrr_cf_d_sh0 ...... r2:5 r1:5 cf:4 ...... d:1 t:5 &rrr_cf_d_sh sh=0
+@rrr_cf_d_sh ...... r2:5 r1:5 cf:4 .... sh:2 . t:5 &rrr_cf_d_sh d=%d_5
+@rrr_cf_d_sh0 ...... r2:5 r1:5 cf:4 ...... . t:5 &rrr_cf_d_sh d=%d_5 sh=0
@rri_cf ...... r:5 t:5 cf:4 . ........... &rri_cf i=%lowsign_11
-@rri_cf_d ...... r:5 t:5 cf:4 d:1 ........... &rri_cf_d i=%lowsign_11
+@rri_cf_d ...... r:5 t:5 cf:4 . ........... \
+ &rri_cf_d d=%d_11 i=%lowsign_11
@rrb_cf ...... r2:5 r1:5 c:3 ........... n:1 . \
&rrb_c_f disp=%assemble_12
@@ -368,8 +372,10 @@ fmpysub_d 100110 ..... ..... ..... ..... 1 ..... @mpyadd
# Conditional Branches
####
-bb_sar 110000 00000 r:5 c:1 1 d:1 ........... n:1 . disp=%assemble_12
-bb_imm 110001 p:5 r:5 c:1 1 d:1 ........... n:1 . disp=%assemble_12
+bb_sar 110000 00000 r:5 c:1 1 . ........... n:1 . \
+ disp=%assemble_12 d=%d_13
+bb_imm 110001 p:5 r:5 c:1 1 . ........... n:1 . \
+ disp=%assemble_12 d=%d_13
movb 110010 ..... ..... ... ........... . . @rrb_cf f=0
movbi 110011 ..... ..... ... ........... . . @rib_cf f=0
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 99c5c4cbca..a70d644c0b 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -200,6 +200,14 @@ static int cmpbid_c(DisasContext *ctx, int val)
return val ? val : 4; /* 0 == "*<<" */
}
+/*
+ * In many places pa1.x did not decode the bit that later became
+ * the pa2.0 D bit. Suppress D unless the cpu is pa2.0.
+ */
+static int pa20_d(DisasContext *ctx, int val)
+{
+ return ctx->is_pa20 & val;
+}
/* Include the auto-generated decoder. */
#include "decode-insns.c.inc"
@@ -693,12 +701,6 @@ static bool cond_need_cb(int c)
return c == 4 || c == 5;
}
-/* Need extensions from TCGv_i32 to TCGv_i64. */
-static bool cond_need_ext(DisasContext *ctx, bool d)
-{
- return !(ctx->is_pa20 && d);
-}
-
/*
* Compute conditional for arithmetic. See Page 5-3, Table 5-1, of
* the Parisc 1.1 Architecture Reference Manual for details.
@@ -715,7 +717,7 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d,
cond = cond_make_f();
break;
case 1: /* = / <> (Z / !Z) */
- if (cond_need_ext(ctx, d)) {
+ if (!d) {
tmp = tcg_temp_new_i64();
tcg_gen_ext32u_i64(tmp, res);
res = tmp;
@@ -725,7 +727,7 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d,
case 2: /* < / >= (N ^ V / !(N ^ V) */
tmp = tcg_temp_new_i64();
tcg_gen_xor_i64(tmp, res, sv);
- if (cond_need_ext(ctx, d)) {
+ if (!d) {
tcg_gen_ext32s_i64(tmp, tmp);
}
cond = cond_make_0_tmp(TCG_COND_LT, tmp);
@@ -742,7 +744,7 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d,
*/
tmp = tcg_temp_new_i64();
tcg_gen_eqv_i64(tmp, res, sv);
- if (cond_need_ext(ctx, d)) {
+ if (!d) {
tcg_gen_sextract_i64(tmp, tmp, 31, 1);
tcg_gen_and_i64(tmp, tmp, res);
tcg_gen_ext32u_i64(tmp, tmp);
@@ -760,13 +762,13 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d,
tmp = tcg_temp_new_i64();
tcg_gen_neg_i64(tmp, cb_msb);
tcg_gen_and_i64(tmp, tmp, res);
- if (cond_need_ext(ctx, d)) {
+ if (!d) {
tcg_gen_ext32u_i64(tmp, tmp);
}
cond = cond_make_0_tmp(TCG_COND_EQ, tmp);
break;
case 6: /* SV / NSV (V / !V) */
- if (cond_need_ext(ctx, d)) {
+ if (!d) {
tmp = tcg_temp_new_i64();
tcg_gen_ext32s_i64(tmp, sv);
sv = tmp;
@@ -827,7 +829,7 @@ static DisasCond do_sub_cond(DisasContext *ctx, unsigned cf, bool d,
if (cf & 1) {
tc = tcg_invert_cond(tc);
}
- if (cond_need_ext(ctx, d)) {
+ if (!d) {
TCGv_i64 t1 = tcg_temp_new_i64();
TCGv_i64 t2 = tcg_temp_new_i64();
@@ -904,7 +906,7 @@ static DisasCond do_log_cond(DisasContext *ctx, unsigned cf, bool d,
g_assert_not_reached();
}
- if (cond_need_ext(ctx, d)) {
+ if (!d) {
TCGv_i64 tmp = tcg_temp_new_i64();
if (ext_uns) {
@@ -979,7 +981,7 @@ static DisasCond do_unit_zero_cond(unsigned cf, bool d, TCGv_i64 res)
static TCGv_i64 get_carry(DisasContext *ctx, bool d,
TCGv_i64 cb, TCGv_i64 cb_msb)
{
- if (cond_need_ext(ctx, d)) {
+ if (!d) {
TCGv_i64 t = tcg_temp_new_i64();
tcg_gen_extract_i64(t, cb, 32, 1);
return t;
@@ -3448,12 +3450,12 @@ static bool trans_bb_sar(DisasContext *ctx, arg_bb_sar *a)
tmp = tcg_temp_new_i64();
tcg_r = load_gpr(ctx, a->r);
- if (cond_need_ext(ctx, a->d)) {
+ if (a->d) {
+ tcg_gen_shl_i64(tmp, tcg_r, cpu_sar);
+ } else {
/* Force shift into [32,63] */
tcg_gen_ori_i64(tmp, cpu_sar, 32);
tcg_gen_shl_i64(tmp, tcg_r, tmp);
- } else {
- tcg_gen_shl_i64(tmp, tcg_r, cpu_sar);
}
cond = cond_make_0_tmp(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
@@ -3470,7 +3472,7 @@ static bool trans_bb_imm(DisasContext *ctx, arg_bb_imm *a)
tmp = tcg_temp_new_i64();
tcg_r = load_gpr(ctx, a->r);
- p = a->p | (cond_need_ext(ctx, a->d) ? 32 : 0);
+ p = a->p | (a->d ? 0 : 32);
tcg_gen_shli_i64(tmp, tcg_r, p);
cond = cond_make_0(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 13/18] target/hppa: Replace c with uv in do_cond
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (11 preceding siblings ...)
2024-03-29 22:31 ` [PULL 12/18] target/hppa: Squash d for pa1.x during decode Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 14/18] target/hppa: Fix overflow computation for shladd Richard Henderson
` (5 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
Prepare for proper indication of shladd unsigned overflow.
The UV indicator will be zero/not-zero instead of a single bit.
Tested-by: Helge Deller <deller@gmx.de>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index a70d644c0b..9d31ef5764 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -707,7 +707,7 @@ static bool cond_need_cb(int c)
*/
static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d,
- TCGv_i64 res, TCGv_i64 cb_msb, TCGv_i64 sv)
+ TCGv_i64 res, TCGv_i64 uv, TCGv_i64 sv)
{
DisasCond cond;
TCGv_i64 tmp;
@@ -754,14 +754,12 @@ static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d,
}
cond = cond_make_0_tmp(TCG_COND_EQ, tmp);
break;
- case 4: /* NUV / UV (!C / C) */
- /* Only bit 0 of cb_msb is ever set. */
- cond = cond_make_0(TCG_COND_EQ, cb_msb);
+ case 4: /* NUV / UV (!UV / UV) */
+ cond = cond_make_0(TCG_COND_EQ, uv);
break;
- case 5: /* ZNV / VNZ (!C | Z / C & !Z) */
+ case 5: /* ZNV / VNZ (!UV | Z / UV & !Z) */
tmp = tcg_temp_new_i64();
- tcg_gen_neg_i64(tmp, cb_msb);
- tcg_gen_and_i64(tmp, tmp, res);
+ tcg_gen_movcond_i64(TCG_COND_EQ, tmp, uv, ctx->zero, ctx->zero, res);
if (!d) {
tcg_gen_ext32u_i64(tmp, tmp);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 14/18] target/hppa: Fix overflow computation for shladd
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (12 preceding siblings ...)
2024-03-29 22:31 ` [PULL 13/18] target/hppa: Replace c with uv in do_cond Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 15/18] target/hppa: Generate getshadowregs inline Richard Henderson
` (4 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
Overflow indicator should include the effect of the shift step.
We had previously left ??? comments about the issue.
Tested-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 84 +++++++++++++++++++++++++++++++----------
1 file changed, 65 insertions(+), 19 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 9d31ef5764..6da9503f33 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -994,7 +994,8 @@ static TCGv_i64 get_psw_carry(DisasContext *ctx, bool d)
/* Compute signed overflow for addition. */
static TCGv_i64 do_add_sv(DisasContext *ctx, TCGv_i64 res,
- TCGv_i64 in1, TCGv_i64 in2)
+ TCGv_i64 in1, TCGv_i64 in2,
+ TCGv_i64 orig_in1, int shift, bool d)
{
TCGv_i64 sv = tcg_temp_new_i64();
TCGv_i64 tmp = tcg_temp_new_i64();
@@ -1003,9 +1004,49 @@ static TCGv_i64 do_add_sv(DisasContext *ctx, TCGv_i64 res,
tcg_gen_xor_i64(tmp, in1, in2);
tcg_gen_andc_i64(sv, sv, tmp);
+ switch (shift) {
+ case 0:
+ break;
+ case 1:
+ /* Shift left by one and compare the sign. */
+ tcg_gen_add_i64(tmp, orig_in1, orig_in1);
+ tcg_gen_xor_i64(tmp, tmp, orig_in1);
+ /* Incorporate into the overflow. */
+ tcg_gen_or_i64(sv, sv, tmp);
+ break;
+ default:
+ {
+ int sign_bit = d ? 63 : 31;
+
+ /* Compare the sign against all lower bits. */
+ tcg_gen_sextract_i64(tmp, orig_in1, sign_bit, 1);
+ tcg_gen_xor_i64(tmp, tmp, orig_in1);
+ /*
+ * If one of the bits shifting into or through the sign
+ * differs, then we have overflow.
+ */
+ tcg_gen_extract_i64(tmp, tmp, sign_bit - shift, shift);
+ tcg_gen_movcond_i64(TCG_COND_NE, sv, tmp, ctx->zero,
+ tcg_constant_i64(-1), sv);
+ }
+ }
return sv;
}
+/* Compute unsigned overflow for addition. */
+static TCGv_i64 do_add_uv(DisasContext *ctx, TCGv_i64 cb, TCGv_i64 cb_msb,
+ TCGv_i64 in1, int shift, bool d)
+{
+ if (shift == 0) {
+ return get_carry(ctx, d, cb, cb_msb);
+ } else {
+ TCGv_i64 tmp = tcg_temp_new_i64();
+ tcg_gen_extract_i64(tmp, in1, (d ? 63 : 31) - shift, shift);
+ tcg_gen_or_i64(tmp, tmp, get_carry(ctx, d, cb, cb_msb));
+ return tmp;
+ }
+}
+
/* Compute signed overflow for subtraction. */
static TCGv_i64 do_sub_sv(DisasContext *ctx, TCGv_i64 res,
TCGv_i64 in1, TCGv_i64 in2)
@@ -1020,19 +1061,19 @@ static TCGv_i64 do_sub_sv(DisasContext *ctx, TCGv_i64 res,
return sv;
}
-static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
+static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 orig_in1,
TCGv_i64 in2, unsigned shift, bool is_l,
bool is_tsv, bool is_tc, bool is_c, unsigned cf, bool d)
{
- TCGv_i64 dest, cb, cb_msb, cb_cond, sv, tmp;
+ TCGv_i64 dest, cb, cb_msb, in1, uv, sv, tmp;
unsigned c = cf >> 1;
DisasCond cond;
dest = tcg_temp_new_i64();
cb = NULL;
cb_msb = NULL;
- cb_cond = NULL;
+ in1 = orig_in1;
if (shift) {
tmp = tcg_temp_new_i64();
tcg_gen_shli_i64(tmp, in1, shift);
@@ -1050,9 +1091,6 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
}
tcg_gen_xor_i64(cb, in1, in2);
tcg_gen_xor_i64(cb, cb, dest);
- if (cond_need_cb(c)) {
- cb_cond = get_carry(ctx, d, cb, cb_msb);
- }
} else {
tcg_gen_add_i64(dest, in1, in2);
if (is_c) {
@@ -1063,18 +1101,23 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
/* Compute signed overflow if required. */
sv = NULL;
if (is_tsv || cond_need_sv(c)) {
- sv = do_add_sv(ctx, dest, in1, in2);
+ sv = do_add_sv(ctx, dest, in1, in2, orig_in1, shift, d);
if (is_tsv) {
if (!d) {
tcg_gen_ext32s_i64(sv, sv);
}
- /* ??? Need to include overflow from shift. */
gen_helper_tsv(tcg_env, sv);
}
}
+ /* Compute unsigned overflow if required. */
+ uv = NULL;
+ if (cond_need_cb(c)) {
+ uv = do_add_uv(ctx, cb, cb_msb, orig_in1, shift, d);
+ }
+
/* Emit any conditional trap before any writeback. */
- cond = do_cond(ctx, cf, d, dest, cb_cond, sv);
+ cond = do_cond(ctx, cf, d, dest, uv, sv);
if (is_tc) {
tmp = tcg_temp_new_i64();
tcg_gen_setcond_i64(cond.c, tmp, cond.a0, cond.a1);
@@ -2843,7 +2886,6 @@ static bool trans_dcor_i(DisasContext *ctx, arg_rr_cf_d *a)
static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
{
TCGv_i64 dest, add1, add2, addc, in1, in2;
- TCGv_i64 cout;
nullify_over(ctx);
@@ -2880,19 +2922,23 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
tcg_gen_xor_i64(cpu_psw_cb, add1, add2);
tcg_gen_xor_i64(cpu_psw_cb, cpu_psw_cb, dest);
- /* Write back PSW[V] for the division step. */
- cout = get_psw_carry(ctx, false);
- tcg_gen_neg_i64(cpu_psw_v, cout);
+ /*
+ * Write back PSW[V] for the division step.
+ * Shift cb{8} from where it lives in bit 32 to bit 31,
+ * so that it overlaps r2{32} in bit 31.
+ */
+ tcg_gen_shri_i64(cpu_psw_v, cpu_psw_cb, 1);
tcg_gen_xor_i64(cpu_psw_v, cpu_psw_v, in2);
/* Install the new nullification. */
if (a->cf) {
- TCGv_i64 sv = NULL;
+ TCGv_i64 sv = NULL, uv = NULL;
if (cond_need_sv(a->cf >> 1)) {
- /* ??? The lshift is supposed to contribute to overflow. */
- sv = do_add_sv(ctx, dest, add1, add2);
+ sv = do_add_sv(ctx, dest, add1, add2, in1, 1, false);
+ } else if (cond_need_cb(a->cf >> 1)) {
+ uv = do_add_uv(ctx, cpu_psw_cb, NULL, in1, 1, false);
}
- ctx->null_cond = do_cond(ctx, a->cf, false, dest, cout, sv);
+ ctx->null_cond = do_cond(ctx, a->cf, false, dest, uv, sv);
}
return nullify_end(ctx);
@@ -3419,7 +3465,7 @@ static bool do_addb(DisasContext *ctx, unsigned r, TCGv_i64 in1,
tcg_gen_add_i64(dest, in1, in2);
}
if (cond_need_sv(c)) {
- sv = do_add_sv(ctx, dest, in1, in2);
+ sv = do_add_sv(ctx, dest, in1, in2, in1, 0, d);
}
cond = do_cond(ctx, c * 2 + f, d, dest, cb_cond, sv);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 15/18] target/hppa: Generate getshadowregs inline
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (13 preceding siblings ...)
2024-03-29 22:31 ` [PULL 14/18] target/hppa: Fix overflow computation for shladd Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 16/18] target/hppa: Move diag argument handling to decodetree Richard Henderson
` (3 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
This operation is trivial and does not require a helper.
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/helper.h | 1 -
target/hppa/sys_helper.c | 4 ++--
target/hppa/translate.c | 17 +++++++++++++----
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 8fd7ba65d8..5900fd70bc 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -86,7 +86,6 @@ DEF_HELPER_FLAGS_0(read_interval_timer, TCG_CALL_NO_RWG, tl)
#ifndef CONFIG_USER_ONLY
DEF_HELPER_1(halt, noreturn, env)
DEF_HELPER_1(reset, noreturn, env)
-DEF_HELPER_1(getshadowregs, void, env)
DEF_HELPER_1(rfi, void, env)
DEF_HELPER_1(rfi_r, void, env)
DEF_HELPER_FLAGS_2(write_interval_timer, TCG_CALL_NO_RWG, void, env, tl)
diff --git a/target/hppa/sys_helper.c b/target/hppa/sys_helper.c
index 4a31748342..208e51c086 100644
--- a/target/hppa/sys_helper.c
+++ b/target/hppa/sys_helper.c
@@ -95,7 +95,7 @@ void HELPER(rfi)(CPUHPPAState *env)
cpu_hppa_put_psw(env, env->cr[CR_IPSW]);
}
-void HELPER(getshadowregs)(CPUHPPAState *env)
+static void getshadowregs(CPUHPPAState *env)
{
env->gr[1] = env->shadow[0];
env->gr[8] = env->shadow[1];
@@ -108,7 +108,7 @@ void HELPER(getshadowregs)(CPUHPPAState *env)
void HELPER(rfi_r)(CPUHPPAState *env)
{
- helper_getshadowregs(env);
+ getshadowregs(env);
helper_rfi(env);
}
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 6da9503f33..29e4a64e40 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2385,14 +2385,23 @@ static bool trans_reset(DisasContext *ctx, arg_reset *a)
#endif
}
-static bool trans_getshadowregs(DisasContext *ctx, arg_getshadowregs *a)
+static bool do_getshadowregs(DisasContext *ctx)
{
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
-#ifndef CONFIG_USER_ONLY
nullify_over(ctx);
- gen_helper_getshadowregs(tcg_env);
+ tcg_gen_ld_i64(cpu_gr[1], tcg_env, offsetof(CPUHPPAState, shadow[0]));
+ tcg_gen_ld_i64(cpu_gr[8], tcg_env, offsetof(CPUHPPAState, shadow[1]));
+ tcg_gen_ld_i64(cpu_gr[9], tcg_env, offsetof(CPUHPPAState, shadow[2]));
+ tcg_gen_ld_i64(cpu_gr[16], tcg_env, offsetof(CPUHPPAState, shadow[3]));
+ tcg_gen_ld_i64(cpu_gr[17], tcg_env, offsetof(CPUHPPAState, shadow[4]));
+ tcg_gen_ld_i64(cpu_gr[24], tcg_env, offsetof(CPUHPPAState, shadow[5]));
+ tcg_gen_ld_i64(cpu_gr[25], tcg_env, offsetof(CPUHPPAState, shadow[6]));
return nullify_end(ctx);
-#endif
+}
+
+static bool trans_getshadowregs(DisasContext *ctx, arg_getshadowregs *a)
+{
+ return do_getshadowregs(ctx);
}
static bool trans_nop_addrx(DisasContext *ctx, arg_ldst *a)
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 16/18] target/hppa: Move diag argument handling to decodetree
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (14 preceding siblings ...)
2024-03-29 22:31 ` [PULL 15/18] target/hppa: Generate getshadowregs inline Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 17/18] target/hppa: Add diag instructions to set/restore shadow registers Richard Henderson
` (2 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller
Split trans_diag into per-operation functions.
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/insns.decode | 8 +++++++-
target/hppa/translate.c | 34 +++++++++++++++++++++-------------
2 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 6a74cf23cd..9f6ffd8e2c 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -634,4 +634,10 @@ fdiv_d 001110 ..... ..... 011 ..... ... ..... @f0e_d_3
xmpyu 001110 ..... ..... 010 .0111 .00 t:5 r1=%ra64 r2=%rb64
# diag
-diag 000101 i:26
+{
+ [
+ diag_btlb 000101 00 0000 0000 0000 0001 0000 0000
+ diag_cout 000101 00 0000 0000 0000 0001 0000 0001
+ ]
+ diag_unimp 000101 i:26
+}
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 29e4a64e40..42dd3f2c8d 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -4572,23 +4572,31 @@ static bool trans_fmpyfadd_d(DisasContext *ctx, arg_fmpyfadd_d *a)
return nullify_end(ctx);
}
-static bool trans_diag(DisasContext *ctx, arg_diag *a)
+/* Emulate PDC BTLB, called by SeaBIOS-hppa */
+static bool trans_diag_btlb(DisasContext *ctx, arg_diag_btlb *a)
{
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
- if (a->i == 0x100) {
- /* emulate PDC BTLB, called by SeaBIOS-hppa */
- nullify_over(ctx);
- gen_helper_diag_btlb(tcg_env);
- return nullify_end(ctx);
- }
- if (a->i == 0x101) {
- /* print char in %r26 to first serial console, used by SeaBIOS-hppa */
- nullify_over(ctx);
- gen_helper_diag_console_output(tcg_env);
- return nullify_end(ctx);
- }
+ nullify_over(ctx);
+ gen_helper_diag_btlb(tcg_env);
+ return nullify_end(ctx);
#endif
+}
+
+/* Print char in %r26 to first serial console, used by SeaBIOS-hppa */
+static bool trans_diag_cout(DisasContext *ctx, arg_diag_cout *a)
+{
+ CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
+#ifndef CONFIG_USER_ONLY
+ nullify_over(ctx);
+ gen_helper_diag_console_output(tcg_env);
+ return nullify_end(ctx);
+#endif
+}
+
+static bool trans_diag_unimp(DisasContext *ctx, arg_diag_unimp *a)
+{
+ CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
qemu_log_mask(LOG_UNIMP, "DIAG opcode 0x%04x ignored\n", a->i);
return true;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 17/18] target/hppa: Add diag instructions to set/restore shadow registers
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (15 preceding siblings ...)
2024-03-29 22:31 ` [PULL 16/18] target/hppa: Move diag argument handling to decodetree Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-03-29 22:31 ` [PULL 18/18] target/hppa: Clear psw_n for BE on use_nullify_skip path Richard Henderson
2024-04-01 12:09 ` [PULL 00/18] target/hppa patch queue Peter Maydell
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Helge Deller, Helge Deller
From: Helge Deller <deller@kernel.org>
The 32-bit PA-7300LC (PCX-L2) CPU and the 64-bit PA8700 (PCX-W2) CPU
use different diag instructions to save or restore the CPU registers
to/from the shadow registers.
Implement those per-CPU architecture diag instructions to fix those
parts of the HP ODE testcases (L2DIAG and WDIAG, section 1) which test
the shadow registers.
Signed-off-by: Helge Deller <deller@gmx.de>
[rth: Use decodetree to distinguish cases]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Helge Deller <deller@gmx.de>
Tested-by: Helge Deller <deller@gmx.de>
---
target/hppa/insns.decode | 10 ++++++++++
target/hppa/translate.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 9f6ffd8e2c..71074a64c1 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -65,6 +65,8 @@
# Argument set definitions
####
+&empty
+
# All insns that need to form a virtual address should use this set.
&ldst t b x disp sp m scale size
@@ -638,6 +640,14 @@ xmpyu 001110 ..... ..... 010 .0111 .00 t:5 r1=%ra64 r2=%rb64
[
diag_btlb 000101 00 0000 0000 0000 0001 0000 0000
diag_cout 000101 00 0000 0000 0000 0001 0000 0001
+
+ # For 32-bit PA-7300LC (PCX-L2)
+ diag_getshadowregs_pa1 000101 00 0000 0000 0001 1010 0000 0000
+ diag_putshadowregs_pa1 000101 00 0000 0000 0001 1010 0100 0000
+
+ # For 64-bit PA8700 (PCX-W2)
+ diag_getshadowregs_pa2 000101 00 0111 1000 0001 1000 0100 0000
+ diag_putshadowregs_pa2 000101 00 0111 0000 0001 1000 0100 0000
]
diag_unimp 000101 i:26
}
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 42dd3f2c8d..143818c2d9 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2399,6 +2399,20 @@ static bool do_getshadowregs(DisasContext *ctx)
return nullify_end(ctx);
}
+static bool do_putshadowregs(DisasContext *ctx)
+{
+ CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
+ nullify_over(ctx);
+ tcg_gen_st_i64(cpu_gr[1], tcg_env, offsetof(CPUHPPAState, shadow[0]));
+ tcg_gen_st_i64(cpu_gr[8], tcg_env, offsetof(CPUHPPAState, shadow[1]));
+ tcg_gen_st_i64(cpu_gr[9], tcg_env, offsetof(CPUHPPAState, shadow[2]));
+ tcg_gen_st_i64(cpu_gr[16], tcg_env, offsetof(CPUHPPAState, shadow[3]));
+ tcg_gen_st_i64(cpu_gr[17], tcg_env, offsetof(CPUHPPAState, shadow[4]));
+ tcg_gen_st_i64(cpu_gr[24], tcg_env, offsetof(CPUHPPAState, shadow[5]));
+ tcg_gen_st_i64(cpu_gr[25], tcg_env, offsetof(CPUHPPAState, shadow[6]));
+ return nullify_end(ctx);
+}
+
static bool trans_getshadowregs(DisasContext *ctx, arg_getshadowregs *a)
{
return do_getshadowregs(ctx);
@@ -4594,6 +4608,26 @@ static bool trans_diag_cout(DisasContext *ctx, arg_diag_cout *a)
#endif
}
+static bool trans_diag_getshadowregs_pa1(DisasContext *ctx, arg_empty *a)
+{
+ return !ctx->is_pa20 && do_getshadowregs(ctx);
+}
+
+static bool trans_diag_getshadowregs_pa2(DisasContext *ctx, arg_empty *a)
+{
+ return ctx->is_pa20 && do_getshadowregs(ctx);
+}
+
+static bool trans_diag_putshadowregs_pa1(DisasContext *ctx, arg_empty *a)
+{
+ return !ctx->is_pa20 && do_putshadowregs(ctx);
+}
+
+static bool trans_diag_putshadowregs_pa2(DisasContext *ctx, arg_empty *a)
+{
+ return ctx->is_pa20 && do_putshadowregs(ctx);
+}
+
static bool trans_diag_unimp(DisasContext *ctx, arg_diag_unimp *a)
{
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PULL 18/18] target/hppa: Clear psw_n for BE on use_nullify_skip path
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (16 preceding siblings ...)
2024-03-29 22:31 ` [PULL 17/18] target/hppa: Add diag instructions to set/restore shadow registers Richard Henderson
@ 2024-03-29 22:31 ` Richard Henderson
2024-04-01 12:09 ` [PULL 00/18] target/hppa patch queue Peter Maydell
18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-29 22:31 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Sven Schnelle, Philippe Mathieu-Daudé
Along this path we have already skipped the insn to be
nullified, so the subsequent insn should be executed.
Cc: qemu-stable@nongnu.org
Reported-by: Sven Schnelle <svens@stackframe.org>
Tested-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 143818c2d9..8a1a8bc3aa 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3948,6 +3948,7 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
copy_iaoq_entry(ctx, cpu_iaoq_b, -1, tmp);
tcg_gen_mov_i64(cpu_iasq_f, new_spc);
tcg_gen_mov_i64(cpu_iasq_b, cpu_iasq_f);
+ nullify_set(ctx, 0);
} else {
copy_iaoq_entry(ctx, cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
if (ctx->iaoq_b == -1) {
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PULL 00/18] target/hppa patch queue
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
` (17 preceding siblings ...)
2024-03-29 22:31 ` [PULL 18/18] target/hppa: Clear psw_n for BE on use_nullify_skip path Richard Henderson
@ 2024-04-01 12:09 ` Peter Maydell
18 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2024-04-01 12:09 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Fri, 29 Mar 2024 at 22:32, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The following changes since commit 5012e522aca161be5c141596c66e5cc6082538a9:
>
> Update version for v9.0.0-rc1 release (2024-03-26 19:46:55 +0000)
>
> are available in the Git repository at:
>
> https://gitlab.com/rth7680/qemu.git tags/pull-pa-20240329
>
> for you to fetch changes up to 4a3aa11e1fb25c28c24a43fd2835c429b00a463d:
>
> target/hppa: Clear psw_n for BE on use_nullify_skip path (2024-03-29 08:15:01 -1000)
>
> ----------------------------------------------------------------
> target/hppa: Fix BE,L set of sr0
> target/hppa: Fix B,GATE for wide mode
> target/hppa: Mark interval timer write as io
> target/hppa: Fix EIRR, EIEM versus icount
> target/hppa: Fix DCOR reconstruction of carry bits
> target/hppa: Fix unit carry conditions
> target/hppa: Fix overflow computation for shladd
> target/hppa: Add diag instructions to set/restore shadow registers
> target/hppa: Clear psw_n for BE on use_nullify_skip path
>
> ----------------------------------------------------------------
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/9.0
for any user-visible changes.
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2024-04-01 12:10 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-29 22:30 [PULL 00/18] target/hppa patch queue Richard Henderson
2024-03-29 22:30 ` [PULL 01/18] target/hppa: Fix BE,L set of sr0 Richard Henderson
2024-03-29 22:30 ` [PULL 02/18] target/hppa: Fix B,GATE for wide mode Richard Henderson
2024-03-29 22:30 ` [PULL 03/18] target/hppa: Handle unit conditions " Richard Henderson
2024-03-29 22:30 ` [PULL 04/18] target/hppa: Fix ADD/SUB trap on overflow for narrow mode Richard Henderson
2024-03-29 22:30 ` [PULL 05/18] target/hppa: Mark interval timer write as io Richard Henderson
2024-03-29 22:30 ` [PULL 06/18] target/hppa: Tidy read of interval timer Richard Henderson
2024-03-29 22:31 ` [PULL 07/18] target/hppa: Fix EIRR, EIEM versus icount Richard Henderson
2024-03-29 22:31 ` [PULL 08/18] target/hppa: Use gva_offset_mask() everywhere Richard Henderson
2024-03-29 22:31 ` [PULL 09/18] target/hppa: Fix DCOR reconstruction of carry bits Richard Henderson
2024-03-29 22:31 ` [PULL 10/18] target/hppa: Optimize UADDCM with no condition Richard Henderson
2024-03-29 22:31 ` [PULL 11/18] target/hppa: Fix unit carry conditions Richard Henderson
2024-03-29 22:31 ` [PULL 12/18] target/hppa: Squash d for pa1.x during decode Richard Henderson
2024-03-29 22:31 ` [PULL 13/18] target/hppa: Replace c with uv in do_cond Richard Henderson
2024-03-29 22:31 ` [PULL 14/18] target/hppa: Fix overflow computation for shladd Richard Henderson
2024-03-29 22:31 ` [PULL 15/18] target/hppa: Generate getshadowregs inline Richard Henderson
2024-03-29 22:31 ` [PULL 16/18] target/hppa: Move diag argument handling to decodetree Richard Henderson
2024-03-29 22:31 ` [PULL 17/18] target/hppa: Add diag instructions to set/restore shadow registers Richard Henderson
2024-03-29 22:31 ` [PULL 18/18] target/hppa: Clear psw_n for BE on use_nullify_skip path Richard Henderson
2024-04-01 12:09 ` [PULL 00/18] target/hppa patch queue Peter Maydell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).