* [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree
@ 2019-02-07 11:53 Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 01/19] target/hppa: Use DisasContextBase.is_jmp Richard Henderson
` (19 more replies)
0 siblings, 20 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
I started this last year, but only recently have found the time
to ferret out the bugs.
I've tested this vs the gcc execute.exp testsuite, against which
there are no regressions. It also continues to boot my old debian
sid installation.
I had not previously been aware, but I now know this fixes a bug
with respect to the purge data cache (PDC) instruction.
Helge or Sven, if you have a chance to do a bit more testing in
the next week, I would appreciate it. Otherwise we can fix any
other minor problems on mainline.
This is based on the target/hppa pull request from this week;
the whole tree can be found at
https://github.com/rth7680/qemu.git tgt-hppa
r~
Richard Henderson (19):
target/hppa: Use DisasContextBase.is_jmp
target/hppa: Begin using scripts/decodetree.py
target/hppa: Convert move to/from system registers
target/hppa: Convert remainder of system insns
target/hppa: Unify specializations of OR
target/hppa: Convert memory management insns
target/hppa: Convert arithmetic/logical insns
target/hppa: Convert indexed memory insns
target/hppa: Convert fp multiply-add
target/hppa: Convert conditional branches
target/hppa: Convert shift, extract, deposit insns
target/hppa: Convert direct and indirect branches
target/hppa: Convert arithmetic immediate insns
target/hppa: Convert offset memory insns
target/hppa: Convert fp indexed memory insns
target/hppa: Convert halt/reset insns
target/hppa: Convert fp fused multiply-add insns
target/hppa: Convert fp operate insns
target/hppa: Merge translate_one into hppa_tr_translate_insn
target/hppa/translate.c | 3218 +++++++++++++++----------------------
target/hppa/Makefile.objs | 8 +
target/hppa/insns.decode | 527 ++++++
3 files changed, 1802 insertions(+), 1951 deletions(-)
create mode 100644 target/hppa/insns.decode
--
2.17.2
^ permalink raw reply [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 01/19] target/hppa: Use DisasContextBase.is_jmp
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 02/19] target/hppa: Begin using scripts/decodetree.py Richard Henderson
` (18 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Instead of returning DisasJumpType, immediately store it.
Return true in preparation for conversion to the decodetree script.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 1011 ++++++++++++++++++++-------------------
1 file changed, 528 insertions(+), 483 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 51bfd9849d..a4f253a022 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -278,10 +278,6 @@ typedef struct DisasContext {
bool psw_n_nonzero;
} DisasContext;
-/* Target-specific return values from translate_one, indicating the
- state of the TB. Note that DISAS_NEXT indicates that we are not
- exiting the TB. */
-
/* We are not using a goto_tb (for whatever reason), but have updated
the iaq (for whatever reason), so don't do it again on exit. */
#define DISAS_IAQ_N_UPDATED DISAS_TARGET_0
@@ -296,8 +292,8 @@ typedef struct DisasContext {
typedef struct DisasInsn {
uint32_t insn, mask;
- DisasJumpType (*trans)(DisasContext *ctx, uint32_t insn,
- const struct DisasInsn *f);
+ bool (*trans)(DisasContext *ctx, uint32_t insn,
+ const struct DisasInsn *f);
union {
void (*ttt)(TCGv_reg, TCGv_reg, TCGv_reg);
void (*weww)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32);
@@ -666,9 +662,10 @@ static void nullify_set(DisasContext *ctx, bool x)
/* Mark the end of an instruction that may have been nullified.
This is the pair to nullify_over. */
-static DisasJumpType nullify_end(DisasContext *ctx, DisasJumpType status)
+static bool nullify_end(DisasContext *ctx)
{
TCGLabel *null_lab = ctx->null_lab;
+ DisasJumpType status = ctx->base.is_jmp;
/* For NEXT, NORETURN, STALE, we can easily continue (or exit).
For UPDATED, we cannot update on the nullified path. */
@@ -678,7 +675,7 @@ static DisasJumpType nullify_end(DisasContext *ctx, DisasJumpType status)
/* The current insn wasn't conditional or handled the condition
applied to it without a branch, so the (new) setting of
NULL_COND can be applied directly to the next insn. */
- return status;
+ return true;
}
ctx->null_lab = NULL;
@@ -696,9 +693,9 @@ static DisasJumpType nullify_end(DisasContext *ctx, DisasJumpType status)
ctx->null_cond = cond_make_n();
}
if (status == DISAS_NORETURN) {
- status = DISAS_NEXT;
+ ctx->base.is_jmp = DISAS_NEXT;
}
- return status;
+ return true;
}
static void copy_iaoq_entry(TCGv_reg dest, target_ureg ival, TCGv_reg vval)
@@ -722,41 +719,44 @@ static void gen_excp_1(int exception)
tcg_temp_free_i32(t);
}
-static DisasJumpType gen_excp(DisasContext *ctx, int exception)
+static void gen_excp(DisasContext *ctx, int exception)
{
copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_f, cpu_iaoq_f);
copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_b, cpu_iaoq_b);
nullify_save(ctx);
gen_excp_1(exception);
- return DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_NORETURN;
}
-static DisasJumpType gen_excp_iir(DisasContext *ctx, int exc)
+static bool gen_excp_iir(DisasContext *ctx, int exc)
{
- TCGv_reg tmp = tcg_const_reg(ctx->insn);
+ TCGv_reg tmp;
+
+ nullify_over(ctx);
+ tmp = tcg_const_reg(ctx->insn);
tcg_gen_st_reg(tmp, cpu_env, offsetof(CPUHPPAState, cr[CR_IIR]));
tcg_temp_free(tmp);
- return gen_excp(ctx, exc);
+ gen_excp(ctx, exc);
+ return nullify_end(ctx);
}
-static DisasJumpType gen_illegal(DisasContext *ctx)
+static bool gen_illegal(DisasContext *ctx)
{
- nullify_over(ctx);
- return nullify_end(ctx, gen_excp_iir(ctx, EXCP_ILL));
+ return gen_excp_iir(ctx, EXCP_ILL);
}
-#define CHECK_MOST_PRIVILEGED(EXCP) \
- do { \
- if (ctx->privilege != 0) { \
- nullify_over(ctx); \
- return nullify_end(ctx, gen_excp_iir(ctx, EXCP)); \
- } \
+#define CHECK_MOST_PRIVILEGED(EXCP) \
+ do { \
+ if (ctx->privilege != 0) { \
+ return gen_excp_iir(ctx, EXCP); \
+ } \
} while (0)
static bool use_goto_tb(DisasContext *ctx, target_ureg dest)
{
/* Suppress goto_tb in the case of single-steping and IO. */
- if ((tb_cflags(ctx->base.tb) & CF_LAST_IO) || ctx->base.singlestep_enabled) {
+ if ((tb_cflags(ctx->base.tb) & CF_LAST_IO)
+ || ctx->base.singlestep_enabled) {
return false;
}
return true;
@@ -1119,9 +1119,9 @@ static TCGv_reg do_sub_sv(DisasContext *ctx, TCGv_reg res,
return sv;
}
-static DisasJumpType do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1,
- TCGv_reg in2, unsigned shift, bool is_l,
- bool is_tsv, bool is_tc, bool is_c, unsigned cf)
+static void do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1,
+ TCGv_reg in2, unsigned shift, bool is_l,
+ bool is_tsv, bool is_tc, bool is_c, unsigned cf)
{
TCGv_reg dest, cb, cb_msb, sv, tmp;
unsigned c = cf >> 1;
@@ -1188,12 +1188,11 @@ static DisasJumpType do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1,
/* Install the new nullification. */
cond_free(&ctx->null_cond);
ctx->null_cond = cond;
- return DISAS_NEXT;
}
-static DisasJumpType do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
- TCGv_reg in2, bool is_tsv, bool is_b,
- bool is_tc, unsigned cf)
+static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
+ TCGv_reg in2, bool is_tsv, bool is_b,
+ bool is_tc, unsigned cf)
{
TCGv_reg dest, sv, cb, cb_msb, zero, tmp;
unsigned c = cf >> 1;
@@ -1255,11 +1254,10 @@ static DisasJumpType do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
/* Install the new nullification. */
cond_free(&ctx->null_cond);
ctx->null_cond = cond;
- return DISAS_NEXT;
}
-static DisasJumpType do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
- TCGv_reg in2, unsigned cf)
+static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
+ TCGv_reg in2, unsigned cf)
{
TCGv_reg dest, sv;
DisasCond cond;
@@ -1284,12 +1282,11 @@ static DisasJumpType do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
/* Install the new nullification. */
cond_free(&ctx->null_cond);
ctx->null_cond = cond;
- return DISAS_NEXT;
}
-static DisasJumpType do_log(DisasContext *ctx, unsigned rt, TCGv_reg in1,
- TCGv_reg in2, unsigned cf,
- void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
+static void do_log(DisasContext *ctx, unsigned rt, TCGv_reg in1,
+ TCGv_reg in2, unsigned cf,
+ void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
{
TCGv_reg dest = dest_gpr(ctx, rt);
@@ -1302,12 +1299,11 @@ static DisasJumpType do_log(DisasContext *ctx, unsigned rt, TCGv_reg in1,
if (cf) {
ctx->null_cond = do_log_cond(cf, dest);
}
- return DISAS_NEXT;
}
-static DisasJumpType do_unit(DisasContext *ctx, unsigned rt, TCGv_reg in1,
- TCGv_reg in2, unsigned cf, bool is_tc,
- void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
+static void do_unit(DisasContext *ctx, unsigned rt, TCGv_reg in1,
+ TCGv_reg in2, unsigned cf, bool is_tc,
+ void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
{
TCGv_reg dest;
DisasCond cond;
@@ -1335,7 +1331,6 @@ static DisasJumpType do_unit(DisasContext *ctx, unsigned rt, TCGv_reg in1,
cond_free(&ctx->null_cond);
ctx->null_cond = cond;
}
- return DISAS_NEXT;
}
#ifndef CONFIG_USER_ONLY
@@ -1498,9 +1493,9 @@ static void do_store_64(DisasContext *ctx, TCGv_i64 src, unsigned rb,
#define do_store_reg do_store_32
#endif
-static DisasJumpType do_load(DisasContext *ctx, unsigned rt, unsigned rb,
- unsigned rx, int scale, target_sreg disp,
- unsigned sp, int modify, TCGMemOp mop)
+static void do_load(DisasContext *ctx, unsigned rt, unsigned rb,
+ unsigned rx, int scale, target_sreg disp,
+ unsigned sp, int modify, TCGMemOp mop)
{
TCGv_reg dest;
@@ -1516,12 +1511,12 @@ static DisasJumpType do_load(DisasContext *ctx, unsigned rt, unsigned rb,
do_load_reg(ctx, dest, rb, rx, scale, disp, sp, modify, mop);
save_gpr(ctx, rt, dest);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
- unsigned rx, int scale, target_sreg disp,
- unsigned sp, int modify)
+static void do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
+ unsigned rx, int scale, target_sreg disp,
+ unsigned sp, int modify)
{
TCGv_i32 tmp;
@@ -1536,12 +1531,12 @@ static DisasJumpType do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
gen_helper_loaded_fr0(cpu_env);
}
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
- unsigned rx, int scale, target_sreg disp,
- unsigned sp, int modify)
+static void do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
+ unsigned rx, int scale, target_sreg disp,
+ unsigned sp, int modify)
{
TCGv_i64 tmp;
@@ -1556,21 +1551,21 @@ static DisasJumpType do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
gen_helper_loaded_fr0(cpu_env);
}
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_store(DisasContext *ctx, unsigned rt, unsigned rb,
- target_sreg disp, unsigned sp,
- int modify, TCGMemOp mop)
+static void do_store(DisasContext *ctx, unsigned rt, unsigned rb,
+ target_sreg disp, unsigned sp,
+ int modify, TCGMemOp mop)
{
nullify_over(ctx);
do_store_reg(ctx, load_gpr(ctx, rt), rb, 0, 0, disp, sp, modify, mop);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
- unsigned rx, int scale, target_sreg disp,
- unsigned sp, int modify)
+static void do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
+ unsigned rx, int scale, target_sreg disp,
+ unsigned sp, int modify)
{
TCGv_i32 tmp;
@@ -1580,12 +1575,12 @@ static DisasJumpType do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
do_store_32(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUL);
tcg_temp_free_i32(tmp);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
- unsigned rx, int scale, target_sreg disp,
- unsigned sp, int modify)
+static void do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
+ unsigned rx, int scale, target_sreg disp,
+ unsigned sp, int modify)
{
TCGv_i64 tmp;
@@ -1595,11 +1590,11 @@ static DisasJumpType do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
do_store_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEQ);
tcg_temp_free_i64(tmp);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
- void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
+static void do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
+ void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
{
TCGv_i32 tmp;
@@ -1610,11 +1605,11 @@ static DisasJumpType do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
save_frw_i32(rt, tmp);
tcg_temp_free_i32(tmp);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
- void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
+static void do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
+ void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
{
TCGv_i32 dst;
TCGv_i64 src;
@@ -1628,11 +1623,11 @@ static DisasJumpType do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
tcg_temp_free_i64(src);
save_frw_i32(rt, dst);
tcg_temp_free_i32(dst);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
- void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
+static void do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
+ void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
{
TCGv_i64 tmp;
@@ -1643,11 +1638,11 @@ static DisasJumpType do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
save_frd(rt, tmp);
tcg_temp_free_i64(tmp);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
- void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
+static void do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
+ void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
{
TCGv_i32 src;
TCGv_i64 dst;
@@ -1661,13 +1656,12 @@ static DisasJumpType do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
tcg_temp_free_i32(src);
save_frd(rt, dst);
tcg_temp_free_i64(dst);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_fop_weww(DisasContext *ctx, unsigned rt,
- unsigned ra, unsigned rb,
- void (*func)(TCGv_i32, TCGv_env,
- TCGv_i32, TCGv_i32))
+static void do_fop_weww(DisasContext *ctx, unsigned rt,
+ unsigned ra, unsigned rb,
+ void (*func)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
{
TCGv_i32 a, b;
@@ -1680,13 +1674,12 @@ static DisasJumpType do_fop_weww(DisasContext *ctx, unsigned rt,
tcg_temp_free_i32(b);
save_frw_i32(rt, a);
tcg_temp_free_i32(a);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType do_fop_dedd(DisasContext *ctx, unsigned rt,
- unsigned ra, unsigned rb,
- void (*func)(TCGv_i64, TCGv_env,
- TCGv_i64, TCGv_i64))
+static void do_fop_dedd(DisasContext *ctx, unsigned rt,
+ unsigned ra, unsigned rb,
+ void (*func)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64))
{
TCGv_i64 a, b;
@@ -1699,13 +1692,13 @@ static DisasJumpType do_fop_dedd(DisasContext *ctx, unsigned rt,
tcg_temp_free_i64(b);
save_frd(rt, a);
tcg_temp_free_i64(a);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
/* Emit an unconditional branch to a direct target, which may or may not
have already had nullification handled. */
-static DisasJumpType do_dbranch(DisasContext *ctx, target_ureg dest,
- unsigned link, bool is_n)
+static void do_dbranch(DisasContext *ctx, target_ureg dest,
+ unsigned link, bool is_n)
{
if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
if (link != 0) {
@@ -1715,7 +1708,6 @@ static DisasJumpType do_dbranch(DisasContext *ctx, target_ureg dest,
if (is_n) {
ctx->null_cond.c = TCG_COND_ALWAYS;
}
- return DISAS_NEXT;
} else {
nullify_over(ctx);
@@ -1731,18 +1723,18 @@ static DisasJumpType do_dbranch(DisasContext *ctx, target_ureg dest,
gen_goto_tb(ctx, 0, ctx->iaoq_b, dest);
}
- nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
nullify_set(ctx, 0);
gen_goto_tb(ctx, 1, ctx->iaoq_b, ctx->iaoq_n);
- return DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_NORETURN;
}
}
/* Emit a conditional branch to a direct target. If the branch itself
is nullified, we should have already used nullify_over. */
-static DisasJumpType do_cbranch(DisasContext *ctx, target_sreg disp, bool is_n,
- DisasCond *cond)
+static void do_cbranch(DisasContext *ctx, target_sreg disp, bool is_n,
+ DisasCond *cond)
{
target_ureg dest = iaoq_dest(ctx, disp);
TCGLabel *taken = NULL;
@@ -1753,10 +1745,12 @@ static DisasJumpType do_cbranch(DisasContext *ctx, target_sreg disp, bool is_n,
/* Handle TRUE and NEVER as direct branches. */
if (c == TCG_COND_ALWAYS) {
- return do_dbranch(ctx, dest, 0, is_n && disp >= 0);
+ do_dbranch(ctx, dest, 0, is_n && disp >= 0);
+ return;
}
if (c == TCG_COND_NEVER) {
- return do_dbranch(ctx, ctx->iaoq_n, 0, is_n && disp < 0);
+ do_dbranch(ctx, ctx->iaoq_n, 0, is_n && disp < 0);
+ return;
}
taken = gen_new_label();
@@ -1799,16 +1793,16 @@ static DisasJumpType do_cbranch(DisasContext *ctx, target_sreg disp, bool is_n,
if (ctx->null_lab) {
gen_set_label(ctx->null_lab);
ctx->null_lab = NULL;
- return DISAS_IAQ_N_STALE;
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE;
} else {
- return DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_NORETURN;
}
}
/* Emit an unconditional branch to an indirect target. This handles
nullification of the branch itself. */
-static DisasJumpType do_ibranch(DisasContext *ctx, TCGv_reg dest,
- unsigned link, bool is_n)
+static void do_ibranch(DisasContext *ctx, TCGv_reg dest,
+ unsigned link, bool is_n)
{
TCGv_reg a0, a1, next, tmp;
TCGCond c;
@@ -1826,7 +1820,8 @@ static DisasJumpType do_ibranch(DisasContext *ctx, TCGv_reg dest,
tcg_gen_mov_reg(cpu_iaoq_f, next);
tcg_gen_addi_reg(cpu_iaoq_b, next, 4);
nullify_set(ctx, 0);
- return DISAS_IAQ_N_UPDATED;
+ ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
+ return;
}
ctx->null_cond.c = TCG_COND_ALWAYS;
}
@@ -1853,7 +1848,7 @@ static DisasJumpType do_ibranch(DisasContext *ctx, TCGv_reg dest,
tcg_gen_movi_reg(cpu_gr[link], ctx->iaoq_n);
}
tcg_gen_lookup_and_goto_ptr();
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
} else {
cond_prep(&ctx->null_cond);
c = ctx->null_cond.c;
@@ -1884,8 +1879,6 @@ static DisasJumpType do_ibranch(DisasContext *ctx, TCGv_reg dest,
cond_free(&ctx->null_cond);
}
}
-
- return DISAS_NEXT;
}
/* Implement
@@ -1926,7 +1919,7 @@ static TCGv_reg do_ibranch_priv(DisasContext *ctx, TCGv_reg offset)
in than the "be disp(sr2,r0)" instruction that probably sent us
here, is the easiest way to handle the branch delay slot on the
aforementioned BE. */
-static DisasJumpType do_page_zero(DisasContext *ctx)
+static void do_page_zero(DisasContext *ctx)
{
/* If by some means we get here with PSW[N]=1, that implies that
the B,GATE instruction would be skipped, and we'd fault on the
@@ -1954,56 +1947,56 @@ static DisasJumpType do_page_zero(DisasContext *ctx)
switch (ctx->iaoq_f & -4) {
case 0x00: /* Null pointer call */
gen_excp_1(EXCP_IMP);
- return DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_NORETURN;
+ break;
case 0xb0: /* LWS */
gen_excp_1(EXCP_SYSCALL_LWS);
- return DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_NORETURN;
+ break;
case 0xe0: /* SET_THREAD_POINTER */
tcg_gen_st_reg(cpu_gr[26], cpu_env, offsetof(CPUHPPAState, cr[27]));
tcg_gen_ori_reg(cpu_iaoq_f, cpu_gr[31], 3);
tcg_gen_addi_reg(cpu_iaoq_b, cpu_iaoq_f, 4);
- return DISAS_IAQ_N_UPDATED;
+ ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
+ break;
case 0x100: /* SYSCALL */
gen_excp_1(EXCP_SYSCALL);
- return DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_NORETURN;
+ break;
default:
do_sigill:
gen_excp_1(EXCP_ILL);
- return DISAS_NORETURN;
+ ctx->base.is_jmp = DISAS_NORETURN;
+ break;
}
}
#endif
-static DisasJumpType trans_nop(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_nop(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
cond_free(&ctx->null_cond);
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_break(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_break(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
- nullify_over(ctx);
- return nullify_end(ctx, gen_excp_iir(ctx, EXCP_BREAK));
+ return gen_excp_iir(ctx, EXCP_BREAK);
}
-static DisasJumpType trans_sync(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_sync(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
/* No point in nullifying the memory barrier. */
tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
cond_free(&ctx->null_cond);
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_mfia(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_mfia(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
TCGv_reg tmp = dest_gpr(ctx, rt);
@@ -2011,11 +2004,10 @@ static DisasJumpType trans_mfia(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, tmp);
cond_free(&ctx->null_cond);
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_mfsp(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_mfsp(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned rs = assemble_sr3(insn);
@@ -2031,16 +2023,14 @@ static DisasJumpType trans_mfsp(DisasContext *ctx, uint32_t insn,
tcg_temp_free_i64(t0);
cond_free(&ctx->null_cond);
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_mfctl(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_mfctl(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned ctl = extract32(insn, 21, 5);
TCGv_reg tmp;
- DisasJumpType ret;
switch (ctl) {
case CR_SAR:
@@ -2063,13 +2053,12 @@ static DisasJumpType trans_mfctl(DisasContext *ctx, uint32_t insn,
gen_io_start();
gen_helper_read_interval_timer(tmp);
gen_io_end();
- ret = DISAS_IAQ_N_STALE;
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE;
} else {
gen_helper_read_interval_timer(tmp);
- ret = DISAS_NEXT;
}
save_gpr(ctx, rt, tmp);
- return nullify_end(ctx, ret);
+ return nullify_end(ctx);
case 26:
case 27:
break;
@@ -2085,11 +2074,10 @@ static DisasJumpType trans_mfctl(DisasContext *ctx, uint32_t insn,
done:
cond_free(&ctx->null_cond);
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_mtsp(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_mtsp(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rr = extract32(insn, 16, 5);
unsigned rs = assemble_sr3(insn);
@@ -2112,11 +2100,10 @@ static DisasJumpType trans_mtsp(DisasContext *ctx, uint32_t insn,
}
tcg_temp_free_i64(t64);
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_mtctl(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_mtctl(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rin = extract32(insn, 16, 5);
unsigned ctl = extract32(insn, 21, 5);
@@ -2130,7 +2117,7 @@ static DisasJumpType trans_mtctl(DisasContext *ctx, uint32_t insn,
tcg_temp_free(tmp);
cond_free(&ctx->null_cond);
- return DISAS_NEXT;
+ return true;
}
/* All other control registers are privileged or read-only. */
@@ -2139,8 +2126,6 @@ static DisasJumpType trans_mtctl(DisasContext *ctx, uint32_t insn,
#ifdef CONFIG_USER_ONLY
g_assert_not_reached();
#else
- DisasJumpType ret = DISAS_NEXT;
-
nullify_over(ctx);
switch (ctl) {
case CR_IT:
@@ -2151,7 +2136,7 @@ static DisasJumpType trans_mtctl(DisasContext *ctx, uint32_t insn,
break;
case CR_EIEM:
gen_helper_write_eiem(cpu_env, reg);
- ret = DISAS_IAQ_N_STALE_EXIT;
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
break;
case CR_IIASQ:
@@ -2170,12 +2155,11 @@ static DisasJumpType trans_mtctl(DisasContext *ctx, uint32_t insn,
tcg_gen_st_reg(reg, cpu_env, offsetof(CPUHPPAState, cr[ctl]));
break;
}
- return nullify_end(ctx, ret);
+ return nullify_end(ctx);
#endif
}
-static DisasJumpType trans_mtsarcm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_mtsarcm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rin = extract32(insn, 16, 5);
TCGv_reg tmp = tcg_temp_new();
@@ -2186,11 +2170,10 @@ static DisasJumpType trans_mtsarcm(DisasContext *ctx, uint32_t insn,
tcg_temp_free(tmp);
cond_free(&ctx->null_cond);
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_ldsid(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ldsid(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
TCGv_reg dest = dest_gpr(ctx, rt);
@@ -2212,7 +2195,7 @@ static DisasJumpType trans_ldsid(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, dest);
cond_free(&ctx->null_cond);
- return DISAS_NEXT;
+ return true;
}
#ifndef CONFIG_USER_ONLY
@@ -2230,8 +2213,7 @@ static target_ureg extract_sm_imm(uint32_t insn)
return val;
}
-static DisasJumpType trans_rsm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_rsm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
target_ureg sm = extract_sm_imm(insn);
@@ -2247,11 +2229,11 @@ static DisasJumpType trans_rsm(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, tmp);
/* Exit the TB to recognize new interrupts, e.g. PSW_M. */
- return nullify_end(ctx, DISAS_IAQ_N_STALE_EXIT);
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
+ return nullify_end(ctx);
}
-static DisasJumpType trans_ssm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ssm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
target_ureg sm = extract_sm_imm(insn);
@@ -2267,11 +2249,11 @@ static DisasJumpType trans_ssm(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, tmp);
/* Exit the TB to recognize new interrupts, e.g. PSW_I. */
- return nullify_end(ctx, DISAS_IAQ_N_STALE_EXIT);
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
+ return nullify_end(ctx);
}
-static DisasJumpType trans_mtsm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_mtsm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rr = extract32(insn, 16, 5);
TCGv_reg tmp, reg;
@@ -2284,11 +2266,11 @@ static DisasJumpType trans_mtsm(DisasContext *ctx, uint32_t insn,
gen_helper_swap_system_mask(tmp, cpu_env, reg);
/* Exit the TB to recognize new interrupts. */
- return nullify_end(ctx, DISAS_IAQ_N_STALE_EXIT);
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
+ return nullify_end(ctx);
}
-static DisasJumpType trans_rfi(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_rfi(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned comp = extract32(insn, 5, 4);
@@ -2300,17 +2282,18 @@ static DisasJumpType trans_rfi(DisasContext *ctx, uint32_t insn,
} else {
gen_helper_rfi(cpu_env);
}
+ /* Exit the TB to recognize new interrupts. */
if (ctx->base.singlestep_enabled) {
gen_excp_1(EXCP_DEBUG);
} else {
tcg_gen_exit_tb(NULL, 0);
}
+ ctx->base.is_jmp = DISAS_NORETURN;
- /* Exit the TB to recognize new interrupts. */
- return nullify_end(ctx, DISAS_NORETURN);
+ return nullify_end(ctx);
}
-static DisasJumpType gen_hlt(DisasContext *ctx, int reset)
+static bool gen_hlt(DisasContext *ctx, int reset)
{
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
nullify_over(ctx);
@@ -2319,7 +2302,8 @@ static DisasJumpType gen_hlt(DisasContext *ctx, int reset)
} else {
gen_helper_halt(cpu_env);
}
- return nullify_end(ctx, DISAS_NORETURN);
+ ctx->base.is_jmp = DISAS_NORETURN;
+ return nullify_end(ctx);
}
#endif /* !CONFIG_USER_ONLY */
@@ -2342,8 +2326,8 @@ static const DisasInsn table_system[] = {
#endif
};
-static DisasJumpType trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rx = extract32(insn, 16, 5);
@@ -2356,11 +2340,10 @@ static DisasJumpType trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rb, dest);
cond_free(&ctx->null_cond);
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_probe(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_probe(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned sp = extract32(insn, 14, 2);
@@ -2392,12 +2375,11 @@ static DisasJumpType trans_probe(DisasContext *ctx, uint32_t insn,
tcg_temp_free_i32(level);
save_gpr(ctx, rt, dest);
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
#ifndef CONFIG_USER_ONLY
-static DisasJumpType trans_ixtlbx(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ixtlbx(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned sp;
unsigned rr = extract32(insn, 16, 5);
@@ -2426,12 +2408,13 @@ static DisasJumpType trans_ixtlbx(DisasContext *ctx, uint32_t insn,
/* Exit TB for ITLB change if mmu is enabled. This *should* not be
the case, since the OS TLB fill handler runs with mmu disabled. */
- return nullify_end(ctx, !is_data && (ctx->tb_flags & PSW_C)
- ? DISAS_IAQ_N_STALE : DISAS_NEXT);
+ if (!is_data && (ctx->tb_flags & PSW_C)) {
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE;
+ }
+ return nullify_end(ctx);
}
-static DisasJumpType trans_pxtlbx(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_pxtlbx(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned m = extract32(insn, 5, 1);
unsigned sp;
@@ -2462,12 +2445,13 @@ static DisasJumpType trans_pxtlbx(DisasContext *ctx, uint32_t insn,
}
/* Exit TB for TLB change if mmu is enabled. */
- return nullify_end(ctx, !is_data && (ctx->tb_flags & PSW_C)
- ? DISAS_IAQ_N_STALE : DISAS_NEXT);
+ if (!is_data && (ctx->tb_flags & PSW_C)) {
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE;
+ }
+ return nullify_end(ctx);
}
-static DisasJumpType trans_lpa(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_lpa(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
@@ -2492,11 +2476,10 @@ static DisasJumpType trans_lpa(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, paddr);
tcg_temp_free(paddr);
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_lci(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_lci(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
TCGv_reg ci;
@@ -2511,7 +2494,8 @@ static DisasJumpType trans_lci(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, ci);
tcg_temp_free(ci);
- return DISAS_NEXT;
+ cond_free(&ctx->null_cond);
+ return true;
}
#endif /* !CONFIG_USER_ONLY */
@@ -2545,8 +2529,7 @@ static const DisasInsn table_mem_mgmt[] = {
#endif
};
-static DisasJumpType trans_add(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_add(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
@@ -2559,7 +2542,6 @@ static DisasJumpType trans_add(DisasContext *ctx, uint32_t insn,
bool is_l = false;
bool is_tc = false;
bool is_tsv = false;
- DisasJumpType ret;
switch (ext) {
case 0x6: /* ADD, SHLADD */
@@ -2585,12 +2567,11 @@ static DisasJumpType trans_add(DisasContext *ctx, uint32_t insn,
}
tcg_r1 = load_gpr(ctx, r1);
tcg_r2 = load_gpr(ctx, r2);
- ret = do_add(ctx, rt, tcg_r1, tcg_r2, shift, is_l, is_tsv, is_tc, is_c, cf);
- return nullify_end(ctx, ret);
+ do_add(ctx, rt, tcg_r1, tcg_r2, shift, is_l, is_tsv, is_tc, is_c, cf);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_sub(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_sub(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
@@ -2601,7 +2582,6 @@ static DisasJumpType trans_sub(DisasContext *ctx, uint32_t insn,
bool is_b = false;
bool is_tc = false;
bool is_tsv = false;
- DisasJumpType ret;
switch (ext) {
case 0x10: /* SUB */
@@ -2630,32 +2610,29 @@ static DisasJumpType trans_sub(DisasContext *ctx, uint32_t insn,
}
tcg_r1 = load_gpr(ctx, r1);
tcg_r2 = load_gpr(ctx, r2);
- ret = do_sub(ctx, rt, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, cf);
- return nullify_end(ctx, ret);
+ do_sub(ctx, rt, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, cf);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_log(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_log(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
unsigned cf = extract32(insn, 12, 4);
unsigned rt = extract32(insn, 0, 5);
TCGv_reg tcg_r1, tcg_r2;
- DisasJumpType ret;
if (cf) {
nullify_over(ctx);
}
tcg_r1 = load_gpr(ctx, r1);
tcg_r2 = load_gpr(ctx, r2);
- ret = do_log(ctx, rt, tcg_r1, tcg_r2, cf, di->f.ttt);
- return nullify_end(ctx, ret);
+ do_log(ctx, rt, tcg_r1, tcg_r2, cf, di->f.ttt);
+ return nullify_end(ctx);
}
/* OR r,0,t -> COPY (according to gas) */
-static DisasJumpType trans_copy(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_copy(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned r1 = extract32(insn, 16, 5);
unsigned rt = extract32(insn, 0, 5);
@@ -2668,49 +2645,44 @@ static DisasJumpType trans_copy(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, cpu_gr[r1]);
}
cond_free(&ctx->null_cond);
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_cmpclr(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_cmpclr(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
unsigned cf = extract32(insn, 12, 4);
unsigned rt = extract32(insn, 0, 5);
TCGv_reg tcg_r1, tcg_r2;
- DisasJumpType ret;
if (cf) {
nullify_over(ctx);
}
tcg_r1 = load_gpr(ctx, r1);
tcg_r2 = load_gpr(ctx, r2);
- ret = do_cmpclr(ctx, rt, tcg_r1, tcg_r2, cf);
- return nullify_end(ctx, ret);
+ do_cmpclr(ctx, rt, tcg_r1, tcg_r2, cf);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_uxor(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_uxor(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
unsigned cf = extract32(insn, 12, 4);
unsigned rt = extract32(insn, 0, 5);
TCGv_reg tcg_r1, tcg_r2;
- DisasJumpType ret;
if (cf) {
nullify_over(ctx);
}
tcg_r1 = load_gpr(ctx, r1);
tcg_r2 = load_gpr(ctx, r2);
- ret = do_unit(ctx, rt, tcg_r1, tcg_r2, cf, false, tcg_gen_xor_reg);
- return nullify_end(ctx, ret);
+ do_unit(ctx, rt, tcg_r1, tcg_r2, cf, false, tcg_gen_xor_reg);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_uaddcm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_uaddcm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
@@ -2718,7 +2690,6 @@ static DisasJumpType trans_uaddcm(DisasContext *ctx, uint32_t insn,
unsigned is_tc = extract32(insn, 6, 1);
unsigned rt = extract32(insn, 0, 5);
TCGv_reg tcg_r1, tcg_r2, tmp;
- DisasJumpType ret;
if (cf) {
nullify_over(ctx);
@@ -2727,19 +2698,17 @@ static DisasJumpType trans_uaddcm(DisasContext *ctx, uint32_t insn,
tcg_r2 = load_gpr(ctx, r2);
tmp = get_temp(ctx);
tcg_gen_not_reg(tmp, tcg_r2);
- ret = do_unit(ctx, rt, tcg_r1, tmp, cf, is_tc, tcg_gen_add_reg);
- return nullify_end(ctx, ret);
+ do_unit(ctx, rt, tcg_r1, tmp, cf, is_tc, tcg_gen_add_reg);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_dcor(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_dcor(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned cf = extract32(insn, 12, 4);
unsigned is_i = extract32(insn, 6, 1);
unsigned rt = extract32(insn, 0, 5);
TCGv_reg tmp;
- DisasJumpType ret;
nullify_over(ctx);
@@ -2750,14 +2719,13 @@ static DisasJumpType trans_dcor(DisasContext *ctx, uint32_t insn,
}
tcg_gen_andi_reg(tmp, tmp, 0x11111111);
tcg_gen_muli_reg(tmp, tmp, 6);
- ret = do_unit(ctx, rt, tmp, load_gpr(ctx, r2), cf, false,
- is_i ? tcg_gen_add_reg : tcg_gen_sub_reg);
+ do_unit(ctx, rt, tmp, load_gpr(ctx, r2), cf, false,
+ is_i ? tcg_gen_add_reg : tcg_gen_sub_reg);
- return nullify_end(ctx, ret);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_ds(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ds(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
@@ -2819,7 +2787,7 @@ static DisasJumpType trans_ds(DisasContext *ctx, uint32_t insn,
tcg_temp_free(add2);
tcg_temp_free(dest);
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
#ifndef CONFIG_USER_ONLY
@@ -2829,8 +2797,7 @@ static DisasJumpType trans_ds(DisasContext *ctx, uint32_t insn,
* or %r31,%r31,%r31 -- death loop; offline cpu
* currently implemented as idle.
*/
-static DisasJumpType trans_pause(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_pause(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
TCGv_i32 tmp;
@@ -2849,8 +2816,9 @@ static DisasJumpType trans_pause(DisasContext *ctx, uint32_t insn,
offsetof(CPUState, halted));
tcg_temp_free_i32(tmp);
gen_excp_1(EXCP_HALTED);
+ ctx->base.is_jmp = DISAS_NORETURN;
- return nullify_end(ctx, DISAS_NORETURN);
+ return nullify_end(ctx);
}
#endif
@@ -2876,7 +2844,7 @@ static const DisasInsn table_arith_log[] = {
{ 0x08000200u, 0xfc000320u, trans_add }, /* shladd */
};
-static DisasJumpType trans_addi(DisasContext *ctx, uint32_t insn)
+static bool trans_addi(DisasContext *ctx, uint32_t insn)
{
target_sreg im = low_sextract(insn, 0, 11);
unsigned e1 = extract32(insn, 11, 1);
@@ -2885,7 +2853,6 @@ static DisasJumpType trans_addi(DisasContext *ctx, uint32_t insn)
unsigned r2 = extract32(insn, 21, 5);
unsigned o1 = extract32(insn, 26, 1);
TCGv_reg tcg_im, tcg_r2;
- DisasJumpType ret;
if (cf) {
nullify_over(ctx);
@@ -2893,12 +2860,12 @@ static DisasJumpType trans_addi(DisasContext *ctx, uint32_t insn)
tcg_im = load_const(ctx, im);
tcg_r2 = load_gpr(ctx, r2);
- ret = do_add(ctx, rt, tcg_im, tcg_r2, 0, false, e1, !o1, false, cf);
+ do_add(ctx, rt, tcg_im, tcg_r2, 0, false, e1, !o1, false, cf);
- return nullify_end(ctx, ret);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_subi(DisasContext *ctx, uint32_t insn)
+static bool trans_subi(DisasContext *ctx, uint32_t insn)
{
target_sreg im = low_sextract(insn, 0, 11);
unsigned e1 = extract32(insn, 11, 1);
@@ -2906,7 +2873,6 @@ static DisasJumpType trans_subi(DisasContext *ctx, uint32_t insn)
unsigned rt = extract32(insn, 16, 5);
unsigned r2 = extract32(insn, 21, 5);
TCGv_reg tcg_im, tcg_r2;
- DisasJumpType ret;
if (cf) {
nullify_over(ctx);
@@ -2914,19 +2880,18 @@ static DisasJumpType trans_subi(DisasContext *ctx, uint32_t insn)
tcg_im = load_const(ctx, im);
tcg_r2 = load_gpr(ctx, r2);
- ret = do_sub(ctx, rt, tcg_im, tcg_r2, e1, false, false, cf);
+ do_sub(ctx, rt, tcg_im, tcg_r2, e1, false, false, cf);
- return nullify_end(ctx, ret);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_cmpiclr(DisasContext *ctx, uint32_t insn)
+static bool trans_cmpiclr(DisasContext *ctx, uint32_t insn)
{
target_sreg im = low_sextract(insn, 0, 11);
unsigned cf = extract32(insn, 12, 4);
unsigned rt = extract32(insn, 16, 5);
unsigned r2 = extract32(insn, 21, 5);
TCGv_reg tcg_im, tcg_r2;
- DisasJumpType ret;
if (cf) {
nullify_over(ctx);
@@ -2934,13 +2899,13 @@ static DisasJumpType trans_cmpiclr(DisasContext *ctx, uint32_t insn)
tcg_im = load_const(ctx, im);
tcg_r2 = load_gpr(ctx, r2);
- ret = do_cmpclr(ctx, rt, tcg_im, tcg_r2, cf);
+ do_cmpclr(ctx, rt, tcg_im, tcg_r2, cf);
- return nullify_end(ctx, ret);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
@@ -2952,11 +2917,12 @@ static DisasJumpType trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
int modify = (m ? (a ? -1 : 1) : 0);
TCGMemOp mop = MO_TE | sz;
- return do_load(ctx, rt, rb, 0, 0, disp, sp, modify, mop);
+ do_load(ctx, rt, rb, 0, 0, disp, sp, modify, mop);
+ return true;
}
-static DisasJumpType trans_ld_idx_x(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ld_idx_x(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
@@ -2967,11 +2933,12 @@ static DisasJumpType trans_ld_idx_x(DisasContext *ctx, uint32_t insn,
unsigned rb = extract32(insn, 21, 5);
TCGMemOp mop = MO_TE | sz;
- return do_load(ctx, rt, rb, rx, u ? sz : 0, 0, sp, m, mop);
+ do_load(ctx, rt, rb, rx, u ? sz : 0, 0, sp, m, mop);
+ return true;
}
-static DisasJumpType trans_st_idx_i(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_st_idx_i(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
int disp = low_sextract(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
@@ -2983,11 +2950,11 @@ static DisasJumpType trans_st_idx_i(DisasContext *ctx, uint32_t insn,
int modify = (m ? (a ? -1 : 1) : 0);
TCGMemOp mop = MO_TE | sz;
- return do_store(ctx, rr, rb, disp, sp, modify, mop);
+ do_store(ctx, rr, rb, disp, sp, modify, mop);
+ return true;
}
-static DisasJumpType trans_ldcw(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ldcw(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
@@ -3030,11 +2997,10 @@ static DisasJumpType trans_ldcw(DisasContext *ctx, uint32_t insn,
}
save_gpr(ctx, rt, dest);
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_stby(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_stby(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
target_sreg disp = low_sextract(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
@@ -3069,56 +3035,53 @@ static DisasJumpType trans_stby(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rb, ofs);
}
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
#ifndef CONFIG_USER_ONLY
-static DisasJumpType trans_ldwa_idx_i(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ldwa_idx_i(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
int hold_mmu_idx = ctx->mmu_idx;
- DisasJumpType ret;
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
/* ??? needs fixing for hppa64 -- ldda does not follow the same
format wrt the sub-opcode in bits 6:9. */
ctx->mmu_idx = MMU_PHYS_IDX;
- ret = trans_ld_idx_i(ctx, insn, di);
+ trans_ld_idx_i(ctx, insn, di);
ctx->mmu_idx = hold_mmu_idx;
- return ret;
+ return true;
}
-static DisasJumpType trans_ldwa_idx_x(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ldwa_idx_x(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
int hold_mmu_idx = ctx->mmu_idx;
- DisasJumpType ret;
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
/* ??? needs fixing for hppa64 -- ldda does not follow the same
format wrt the sub-opcode in bits 6:9. */
ctx->mmu_idx = MMU_PHYS_IDX;
- ret = trans_ld_idx_x(ctx, insn, di);
+ trans_ld_idx_x(ctx, insn, di);
ctx->mmu_idx = hold_mmu_idx;
- return ret;
+ return true;
}
-static DisasJumpType trans_stwa_idx_i(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_stwa_idx_i(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
int hold_mmu_idx = ctx->mmu_idx;
- DisasJumpType ret;
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
/* ??? needs fixing for hppa64 -- ldda does not follow the same
format wrt the sub-opcode in bits 6:9. */
ctx->mmu_idx = MMU_PHYS_IDX;
- ret = trans_st_idx_i(ctx, insn, di);
+ trans_st_idx_i(ctx, insn, di);
ctx->mmu_idx = hold_mmu_idx;
- return ret;
+ return true;
}
#endif
@@ -3135,7 +3098,7 @@ static const DisasInsn table_index_mem[] = {
#endif
};
-static DisasJumpType trans_ldil(DisasContext *ctx, uint32_t insn)
+static bool trans_ldil(DisasContext *ctx, uint32_t insn)
{
unsigned rt = extract32(insn, 21, 5);
target_sreg i = assemble_21(insn);
@@ -3144,11 +3107,10 @@ static DisasJumpType trans_ldil(DisasContext *ctx, uint32_t insn)
tcg_gen_movi_reg(tcg_rt, i);
save_gpr(ctx, rt, tcg_rt);
cond_free(&ctx->null_cond);
-
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_addil(DisasContext *ctx, uint32_t insn)
+static bool trans_addil(DisasContext *ctx, uint32_t insn)
{
unsigned rt = extract32(insn, 21, 5);
target_sreg i = assemble_21(insn);
@@ -3158,11 +3120,10 @@ static DisasJumpType trans_addil(DisasContext *ctx, uint32_t insn)
tcg_gen_addi_reg(tcg_r1, tcg_rt, i);
save_gpr(ctx, 1, tcg_r1);
cond_free(&ctx->null_cond);
-
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_ldo(DisasContext *ctx, uint32_t insn)
+static bool trans_ldo(DisasContext *ctx, uint32_t insn)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rt = extract32(insn, 16, 5);
@@ -3178,23 +3139,22 @@ static DisasJumpType trans_ldo(DisasContext *ctx, uint32_t insn)
}
save_gpr(ctx, rt, tcg_rt);
cond_free(&ctx->null_cond);
-
- return DISAS_NEXT;
+ return true;
}
-static DisasJumpType trans_load(DisasContext *ctx, uint32_t insn,
- bool is_mod, TCGMemOp mop)
+static bool trans_load(DisasContext *ctx, uint32_t insn,
+ bool is_mod, TCGMemOp mop)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rt = extract32(insn, 16, 5);
unsigned sp = extract32(insn, 14, 2);
target_sreg i = assemble_16(insn);
- return do_load(ctx, rt, rb, 0, 0, i, sp,
- is_mod ? (i < 0 ? -1 : 1) : 0, mop);
+ do_load(ctx, rt, rb, 0, 0, i, sp, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
+ return true;
}
-static DisasJumpType trans_load_w(DisasContext *ctx, uint32_t insn)
+static bool trans_load_w(DisasContext *ctx, uint32_t insn)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rt = extract32(insn, 16, 5);
@@ -3206,17 +3166,20 @@ static DisasJumpType trans_load_w(DisasContext *ctx, uint32_t insn)
case 0:
case 1:
/* FLDW without modification. */
- return do_floadw(ctx, ext2 * 32 + rt, rb, 0, 0, i, sp, 0);
+ do_floadw(ctx, ext2 * 32 + rt, rb, 0, 0, i, sp, 0);
+ break;
case 2:
/* LDW with modification. Note that the sign of I selects
post-dec vs pre-inc. */
- return do_load(ctx, rt, rb, 0, 0, i, sp, (i < 0 ? 1 : -1), MO_TEUL);
+ do_load(ctx, rt, rb, 0, 0, i, sp, (i < 0 ? 1 : -1), MO_TEUL);
+ break;
default:
return gen_illegal(ctx);
}
+ return true;
}
-static DisasJumpType trans_fload_mod(DisasContext *ctx, uint32_t insn)
+static bool trans_fload_mod(DisasContext *ctx, uint32_t insn)
{
target_sreg i = assemble_16a(insn);
unsigned t1 = extract32(insn, 1, 1);
@@ -3226,21 +3189,23 @@ static DisasJumpType trans_fload_mod(DisasContext *ctx, uint32_t insn)
unsigned rb = extract32(insn, 21, 5);
/* FLDW with modification. */
- return do_floadw(ctx, t1 * 32 + t0, rb, 0, 0, i, sp, (a ? -1 : 1));
+ do_floadw(ctx, t1 * 32 + t0, rb, 0, 0, i, sp, (a ? -1 : 1));
+ return true;
}
-static DisasJumpType trans_store(DisasContext *ctx, uint32_t insn,
- bool is_mod, TCGMemOp mop)
+static bool trans_store(DisasContext *ctx, uint32_t insn,
+ bool is_mod, TCGMemOp mop)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rt = extract32(insn, 16, 5);
unsigned sp = extract32(insn, 14, 2);
target_sreg i = assemble_16(insn);
- return do_store(ctx, rt, rb, i, sp, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
+ do_store(ctx, rt, rb, i, sp, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
+ return true;
}
-static DisasJumpType trans_store_w(DisasContext *ctx, uint32_t insn)
+static bool trans_store_w(DisasContext *ctx, uint32_t insn)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rt = extract32(insn, 16, 5);
@@ -3252,16 +3217,19 @@ static DisasJumpType trans_store_w(DisasContext *ctx, uint32_t insn)
case 0:
case 1:
/* FSTW without modification. */
- return do_fstorew(ctx, ext2 * 32 + rt, rb, 0, 0, i, sp, 0);
+ do_fstorew(ctx, ext2 * 32 + rt, rb, 0, 0, i, sp, 0);
+ break;
case 2:
/* STW with modification. */
- return do_store(ctx, rt, rb, i, sp, (i < 0 ? 1 : -1), MO_TEUL);
+ do_store(ctx, rt, rb, i, sp, (i < 0 ? 1 : -1), MO_TEUL);
+ break;
default:
return gen_illegal(ctx);
}
+ return true;
}
-static DisasJumpType trans_fstore_mod(DisasContext *ctx, uint32_t insn)
+static bool trans_fstore_mod(DisasContext *ctx, uint32_t insn)
{
target_sreg i = assemble_16a(insn);
unsigned t1 = extract32(insn, 1, 1);
@@ -3271,10 +3239,11 @@ static DisasJumpType trans_fstore_mod(DisasContext *ctx, uint32_t insn)
unsigned rb = extract32(insn, 21, 5);
/* FSTW with modification. */
- return do_fstorew(ctx, t1 * 32 + t0, rb, 0, 0, i, sp, (a ? -1 : 1));
+ do_fstorew(ctx, t1 * 32 + t0, rb, 0, 0, i, sp, (a ? -1 : 1));
+ return true;
}
-static DisasJumpType trans_copr_w(DisasContext *ctx, uint32_t insn)
+static bool trans_copr_w(DisasContext *ctx, uint32_t insn)
{
unsigned t0 = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
@@ -3303,14 +3272,18 @@ static DisasJumpType trans_copr_w(DisasContext *ctx, uint32_t insn)
switch (ext3) {
case 0: /* FLDW */
- return do_floadw(ctx, rt, rb, rx, scale, disp, sp, modify);
+ do_floadw(ctx, rt, rb, rx, scale, disp, sp, modify);
+ break;
case 4: /* FSTW */
- return do_fstorew(ctx, rt, rb, rx, scale, disp, sp, modify);
+ do_fstorew(ctx, rt, rb, rx, scale, disp, sp, modify);
+ break;
+ default:
+ return gen_illegal(ctx);
}
- return gen_illegal(ctx);
+ return true;
}
-static DisasJumpType trans_copr_dw(DisasContext *ctx, uint32_t insn)
+static bool trans_copr_dw(DisasContext *ctx, uint32_t insn)
{
unsigned rt = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
@@ -3337,16 +3310,19 @@ static DisasJumpType trans_copr_dw(DisasContext *ctx, uint32_t insn)
switch (ext4) {
case 0: /* FLDD */
- return do_floadd(ctx, rt, rb, rx, scale, disp, sp, modify);
+ do_floadd(ctx, rt, rb, rx, scale, disp, sp, modify);
+ break;
case 8: /* FSTD */
- return do_fstored(ctx, rt, rb, rx, scale, disp, sp, modify);
+ do_fstored(ctx, rt, rb, rx, scale, disp, sp, modify);
+ break;
default:
return gen_illegal(ctx);
}
+ return true;
}
-static DisasJumpType trans_cmpb(DisasContext *ctx, uint32_t insn,
- bool is_true, bool is_imm, bool is_dw)
+static bool trans_cmpb(DisasContext *ctx, uint32_t insn,
+ bool is_true, bool is_imm, bool is_dw)
{
target_sreg disp = assemble_12(insn) * 4;
unsigned n = extract32(insn, 1, 1);
@@ -3374,11 +3350,12 @@ static DisasJumpType trans_cmpb(DisasContext *ctx, uint32_t insn,
}
cond = do_sub_cond(cf, dest, in1, in2, sv);
- return do_cbranch(ctx, disp, n, &cond);
+ do_cbranch(ctx, disp, n, &cond);
+ return true;
}
-static DisasJumpType trans_addb(DisasContext *ctx, uint32_t insn,
- bool is_true, bool is_imm)
+static bool trans_addb(DisasContext *ctx, uint32_t insn,
+ bool is_true, bool is_imm)
{
target_sreg disp = assemble_12(insn) * 4;
unsigned n = extract32(insn, 1, 1);
@@ -3416,10 +3393,11 @@ static DisasJumpType trans_addb(DisasContext *ctx, uint32_t insn,
}
cond = do_cond(cf, dest, cb_msb, sv);
- return do_cbranch(ctx, disp, n, &cond);
+ do_cbranch(ctx, disp, n, &cond);
+ return true;
}
-static DisasJumpType trans_bb(DisasContext *ctx, uint32_t insn)
+static bool trans_bb(DisasContext *ctx, uint32_t insn)
{
target_sreg disp = assemble_12(insn) * 4;
unsigned n = extract32(insn, 1, 1);
@@ -3442,10 +3420,11 @@ static DisasJumpType trans_bb(DisasContext *ctx, uint32_t insn)
cond = cond_make_0(c ? TCG_COND_GE : TCG_COND_LT, tmp);
tcg_temp_free(tmp);
- return do_cbranch(ctx, disp, n, &cond);
+ do_cbranch(ctx, disp, n, &cond);
+ return true;
}
-static DisasJumpType trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
+static bool trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
{
target_sreg disp = assemble_12(insn) * 4;
unsigned n = extract32(insn, 1, 1);
@@ -3467,11 +3446,12 @@ static DisasJumpType trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
}
cond = do_sed_cond(c, dest);
- return do_cbranch(ctx, disp, n, &cond);
+ do_cbranch(ctx, disp, n, &cond);
+ return true;
}
-static DisasJumpType trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned c = extract32(insn, 13, 3);
@@ -3512,11 +3492,11 @@ static DisasJumpType trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned cpos = extract32(insn, 5, 5);
@@ -3553,11 +3533,11 @@ static DisasJumpType trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_extrw_sar(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_extrw_sar(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned clen = extract32(insn, 0, 5);
unsigned is_se = extract32(insn, 10, 1);
@@ -3592,11 +3572,11 @@ static DisasJumpType trans_extrw_sar(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_extrw_imm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_extrw_imm(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned clen = extract32(insn, 0, 5);
unsigned pos = extract32(insn, 5, 5);
@@ -3626,7 +3606,7 @@ static DisasJumpType trans_extrw_imm(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
static const DisasInsn table_sh_ex[] = {
@@ -3636,8 +3616,8 @@ static const DisasInsn table_sh_ex[] = {
{ 0xd0001800u, 0xfc001800u, trans_extrw_imm },
};
-static DisasJumpType trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned clen = extract32(insn, 0, 5);
unsigned cpos = extract32(insn, 5, 5);
@@ -3677,11 +3657,11 @@ static DisasJumpType trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_depw_imm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_depw_imm(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned clen = extract32(insn, 0, 5);
unsigned cpos = extract32(insn, 5, 5);
@@ -3714,11 +3694,11 @@ static DisasJumpType trans_depw_imm(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_depw_sar(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_depw_sar(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned clen = extract32(insn, 0, 5);
unsigned nz = extract32(insn, 10, 1);
@@ -3766,7 +3746,7 @@ static DisasJumpType trans_depw_sar(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
static const DisasInsn table_depw[] = {
@@ -3775,7 +3755,7 @@ static const DisasInsn table_depw[] = {
{ 0xd4001800u, 0xfc001800u, trans_depw_imm_c },
};
-static DisasJumpType trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
+static bool trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
{
unsigned n = extract32(insn, 1, 1);
unsigned b = extract32(insn, 21, 5);
@@ -3792,7 +3772,8 @@ static DisasJumpType trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
case of "be disp(*,r0)" using a direct branch to disp, so that we can
goto_tb to the TB containing the syscall. */
if (b == 0) {
- return do_dbranch(ctx, disp, is_l ? 31 : 0, n);
+ do_dbranch(ctx, disp, is_l ? 31 : 0, n);
+ return true;
}
#else
int sp = assemble_sr3(insn);
@@ -3804,7 +3785,7 @@ static DisasJumpType trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
tmp = do_ibranch_priv(ctx, tmp);
#ifdef CONFIG_USER_ONLY
- return do_ibranch(ctx, tmp, is_l ? 31 : 0, n);
+ do_ibranch(ctx, tmp, is_l ? 31 : 0, n);
#else
TCGv_i64 new_spc = tcg_temp_new_i64();
@@ -3829,22 +3810,23 @@ static DisasJumpType trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
}
tcg_temp_free_i64(new_spc);
tcg_gen_lookup_and_goto_ptr();
- return nullify_end(ctx, DISAS_NORETURN);
+ ctx->base.is_jmp = DISAS_NORETURN;
+ return nullify_end(ctx);
#endif
+ return true;
}
-static DisasJumpType trans_bl(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_bl(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
unsigned link = extract32(insn, 21, 5);
target_sreg disp = assemble_17(insn);
- return do_dbranch(ctx, iaoq_dest(ctx, disp), link, n);
+ do_dbranch(ctx, iaoq_dest(ctx, disp), link, n);
+ return true;
}
-static DisasJumpType trans_b_gate(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_b_gate(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
unsigned link = extract32(insn, 21, 5);
@@ -3876,7 +3858,8 @@ static DisasJumpType trans_b_gate(DisasContext *ctx, uint32_t insn,
we will re-translate, at which point we *will* be able to find
the TLB entry and determine if this is in fact a gateway page. */
if (type < 0) {
- return gen_excp(ctx, EXCP_ITLB_MISS);
+ gen_excp(ctx, EXCP_ITLB_MISS);
+ return true;
}
/* No change for non-gateway pages or for priv decrease. */
if (type >= 4 && type - 4 < ctx->privilege) {
@@ -3887,20 +3870,20 @@ static DisasJumpType trans_b_gate(DisasContext *ctx, uint32_t insn,
}
#endif
- return do_dbranch(ctx, dest, link, n);
+ do_dbranch(ctx, dest, link, n);
+ return true;
}
-static DisasJumpType trans_bl_long(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_bl_long(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
target_sreg disp = assemble_22(insn);
- return do_dbranch(ctx, iaoq_dest(ctx, disp), 2, n);
+ do_dbranch(ctx, iaoq_dest(ctx, disp), 2, n);
+ return true;
}
-static DisasJumpType trans_blr(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_blr(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
unsigned rx = extract32(insn, 16, 5);
@@ -3910,11 +3893,11 @@ static DisasJumpType trans_blr(DisasContext *ctx, uint32_t insn,
tcg_gen_shli_reg(tmp, load_gpr(ctx, rx), 3);
tcg_gen_addi_reg(tmp, tmp, ctx->iaoq_f + 8);
/* The computation here never changes privilege level. */
- return do_ibranch(ctx, tmp, link, n);
+ do_ibranch(ctx, tmp, link, n);
+ return true;
}
-static DisasJumpType trans_bv(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_bv(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
unsigned rx = extract32(insn, 16, 5);
@@ -3929,11 +3912,11 @@ static DisasJumpType trans_bv(DisasContext *ctx, uint32_t insn,
tcg_gen_add_reg(dest, dest, load_gpr(ctx, rb));
}
dest = do_ibranch_priv(ctx, dest);
- return do_ibranch(ctx, dest, 0, n);
+ do_ibranch(ctx, dest, 0, n);
+ return true;
}
-static DisasJumpType trans_bve(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_bve(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
unsigned rb = extract32(insn, 21, 5);
@@ -3942,7 +3925,7 @@ static DisasJumpType trans_bve(DisasContext *ctx, uint32_t insn,
#ifdef CONFIG_USER_ONLY
dest = do_ibranch_priv(ctx, load_gpr(ctx, rb));
- return do_ibranch(ctx, dest, link, n);
+ do_ibranch(ctx, dest, link, n);
#else
nullify_over(ctx);
dest = do_ibranch_priv(ctx, load_gpr(ctx, rb));
@@ -3958,8 +3941,10 @@ static DisasJumpType trans_bve(DisasContext *ctx, uint32_t insn,
}
nullify_set(ctx, n);
tcg_gen_lookup_and_goto_ptr();
- return nullify_end(ctx, DISAS_NORETURN);
+ ctx->base.is_jmp = DISAS_NORETURN;
+ return nullify_end(ctx);
#endif
+ return true;
}
static const DisasInsn table_branch[] = {
@@ -3971,87 +3956,97 @@ static const DisasInsn table_branch[] = {
{ 0xe8002000u, 0xfc00e000u, trans_b_gate },
};
-static DisasJumpType trans_fop_wew_0c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fop_wew_0c(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned ra = extract32(insn, 21, 5);
- return do_fop_wew(ctx, rt, ra, di->f.wew);
+ do_fop_wew(ctx, rt, ra, di->f.wew);
+ return true;
}
-static DisasJumpType trans_fop_wew_0e(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fop_wew_0e(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = assemble_rt64(insn);
unsigned ra = assemble_ra64(insn);
- return do_fop_wew(ctx, rt, ra, di->f.wew);
+ do_fop_wew(ctx, rt, ra, di->f.wew);
+ return true;
}
-static DisasJumpType trans_fop_ded(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fop_ded(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned ra = extract32(insn, 21, 5);
- return do_fop_ded(ctx, rt, ra, di->f.ded);
+ do_fop_ded(ctx, rt, ra, di->f.ded);
+ return true;
}
-static DisasJumpType trans_fop_wed_0c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fop_wed_0c(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned ra = extract32(insn, 21, 5);
- return do_fop_wed(ctx, rt, ra, di->f.wed);
+ do_fop_wed(ctx, rt, ra, di->f.wed);
+ return true;
}
-static DisasJumpType trans_fop_wed_0e(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fop_wed_0e(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = assemble_rt64(insn);
unsigned ra = extract32(insn, 21, 5);
- return do_fop_wed(ctx, rt, ra, di->f.wed);
+ do_fop_wed(ctx, rt, ra, di->f.wed);
+ return true;
}
-static DisasJumpType trans_fop_dew_0c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fop_dew_0c(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned ra = extract32(insn, 21, 5);
- return do_fop_dew(ctx, rt, ra, di->f.dew);
+ do_fop_dew(ctx, rt, ra, di->f.dew);
+ return true;
}
-static DisasJumpType trans_fop_dew_0e(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fop_dew_0e(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned ra = assemble_ra64(insn);
- return do_fop_dew(ctx, rt, ra, di->f.dew);
+ do_fop_dew(ctx, rt, ra, di->f.dew);
+ return true;
}
-static DisasJumpType trans_fop_weww_0c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fop_weww_0c(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned rb = extract32(insn, 16, 5);
unsigned ra = extract32(insn, 21, 5);
- return do_fop_weww(ctx, rt, ra, rb, di->f.weww);
+ do_fop_weww(ctx, rt, ra, rb, di->f.weww);
+ return true;
}
-static DisasJumpType trans_fop_weww_0e(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fop_weww_0e(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = assemble_rt64(insn);
unsigned rb = assemble_rb64(insn);
unsigned ra = assemble_ra64(insn);
- return do_fop_weww(ctx, rt, ra, rb, di->f.weww);
+ do_fop_weww(ctx, rt, ra, rb, di->f.weww);
+ return true;
}
-static DisasJumpType trans_fop_dedd(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fop_dedd(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned rb = extract32(insn, 16, 5);
unsigned ra = extract32(insn, 21, 5);
- return do_fop_dedd(ctx, rt, ra, rb, di->f.dedd);
+ do_fop_dedd(ctx, rt, ra, rb, di->f.dedd);
+ return true;
}
static void gen_fcpy_s(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
@@ -4094,8 +4089,8 @@ static void gen_fnegabs_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
tcg_gen_ori_i64(dst, src, INT64_MIN);
}
-static DisasJumpType do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
- unsigned y, unsigned c)
+static void do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
+ unsigned y, unsigned c)
{
TCGv_i32 ta, tb, tc, ty;
@@ -4113,31 +4108,32 @@ static DisasJumpType do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
tcg_temp_free_i32(ty);
tcg_temp_free_i32(tc);
- return nullify_end(ctx, DISAS_NEXT);
+ nullify_end(ctx);
}
-static DisasJumpType trans_fcmp_s_0c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fcmp_s_0c(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned c = extract32(insn, 0, 5);
unsigned y = extract32(insn, 13, 3);
unsigned rb = extract32(insn, 16, 5);
unsigned ra = extract32(insn, 21, 5);
- return do_fcmp_s(ctx, ra, rb, y, c);
+ do_fcmp_s(ctx, ra, rb, y, c);
+ return true;
}
-static DisasJumpType trans_fcmp_s_0e(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fcmp_s_0e(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned c = extract32(insn, 0, 5);
unsigned y = extract32(insn, 13, 3);
unsigned rb = assemble_rb64(insn);
unsigned ra = assemble_ra64(insn);
- return do_fcmp_s(ctx, ra, rb, y, c);
+ do_fcmp_s(ctx, ra, rb, y, c);
+ return true;
}
-static DisasJumpType trans_fcmp_d(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fcmp_d(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned c = extract32(insn, 0, 5);
unsigned y = extract32(insn, 13, 3);
@@ -4160,11 +4156,11 @@ static DisasJumpType trans_fcmp_d(DisasContext *ctx, uint32_t insn,
tcg_temp_free_i32(ty);
tcg_temp_free_i32(tc);
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_ftest_t(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ftest_t(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned y = extract32(insn, 13, 3);
unsigned cbit = (y ^ 1) - 1;
@@ -4178,11 +4174,11 @@ static DisasJumpType trans_ftest_t(DisasContext *ctx, uint32_t insn,
ctx->null_cond = cond_make_0(TCG_COND_NE, t);
tcg_temp_free(t);
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_ftest_q(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ftest_q(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned c = extract32(insn, 0, 5);
int mask;
@@ -4232,11 +4228,10 @@ static DisasJumpType trans_ftest_q(DisasContext *ctx, uint32_t insn,
ctx->null_cond = cond_make_0(TCG_COND_EQ, t);
}
done:
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_xmpyu(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_xmpyu(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned rb = assemble_rb64(insn);
@@ -4252,7 +4247,7 @@ static DisasJumpType trans_xmpyu(DisasContext *ctx, uint32_t insn,
tcg_temp_free_i64(a);
tcg_temp_free_i64(b);
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
#define FOP_DED trans_fop_ded, .f.ded
@@ -4427,8 +4422,7 @@ static inline int fmpyadd_s_reg(unsigned r)
return (r & 16) * 2 + 16 + (r & 15);
}
-static DisasJumpType trans_fmpyadd(DisasContext *ctx,
- uint32_t insn, bool is_sub)
+static bool trans_fmpyadd(DisasContext *ctx, uint32_t insn, bool is_sub)
{
unsigned tm = extract32(insn, 0, 5);
unsigned f = extract32(insn, 5, 1);
@@ -4456,11 +4450,11 @@ static DisasJumpType trans_fmpyadd(DisasContext *ctx,
is_sub ? gen_helper_fsub_d : gen_helper_fadd_d);
}
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = assemble_rt64(insn);
unsigned neg = extract32(insn, 5, 1);
@@ -4484,11 +4478,11 @@ static DisasJumpType trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
tcg_temp_free_i32(c);
save_frw_i32(rt, a);
tcg_temp_free_i32(a);
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
-static DisasJumpType trans_fmpyfadd_d(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fmpyfadd_d(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned neg = extract32(insn, 5, 1);
@@ -4512,7 +4506,7 @@ static DisasJumpType trans_fmpyfadd_d(DisasContext *ctx, uint32_t insn,
tcg_temp_free_i64(c);
save_frd(rt, a);
tcg_temp_free_i64(a);
- return nullify_end(ctx, DISAS_NEXT);
+ return nullify_end(ctx);
}
static const DisasInsn table_fp_fused[] = {
@@ -4520,127 +4514,175 @@ static const DisasInsn table_fp_fused[] = {
{ 0xb8000800u, 0xfc0019c0u, trans_fmpyfadd_d }
};
-static DisasJumpType translate_table_int(DisasContext *ctx, uint32_t insn,
- const DisasInsn table[], size_t n)
+static void translate_table_int(DisasContext *ctx, uint32_t insn,
+ const DisasInsn table[], size_t n)
{
size_t i;
for (i = 0; i < n; ++i) {
if ((insn & table[i].mask) == table[i].insn) {
- return table[i].trans(ctx, insn, &table[i]);
+ table[i].trans(ctx, insn, &table[i]);
+ return;
}
}
qemu_log_mask(LOG_UNIMP, "UNIMP insn %08x @ " TARGET_FMT_lx "\n",
insn, ctx->base.pc_next);
- return gen_illegal(ctx);
+ gen_illegal(ctx);
}
#define translate_table(ctx, insn, table) \
translate_table_int(ctx, insn, table, ARRAY_SIZE(table))
-static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
+static void translate_one(DisasContext *ctx, uint32_t insn)
{
uint32_t opc = extract32(insn, 26, 6);
switch (opc) {
case 0x00: /* system op */
- return translate_table(ctx, insn, table_system);
+ translate_table(ctx, insn, table_system);
+ return;
case 0x01:
- return translate_table(ctx, insn, table_mem_mgmt);
+ translate_table(ctx, insn, table_mem_mgmt);
+ return;
case 0x02:
- return translate_table(ctx, insn, table_arith_log);
+ translate_table(ctx, insn, table_arith_log);
+ return;
case 0x03:
- return translate_table(ctx, insn, table_index_mem);
+ translate_table(ctx, insn, table_index_mem);
+ return;
case 0x06:
- return trans_fmpyadd(ctx, insn, false);
+ trans_fmpyadd(ctx, insn, false);
+ return;
case 0x08:
- return trans_ldil(ctx, insn);
+ trans_ldil(ctx, insn);
+ return;
case 0x09:
- return trans_copr_w(ctx, insn);
+ trans_copr_w(ctx, insn);
+ return;
case 0x0A:
- return trans_addil(ctx, insn);
+ trans_addil(ctx, insn);
+ return;
case 0x0B:
- return trans_copr_dw(ctx, insn);
+ trans_copr_dw(ctx, insn);
+ return;
case 0x0C:
- return translate_table(ctx, insn, table_float_0c);
+ translate_table(ctx, insn, table_float_0c);
+ return;
case 0x0D:
- return trans_ldo(ctx, insn);
+ trans_ldo(ctx, insn);
+ return;
case 0x0E:
- return translate_table(ctx, insn, table_float_0e);
+ translate_table(ctx, insn, table_float_0e);
+ return;
case 0x10:
- return trans_load(ctx, insn, false, MO_UB);
+ trans_load(ctx, insn, false, MO_UB);
+ return;
case 0x11:
- return trans_load(ctx, insn, false, MO_TEUW);
+ trans_load(ctx, insn, false, MO_TEUW);
+ return;
case 0x12:
- return trans_load(ctx, insn, false, MO_TEUL);
+ trans_load(ctx, insn, false, MO_TEUL);
+ return;
case 0x13:
- return trans_load(ctx, insn, true, MO_TEUL);
+ trans_load(ctx, insn, true, MO_TEUL);
+ return;
case 0x16:
- return trans_fload_mod(ctx, insn);
+ trans_fload_mod(ctx, insn);
+ return;
case 0x17:
- return trans_load_w(ctx, insn);
+ trans_load_w(ctx, insn);
+ return;
case 0x18:
- return trans_store(ctx, insn, false, MO_UB);
+ trans_store(ctx, insn, false, MO_UB);
+ return;
case 0x19:
- return trans_store(ctx, insn, false, MO_TEUW);
+ trans_store(ctx, insn, false, MO_TEUW);
+ return;
case 0x1A:
- return trans_store(ctx, insn, false, MO_TEUL);
+ trans_store(ctx, insn, false, MO_TEUL);
+ return;
case 0x1B:
- return trans_store(ctx, insn, true, MO_TEUL);
+ trans_store(ctx, insn, true, MO_TEUL);
+ return;
case 0x1E:
- return trans_fstore_mod(ctx, insn);
+ trans_fstore_mod(ctx, insn);
+ return;
case 0x1F:
- return trans_store_w(ctx, insn);
+ trans_store_w(ctx, insn);
+ return;
case 0x20:
- return trans_cmpb(ctx, insn, true, false, false);
+ trans_cmpb(ctx, insn, true, false, false);
+ return;
case 0x21:
- return trans_cmpb(ctx, insn, true, true, false);
+ trans_cmpb(ctx, insn, true, true, false);
+ return;
case 0x22:
- return trans_cmpb(ctx, insn, false, false, false);
+ trans_cmpb(ctx, insn, false, false, false);
+ return;
case 0x23:
- return trans_cmpb(ctx, insn, false, true, false);
+ trans_cmpb(ctx, insn, false, true, false);
+ return;
case 0x24:
- return trans_cmpiclr(ctx, insn);
+ trans_cmpiclr(ctx, insn);
+ return;
case 0x25:
- return trans_subi(ctx, insn);
+ trans_subi(ctx, insn);
+ return;
case 0x26:
- return trans_fmpyadd(ctx, insn, true);
+ trans_fmpyadd(ctx, insn, true);
+ return;
case 0x27:
- return trans_cmpb(ctx, insn, true, false, true);
+ trans_cmpb(ctx, insn, true, false, true);
+ return;
case 0x28:
- return trans_addb(ctx, insn, true, false);
+ trans_addb(ctx, insn, true, false);
+ return;
case 0x29:
- return trans_addb(ctx, insn, true, true);
+ trans_addb(ctx, insn, true, true);
+ return;
case 0x2A:
- return trans_addb(ctx, insn, false, false);
+ trans_addb(ctx, insn, false, false);
+ return;
case 0x2B:
- return trans_addb(ctx, insn, false, true);
+ trans_addb(ctx, insn, false, true);
+ return;
case 0x2C:
case 0x2D:
- return trans_addi(ctx, insn);
+ trans_addi(ctx, insn);
+ return;
case 0x2E:
- return translate_table(ctx, insn, table_fp_fused);
+ translate_table(ctx, insn, table_fp_fused);
+ return;
case 0x2F:
- return trans_cmpb(ctx, insn, false, false, true);
+ trans_cmpb(ctx, insn, false, false, true);
+ return;
case 0x30:
case 0x31:
- return trans_bb(ctx, insn);
+ trans_bb(ctx, insn);
+ return;
case 0x32:
- return trans_movb(ctx, insn, false);
+ trans_movb(ctx, insn, false);
+ return;
case 0x33:
- return trans_movb(ctx, insn, true);
+ trans_movb(ctx, insn, true);
+ return;
case 0x34:
- return translate_table(ctx, insn, table_sh_ex);
+ translate_table(ctx, insn, table_sh_ex);
+ return;
case 0x35:
- return translate_table(ctx, insn, table_depw);
+ translate_table(ctx, insn, table_depw);
+ return;
case 0x38:
- return trans_be(ctx, insn, false);
+ trans_be(ctx, insn, false);
+ return;
case 0x39:
- return trans_be(ctx, insn, true);
+ trans_be(ctx, insn, true);
+ return;
case 0x3A:
- return translate_table(ctx, insn, table_branch);
+ translate_table(ctx, insn, table_branch);
+ return;
case 0x04: /* spopn */
case 0x05: /* diag */
@@ -4656,17 +4698,19 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
#ifndef CONFIG_USER_ONLY
/* Unassigned, but use as system-halt. */
if (insn == 0xfffdead0) {
- return gen_hlt(ctx, 0); /* halt system */
+ gen_hlt(ctx, 0); /* halt system */
+ return;
}
if (insn == 0xfffdead1) {
- return gen_hlt(ctx, 1); /* reset system */
+ gen_hlt(ctx, 1); /* reset system */
+ return;
}
#endif
break;
default:
break;
}
- return gen_illegal(ctx);
+ gen_illegal(ctx);
}
static void hppa_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
@@ -4733,7 +4777,7 @@ static bool hppa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
- ctx->base.is_jmp = gen_excp(ctx, EXCP_DEBUG);
+ gen_excp(ctx, EXCP_DEBUG);
ctx->base.pc_next += 4;
return true;
}
@@ -4748,7 +4792,8 @@ static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
/* Execute one insn. */
#ifdef CONFIG_USER_ONLY
if (ctx->base.pc_next < TARGET_PAGE_SIZE) {
- ret = do_page_zero(ctx);
+ do_page_zero(ctx);
+ ret = ctx->base.is_jmp;
assert(ret != DISAS_NEXT);
} else
#endif
@@ -4773,7 +4818,8 @@ static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
ret = DISAS_NEXT;
} else {
ctx->insn = insn;
- ret = translate_one(ctx, insn);
+ translate_one(ctx, insn);
+ ret = ctx->base.is_jmp;
assert(ctx->null_lab == NULL);
}
}
@@ -4799,14 +4845,13 @@ static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
|| ctx->null_cond.c == TCG_COND_ALWAYS)) {
nullify_set(ctx, ctx->null_cond.c == TCG_COND_ALWAYS);
gen_goto_tb(ctx, 0, ctx->iaoq_b, ctx->iaoq_n);
- ret = DISAS_NORETURN;
+ ctx->base.is_jmp = ret = DISAS_NORETURN;
} else {
- ret = DISAS_IAQ_N_STALE;
+ ctx->base.is_jmp = ret = DISAS_IAQ_N_STALE;
}
}
ctx->iaoq_f = ctx->iaoq_b;
ctx->iaoq_b = ctx->iaoq_n;
- ctx->base.is_jmp = ret;
ctx->base.pc_next += 4;
if (ret == DISAS_NORETURN || ret == DISAS_IAQ_N_UPDATED) {
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 02/19] target/hppa: Begin using scripts/decodetree.py
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 01/19] target/hppa: Use DisasContextBase.is_jmp Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 03/19] target/hppa: Convert move to/from system registers Richard Henderson
` (17 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Convert the BREAK instruction to start.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 24 +++++++++++++++++++-----
target/hppa/Makefile.objs | 8 ++++++++
target/hppa/insns.decode | 24 ++++++++++++++++++++++++
3 files changed, 51 insertions(+), 5 deletions(-)
create mode 100644 target/hppa/insns.decode
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index a4f253a022..f50ec7b9c2 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -278,6 +278,9 @@ typedef struct DisasContext {
bool psw_n_nonzero;
} DisasContext;
+/* Include the auto-generated decoder. */
+#include "decode.inc.c"
+
/* We are not using a goto_tb (for whatever reason), but have updated
the iaq (for whatever reason), so don't do it again on exit. */
#define DISAS_IAQ_N_UPDATED DISAS_TARGET_0
@@ -661,7 +664,8 @@ static void nullify_set(DisasContext *ctx, bool x)
}
/* Mark the end of an instruction that may have been nullified.
- This is the pair to nullify_over. */
+ This is the pair to nullify_over. Always returns true so that
+ it may be tail-called from a translate function. */
static bool nullify_end(DisasContext *ctx)
{
TCGLabel *null_lab = ctx->null_lab;
@@ -745,12 +749,17 @@ static bool gen_illegal(DisasContext *ctx)
return gen_excp_iir(ctx, EXCP_ILL);
}
-#define CHECK_MOST_PRIVILEGED(EXCP) \
+#ifdef CONFIG_USER_ONLY
+#define CHECK_MOST_PRIVILEGED(EXCP) \
+ return gen_excp_iir(ctx, EXCP)
+#else
+#define CHECK_MOST_PRIVILEGED(EXCP) \
do { \
if (ctx->privilege != 0) { \
return gen_excp_iir(ctx, EXCP); \
} \
} while (0)
+#endif
static bool use_goto_tb(DisasContext *ctx, target_ureg dest)
{
@@ -1982,7 +1991,7 @@ static bool trans_nop(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
return true;
}
-static bool trans_break(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_break(DisasContext *ctx, arg_break *a)
{
return gen_excp_iir(ctx, EXCP_BREAK);
}
@@ -2308,7 +2317,6 @@ static bool gen_hlt(DisasContext *ctx, int reset)
#endif /* !CONFIG_USER_ONLY */
static const DisasInsn table_system[] = {
- { 0x00000000u, 0xfc001fe0u, trans_break },
{ 0x00001820u, 0xffe01fffu, trans_mtsp },
{ 0x00001840u, 0xfc00ffffu, trans_mtctl },
{ 0x016018c0u, 0xffe0ffffu, trans_mtsarcm },
@@ -4534,8 +4542,14 @@ static void translate_table_int(DisasContext *ctx, uint32_t insn,
static void translate_one(DisasContext *ctx, uint32_t insn)
{
- uint32_t opc = extract32(insn, 26, 6);
+ uint32_t opc;
+ /* Transition to the auto-generated decoder. */
+ if (decode(ctx, insn)) {
+ return;
+ }
+
+ opc = extract32(insn, 26, 6);
switch (opc) {
case 0x00: /* system op */
translate_table(ctx, insn, table_system);
diff --git a/target/hppa/Makefile.objs b/target/hppa/Makefile.objs
index 3359da5341..174f50a96c 100644
--- a/target/hppa/Makefile.objs
+++ b/target/hppa/Makefile.objs
@@ -1,3 +1,11 @@
obj-y += translate.o helper.o cpu.o op_helper.o gdbstub.o mem_helper.o
obj-y += int_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o
+
+DECODETREE = $(SRC_PATH)/scripts/decodetree.py
+
+target/hppa/decode.inc.c: $(SRC_PATH)/target/hppa/insns.decode $(DECODETREE)
+ $(call quiet-command,\
+ $(PYTHON) $(DECODETREE) -o $@ $<, "GEN", $(TARGET_DIR)$@)
+
+target/hppa/translate.o: target/hppa/decode.inc.c
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
new file mode 100644
index 0000000000..2822fbc58b
--- /dev/null
+++ b/target/hppa/insns.decode
@@ -0,0 +1,24 @@
+#
+# HPPA instruction decode definitions.
+#
+# Copyright (c) 2018 Richard Henderson <rth@twiddle.net>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
+#
+
+####
+# System
+####
+
+break 000000 ----- ----- --- 00000000 -----
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 03/19] target/hppa: Convert move to/from system registers
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 01/19] target/hppa: Use DisasContextBase.is_jmp Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 02/19] target/hppa: Begin using scripts/decodetree.py Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 04/19] target/hppa: Convert remainder of system insns Richard Henderson
` (16 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 61 +++++++++++++++++-----------------------
target/hppa/insns.decode | 15 ++++++++++
2 files changed, 41 insertions(+), 35 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index f50ec7b9c2..72cb7b477e 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -838,7 +838,7 @@ static unsigned assemble_rc64(uint32_t insn)
return r2 * 32 + r1 * 4 + r0;
}
-static unsigned assemble_sr3(uint32_t insn)
+static inline unsigned assemble_sr3(uint32_t insn)
{
unsigned s2 = extract32(insn, 13, 1);
unsigned s0 = extract32(insn, 14, 2);
@@ -2005,9 +2005,9 @@ static bool trans_sync(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
return true;
}
-static bool trans_mfia(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_mfia(DisasContext *ctx, arg_mfia *a)
{
- unsigned rt = extract32(insn, 0, 5);
+ unsigned rt = a->t;
TCGv_reg tmp = dest_gpr(ctx, rt);
tcg_gen_movi_reg(tmp, ctx->iaoq_f);
save_gpr(ctx, rt, tmp);
@@ -2016,10 +2016,10 @@ static bool trans_mfia(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
return true;
}
-static bool trans_mfsp(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_mfsp(DisasContext *ctx, arg_mfsp *a)
{
- unsigned rt = extract32(insn, 0, 5);
- unsigned rs = assemble_sr3(insn);
+ unsigned rt = a->t;
+ unsigned rs = a->sp;
TCGv_i64 t0 = tcg_temp_new_i64();
TCGv_reg t1 = tcg_temp_new();
@@ -2035,16 +2035,16 @@ static bool trans_mfsp(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
return true;
}
-static bool trans_mfctl(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_mfctl(DisasContext *ctx, arg_mfctl *a)
{
- unsigned rt = extract32(insn, 0, 5);
- unsigned ctl = extract32(insn, 21, 5);
+ unsigned rt = a->t;
+ unsigned ctl = a->r;
TCGv_reg tmp;
switch (ctl) {
case CR_SAR:
#ifdef TARGET_HPPA64
- if (extract32(insn, 14, 1) == 0) {
+ if (a->e == 0) {
/* MFSAR without ,W masks low 5 bits. */
tmp = dest_gpr(ctx, rt);
tcg_gen_andi_reg(tmp, cpu_sar, 31);
@@ -2086,10 +2086,10 @@ static bool trans_mfctl(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
return true;
}
-static bool trans_mtsp(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_mtsp(DisasContext *ctx, arg_mtsp *a)
{
- unsigned rr = extract32(insn, 16, 5);
- unsigned rs = assemble_sr3(insn);
+ unsigned rr = a->r;
+ unsigned rs = a->sp;
TCGv_i64 t64;
if (rs >= 5) {
@@ -2112,11 +2112,10 @@ static bool trans_mtsp(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
return nullify_end(ctx);
}
-static bool trans_mtctl(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a)
{
- unsigned rin = extract32(insn, 16, 5);
- unsigned ctl = extract32(insn, 21, 5);
- TCGv_reg reg = load_gpr(ctx, rin);
+ unsigned ctl = a->t;
+ TCGv_reg reg = load_gpr(ctx, a->r);
TCGv_reg tmp;
if (ctl == CR_SAR) {
@@ -2132,9 +2131,7 @@ static bool trans_mtctl(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
/* All other control registers are privileged or read-only. */
CHECK_MOST_PRIVILEGED(EXCP_PRIV_REG);
-#ifdef CONFIG_USER_ONLY
- g_assert_not_reached();
-#else
+#ifndef CONFIG_USER_ONLY
nullify_over(ctx);
switch (ctl) {
case CR_IT:
@@ -2168,12 +2165,11 @@ static bool trans_mtctl(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
#endif
}
-static bool trans_mtsarcm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_mtsarcm(DisasContext *ctx, arg_mtsarcm *a)
{
- unsigned rin = extract32(insn, 16, 5);
TCGv_reg tmp = tcg_temp_new();
- tcg_gen_not_reg(tmp, load_gpr(ctx, rin));
+ tcg_gen_not_reg(tmp, load_gpr(ctx, a->r));
tcg_gen_andi_reg(tmp, tmp, TARGET_REGISTER_BITS - 1);
save_or_nullify(ctx, cpu_sar, tmp);
tcg_temp_free(tmp);
@@ -2261,24 +2257,26 @@ static bool trans_ssm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
return nullify_end(ctx);
}
+#endif /* !CONFIG_USER_ONLY */
-static bool trans_mtsm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_mtsm(DisasContext *ctx, arg_mtsm *a)
{
- unsigned rr = extract32(insn, 16, 5);
- TCGv_reg tmp, reg;
-
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
+#ifndef CONFIG_USER_ONLY
+ TCGv_reg tmp, reg;
nullify_over(ctx);
- reg = load_gpr(ctx, rr);
+ reg = load_gpr(ctx, a->r);
tmp = get_temp(ctx);
gen_helper_swap_system_mask(tmp, cpu_env, reg);
/* Exit the TB to recognize new interrupts. */
ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
return nullify_end(ctx);
+#endif
}
+#ifndef CONFIG_USER_ONLY
static bool trans_rfi(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
unsigned comp = extract32(insn, 5, 4);
@@ -2317,19 +2315,12 @@ static bool gen_hlt(DisasContext *ctx, int reset)
#endif /* !CONFIG_USER_ONLY */
static const DisasInsn table_system[] = {
- { 0x00001820u, 0xffe01fffu, trans_mtsp },
- { 0x00001840u, 0xfc00ffffu, trans_mtctl },
- { 0x016018c0u, 0xffe0ffffu, trans_mtsarcm },
- { 0x000014a0u, 0xffffffe0u, trans_mfia },
- { 0x000004a0u, 0xffff1fe0u, trans_mfsp },
- { 0x000008a0u, 0xfc1fbfe0u, trans_mfctl },
{ 0x00000400u, 0xffffffffu, trans_sync }, /* sync */
{ 0x00100400u, 0xffffffffu, trans_sync }, /* syncdma */
{ 0x000010a0u, 0xfc1f3fe0u, trans_ldsid },
#ifndef CONFIG_USER_ONLY
{ 0x00000e60u, 0xfc00ffe0u, trans_rsm },
{ 0x00000d60u, 0xfc00ffe0u, trans_ssm },
- { 0x00001860u, 0xffe0ffffu, trans_mtsm },
{ 0x00000c00u, 0xfffffe1fu, trans_rfi },
#endif
};
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 2822fbc58b..047a9d01ec 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -17,8 +17,23 @@
# License along with this library; if not, see <http://www.gnu.org/licenses/>.
#
+####
+# Field definitions
+####
+
+%assemble_sr3 13:1 14:2
+
####
# System
####
break 000000 ----- ----- --- 00000000 -----
+
+mtsp 000000 ----- r:5 ... 11000001 00000 sp=%assemble_sr3
+mtctl 000000 t:5 r:5 --- 11000010 00000
+mtsarcm 000000 01011 r:5 --- 11000110 00000
+mtsm 000000 00000 r:5 000 11000011 00000
+
+mfia 000000 ----- 00000 --- 10100101 t:5
+mfsp 000000 ----- 00000 ... 00100101 t:5 sp=%assemble_sr3
+mfctl 000000 r:5 00000- e:1 -01000101 t:5
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 04/19] target/hppa: Convert remainder of system insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (2 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 03/19] target/hppa: Convert move to/from system registers Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 05/19] target/hppa: Unify specializations of OR Richard Henderson
` (15 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 99 ++++++++++++++++++----------------------
target/hppa/insns.decode | 12 +++++
2 files changed, 56 insertions(+), 55 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 72cb7b477e..2ca0f5da10 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -278,6 +278,18 @@ typedef struct DisasContext {
bool psw_n_nonzero;
} DisasContext;
+/* Note that ssm/rsm instructions number PSW_W and PSW_E differently. */
+static int expand_sm_imm(int val)
+{
+ if (val & PSW_SM_E) {
+ val = (val & ~PSW_SM_E) | PSW_E;
+ }
+ if (val & PSW_SM_W) {
+ val = (val & ~PSW_SM_W) | PSW_W;
+ }
+ return val;
+}
+
/* Include the auto-generated decoder. */
#include "decode.inc.c"
@@ -1996,7 +2008,7 @@ static bool trans_break(DisasContext *ctx, arg_break *a)
return gen_excp_iir(ctx, EXCP_BREAK);
}
-static bool trans_sync(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_sync(DisasContext *ctx, arg_sync *a)
{
/* No point in nullifying the memory barrier. */
tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
@@ -2178,86 +2190,67 @@ static bool trans_mtsarcm(DisasContext *ctx, arg_mtsarcm *a)
return true;
}
-static bool trans_ldsid(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_ldsid(DisasContext *ctx, arg_ldsid *a)
{
- unsigned rt = extract32(insn, 0, 5);
- TCGv_reg dest = dest_gpr(ctx, rt);
+ TCGv_reg dest = dest_gpr(ctx, a->t);
#ifdef CONFIG_USER_ONLY
/* We don't implement space registers in user mode. */
tcg_gen_movi_reg(dest, 0);
#else
- unsigned rb = extract32(insn, 21, 5);
- unsigned sp = extract32(insn, 14, 2);
TCGv_i64 t0 = tcg_temp_new_i64();
- tcg_gen_mov_i64(t0, space_select(ctx, sp, load_gpr(ctx, rb)));
+ tcg_gen_mov_i64(t0, space_select(ctx, a->sp, load_gpr(ctx, a->b)));
tcg_gen_shri_i64(t0, t0, 32);
tcg_gen_trunc_i64_reg(dest, t0);
tcg_temp_free_i64(t0);
#endif
- save_gpr(ctx, rt, dest);
+ save_gpr(ctx, a->t, dest);
cond_free(&ctx->null_cond);
return true;
}
+static bool trans_rsm(DisasContext *ctx, arg_rsm *a)
+{
+ CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
-/* Note that ssm/rsm instructions number PSW_W and PSW_E differently. */
-static target_ureg extract_sm_imm(uint32_t insn)
-{
- target_ureg val = extract32(insn, 16, 10);
-
- if (val & PSW_SM_E) {
- val = (val & ~PSW_SM_E) | PSW_E;
- }
- if (val & PSW_SM_W) {
- val = (val & ~PSW_SM_W) | PSW_W;
- }
- return val;
-}
-
-static bool trans_rsm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
-{
- unsigned rt = extract32(insn, 0, 5);
- target_ureg sm = extract_sm_imm(insn);
TCGv_reg tmp;
- CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
nullify_over(ctx);
tmp = get_temp(ctx);
tcg_gen_ld_reg(tmp, cpu_env, offsetof(CPUHPPAState, psw));
- tcg_gen_andi_reg(tmp, tmp, ~sm);
+ tcg_gen_andi_reg(tmp, tmp, ~a->i);
gen_helper_swap_system_mask(tmp, cpu_env, tmp);
- save_gpr(ctx, rt, tmp);
+ save_gpr(ctx, a->t, tmp);
/* Exit the TB to recognize new interrupts, e.g. PSW_M. */
ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
return nullify_end(ctx);
+#endif
}
-static bool trans_ssm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_ssm(DisasContext *ctx, arg_ssm *a)
{
- unsigned rt = extract32(insn, 0, 5);
- target_ureg sm = extract_sm_imm(insn);
+ CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
+#ifndef CONFIG_USER_ONLY
TCGv_reg tmp;
- CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
nullify_over(ctx);
tmp = get_temp(ctx);
tcg_gen_ld_reg(tmp, cpu_env, offsetof(CPUHPPAState, psw));
- tcg_gen_ori_reg(tmp, tmp, sm);
+ tcg_gen_ori_reg(tmp, tmp, a->i);
gen_helper_swap_system_mask(tmp, cpu_env, tmp);
- save_gpr(ctx, rt, tmp);
+ save_gpr(ctx, a->t, tmp);
/* Exit the TB to recognize new interrupts, e.g. PSW_I. */
ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
return nullify_end(ctx);
+#endif
}
-#endif /* !CONFIG_USER_ONLY */
static bool trans_mtsm(DisasContext *ctx, arg_mtsm *a)
{
@@ -2276,15 +2269,13 @@ static bool trans_mtsm(DisasContext *ctx, arg_mtsm *a)
#endif
}
-#ifndef CONFIG_USER_ONLY
-static bool trans_rfi(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool do_rfi(DisasContext *ctx, bool rfi_r)
{
- unsigned comp = extract32(insn, 5, 4);
-
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
+#ifndef CONFIG_USER_ONLY
nullify_over(ctx);
- if (comp == 5) {
+ if (rfi_r) {
gen_helper_rfi_r(cpu_env);
} else {
gen_helper_rfi(cpu_env);
@@ -2298,8 +2289,20 @@ static bool trans_rfi(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
ctx->base.is_jmp = DISAS_NORETURN;
return nullify_end(ctx);
+#endif
}
+static bool trans_rfi(DisasContext *ctx, arg_rfi *a)
+{
+ return do_rfi(ctx, false);
+}
+
+static bool trans_rfi_r(DisasContext *ctx, arg_rfi_r *a)
+{
+ return do_rfi(ctx, true);
+}
+
+#ifndef CONFIG_USER_ONLY
static bool gen_hlt(DisasContext *ctx, int reset)
{
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
@@ -2314,17 +2317,6 @@ static bool gen_hlt(DisasContext *ctx, int reset)
}
#endif /* !CONFIG_USER_ONLY */
-static const DisasInsn table_system[] = {
- { 0x00000400u, 0xffffffffu, trans_sync }, /* sync */
- { 0x00100400u, 0xffffffffu, trans_sync }, /* syncdma */
- { 0x000010a0u, 0xfc1f3fe0u, trans_ldsid },
-#ifndef CONFIG_USER_ONLY
- { 0x00000e60u, 0xfc00ffe0u, trans_rsm },
- { 0x00000d60u, 0xfc00ffe0u, trans_ssm },
- { 0x00000c00u, 0xfffffe1fu, trans_rfi },
-#endif
-};
-
static bool trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
@@ -4542,9 +4534,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
opc = extract32(insn, 26, 6);
switch (opc) {
- case 0x00: /* system op */
- translate_table(ctx, insn, table_system);
- return;
case 0x01:
translate_table(ctx, insn, table_mem_mgmt);
return;
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 047a9d01ec..16ea5e1b46 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -23,6 +23,8 @@
%assemble_sr3 13:1 14:2
+%sm_imm 16:10 !function=expand_sm_imm
+
####
# System
####
@@ -37,3 +39,13 @@ mtsm 000000 00000 r:5 000 11000011 00000
mfia 000000 ----- 00000 --- 10100101 t:5
mfsp 000000 ----- 00000 ... 00100101 t:5 sp=%assemble_sr3
mfctl 000000 r:5 00000- e:1 -01000101 t:5
+
+sync 000000 ----- ----- 000 00100000 00000 # sync, syncdma
+
+ldsid 000000 b:5 ----- sp:2 0 10000101 t:5
+
+rsm 000000 .......... 000 01110011 t:5 i=%sm_imm
+ssm 000000 .......... 000 01101011 t:5 i=%sm_imm
+
+rfi 000000 ----- ----- --- 01100000 00000
+rfi_r 000000 ----- ----- --- 01100101 00000
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 05/19] target/hppa: Unify specializations of OR
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (3 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 04/19] target/hppa: Convert remainder of system insns Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 06/19] target/hppa: Convert memory management insns Richard Henderson
` (14 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
With decodetree.py, the specializations would conflict so we
must have a single entry point for all variants of OR.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 108 ++++++++++++++++++++++------------------
1 file changed, 59 insertions(+), 49 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 2ca0f5da10..6c2f560fc1 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2622,21 +2622,69 @@ static bool trans_log(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
return nullify_end(ctx);
}
-/* OR r,0,t -> COPY (according to gas) */
-static bool trans_copy(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_or(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
+ unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
+ unsigned cf = extract32(insn, 12, 4);
unsigned rt = extract32(insn, 0, 5);
+ TCGv_reg tcg_r1, tcg_r2;
- if (r1 == 0) {
- TCGv_reg dest = dest_gpr(ctx, rt);
- tcg_gen_movi_reg(dest, 0);
- save_gpr(ctx, rt, dest);
- } else {
- save_gpr(ctx, rt, cpu_gr[r1]);
+ if (cf == 0) {
+ if (rt == 0) { /* NOP */
+ cond_free(&ctx->null_cond);
+ return true;
+ }
+ if (r2 == 0) { /* COPY */
+ if (r1 == 0) {
+ TCGv_reg dest = dest_gpr(ctx, rt);
+ tcg_gen_movi_reg(dest, 0);
+ save_gpr(ctx, rt, dest);
+ } else {
+ save_gpr(ctx, rt, cpu_gr[r1]);
+ }
+ cond_free(&ctx->null_cond);
+ return true;
+ }
+#ifndef CONFIG_USER_ONLY
+ /* These are QEMU extensions and are nops in the real architecture:
+ *
+ * or %r10,%r10,%r10 -- idle loop; wait for interrupt
+ * or %r31,%r31,%r31 -- death loop; offline cpu
+ * currently implemented as idle.
+ */
+ if ((rt == 10 || rt == 31) && r1 == rt && r2 == rt) { /* PAUSE */
+ TCGv_i32 tmp;
+
+ /* No need to check for supervisor, as userland can only pause
+ until the next timer interrupt. */
+ nullify_over(ctx);
+
+ /* Advance the instruction queue. */
+ copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
+ copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
+ nullify_set(ctx, 0);
+
+ /* Tell the qemu main loop to halt until this cpu has work. */
+ tmp = tcg_const_i32(1);
+ tcg_gen_st_i32(tmp, cpu_env, -offsetof(HPPACPU, env) +
+ offsetof(CPUState, halted));
+ tcg_temp_free_i32(tmp);
+ gen_excp_1(EXCP_HALTED);
+ ctx->base.is_jmp = DISAS_NORETURN;
+
+ return nullify_end(ctx);
+ }
+#endif
}
- cond_free(&ctx->null_cond);
- return true;
+
+ if (cf) {
+ nullify_over(ctx);
+ }
+ tcg_r1 = load_gpr(ctx, r1);
+ tcg_r2 = load_gpr(ctx, r2);
+ do_log(ctx, rt, tcg_r1, tcg_r2, cf, tcg_gen_or_reg);
+ return nullify_end(ctx);
}
static bool trans_cmpclr(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
@@ -2781,48 +2829,10 @@ static bool trans_ds(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
return nullify_end(ctx);
}
-#ifndef CONFIG_USER_ONLY
-/* These are QEMU extensions and are nops in the real architecture:
- *
- * or %r10,%r10,%r10 -- idle loop; wait for interrupt
- * or %r31,%r31,%r31 -- death loop; offline cpu
- * currently implemented as idle.
- */
-static bool trans_pause(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
-{
- TCGv_i32 tmp;
-
- /* No need to check for supervisor, as userland can only pause
- until the next timer interrupt. */
- nullify_over(ctx);
-
- /* Advance the instruction queue. */
- copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
- copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
- nullify_set(ctx, 0);
-
- /* Tell the qemu main loop to halt until this cpu has work. */
- tmp = tcg_const_i32(1);
- tcg_gen_st_i32(tmp, cpu_env, -offsetof(HPPACPU, env) +
- offsetof(CPUState, halted));
- tcg_temp_free_i32(tmp);
- gen_excp_1(EXCP_HALTED);
- ctx->base.is_jmp = DISAS_NORETURN;
-
- return nullify_end(ctx);
-}
-#endif
-
static const DisasInsn table_arith_log[] = {
- { 0x08000240u, 0xfc00ffffu, trans_nop }, /* or x,y,0 */
- { 0x08000240u, 0xffe0ffe0u, trans_copy }, /* or x,0,t */
-#ifndef CONFIG_USER_ONLY
- { 0x094a024au, 0xffffffffu, trans_pause }, /* or r10,r10,r10 */
- { 0x0bff025fu, 0xffffffffu, trans_pause }, /* or r31,r31,r31 */
-#endif
+ { 0x08000240u, 0xfc000fe0u, trans_or },
{ 0x08000000u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_andc_reg },
{ 0x08000200u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_and_reg },
- { 0x08000240u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_or_reg },
{ 0x08000280u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_xor_reg },
{ 0x08000880u, 0xfc000fe0u, trans_cmpclr },
{ 0x08000380u, 0xfc000fe0u, trans_uxor },
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 06/19] target/hppa: Convert memory management insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (4 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 05/19] target/hppa: Unify specializations of OR Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 07/19] target/hppa: Convert arithmetic/logical insns Richard Henderson
` (13 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 162 ++++++++++++---------------------------
target/hppa/insns.decode | 38 +++++++++
2 files changed, 89 insertions(+), 111 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 6c2f560fc1..961b890153 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -290,6 +290,12 @@ static int expand_sm_imm(int val)
return val;
}
+/* Inverted space register indicates 0 means sr0 not inferred from base. */
+static int expand_sr3x(int val)
+{
+ return ~val;
+}
+
/* Include the auto-generated decoder. */
#include "decode.inc.c"
@@ -1997,7 +2003,7 @@ static void do_page_zero(DisasContext *ctx)
}
#endif
-static bool trans_nop(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_nop(DisasContext *ctx, arg_nop *a)
{
cond_free(&ctx->null_cond);
return true;
@@ -2317,81 +2323,62 @@ static bool gen_hlt(DisasContext *ctx, int reset)
}
#endif /* !CONFIG_USER_ONLY */
-static bool trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_nop_addrx(DisasContext *ctx, arg_ldst *a)
{
- unsigned rb = extract32(insn, 21, 5);
- unsigned rx = extract32(insn, 16, 5);
- TCGv_reg dest = dest_gpr(ctx, rb);
- TCGv_reg src1 = load_gpr(ctx, rb);
- TCGv_reg src2 = load_gpr(ctx, rx);
-
- /* The only thing we need to do is the base register modification. */
- tcg_gen_add_reg(dest, src1, src2);
- save_gpr(ctx, rb, dest);
+ if (a->m) {
+ TCGv_reg dest = dest_gpr(ctx, a->b);
+ TCGv_reg src1 = load_gpr(ctx, a->b);
+ TCGv_reg src2 = load_gpr(ctx, a->x);
+ /* The only thing we need to do is the base register modification. */
+ tcg_gen_add_reg(dest, src1, src2);
+ save_gpr(ctx, a->b, dest);
+ }
cond_free(&ctx->null_cond);
return true;
}
-static bool trans_probe(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_probe(DisasContext *ctx, arg_probe *a)
{
- unsigned rt = extract32(insn, 0, 5);
- unsigned sp = extract32(insn, 14, 2);
- unsigned rr = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
- unsigned is_write = extract32(insn, 6, 1);
- unsigned is_imm = extract32(insn, 13, 1);
TCGv_reg dest, ofs;
TCGv_i32 level, want;
TCGv_tl addr;
nullify_over(ctx);
- dest = dest_gpr(ctx, rt);
- form_gva(ctx, &addr, &ofs, rb, 0, 0, 0, sp, 0, false);
+ dest = dest_gpr(ctx, a->t);
+ form_gva(ctx, &addr, &ofs, a->b, 0, 0, 0, a->sp, 0, false);
- if (is_imm) {
- level = tcg_const_i32(extract32(insn, 16, 2));
+ if (a->imm) {
+ level = tcg_const_i32(a->ri);
} else {
level = tcg_temp_new_i32();
- tcg_gen_trunc_reg_i32(level, load_gpr(ctx, rr));
+ tcg_gen_trunc_reg_i32(level, load_gpr(ctx, a->ri));
tcg_gen_andi_i32(level, level, 3);
}
- want = tcg_const_i32(is_write ? PAGE_WRITE : PAGE_READ);
+ want = tcg_const_i32(a->write ? PAGE_WRITE : PAGE_READ);
gen_helper_probe(dest, cpu_env, addr, level, want);
tcg_temp_free_i32(want);
tcg_temp_free_i32(level);
- save_gpr(ctx, rt, dest);
+ save_gpr(ctx, a->t, dest);
return nullify_end(ctx);
}
-#ifndef CONFIG_USER_ONLY
-static bool trans_ixtlbx(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_ixtlbx(DisasContext *ctx, arg_ixtlbx *a)
{
- unsigned sp;
- unsigned rr = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
- unsigned is_data = insn & 0x1000;
- unsigned is_addr = insn & 0x40;
+ CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
+#ifndef CONFIG_USER_ONLY
TCGv_tl addr;
TCGv_reg ofs, reg;
- if (is_data) {
- sp = extract32(insn, 14, 2);
- } else {
- sp = ~assemble_sr3(insn);
- }
-
- CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
nullify_over(ctx);
- form_gva(ctx, &addr, &ofs, rb, 0, 0, 0, sp, 0, false);
- reg = load_gpr(ctx, rr);
- if (is_addr) {
+ form_gva(ctx, &addr, &ofs, a->b, 0, 0, 0, a->sp, 0, false);
+ reg = load_gpr(ctx, a->r);
+ if (a->addr) {
gen_helper_itlba(cpu_env, addr, reg);
} else {
gen_helper_itlbp(cpu_env, addr, reg);
@@ -2399,80 +2386,67 @@ static bool trans_ixtlbx(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
/* Exit TB for ITLB change if mmu is enabled. This *should* not be
the case, since the OS TLB fill handler runs with mmu disabled. */
- if (!is_data && (ctx->tb_flags & PSW_C)) {
+ if (!a->data && (ctx->tb_flags & PSW_C)) {
ctx->base.is_jmp = DISAS_IAQ_N_STALE;
}
return nullify_end(ctx);
+#endif
}
-static bool trans_pxtlbx(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_pxtlbx(DisasContext *ctx, arg_pxtlbx *a)
{
- unsigned m = extract32(insn, 5, 1);
- unsigned sp;
- unsigned rx = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
- unsigned is_data = insn & 0x1000;
- unsigned is_local = insn & 0x40;
+ CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
+#ifndef CONFIG_USER_ONLY
TCGv_tl addr;
TCGv_reg ofs;
- if (is_data) {
- sp = extract32(insn, 14, 2);
- } else {
- sp = ~assemble_sr3(insn);
- }
-
- CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
nullify_over(ctx);
- form_gva(ctx, &addr, &ofs, rb, rx, 0, 0, sp, m, false);
- if (m) {
- save_gpr(ctx, rb, ofs);
+ form_gva(ctx, &addr, &ofs, a->b, a->x, 0, 0, a->sp, a->m, false);
+ if (a->m) {
+ save_gpr(ctx, a->b, ofs);
}
- if (is_local) {
+ if (a->local) {
gen_helper_ptlbe(cpu_env);
} else {
gen_helper_ptlb(cpu_env, addr);
}
/* Exit TB for TLB change if mmu is enabled. */
- if (!is_data && (ctx->tb_flags & PSW_C)) {
+ if (!a->data && (ctx->tb_flags & PSW_C)) {
ctx->base.is_jmp = DISAS_IAQ_N_STALE;
}
return nullify_end(ctx);
+#endif
}
-static bool trans_lpa(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_lpa(DisasContext *ctx, arg_ldst *a)
{
- unsigned rt = extract32(insn, 0, 5);
- unsigned m = extract32(insn, 5, 1);
- unsigned sp = extract32(insn, 14, 2);
- unsigned rx = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
+ CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
+#ifndef CONFIG_USER_ONLY
TCGv_tl vaddr;
TCGv_reg ofs, paddr;
- CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
nullify_over(ctx);
- form_gva(ctx, &vaddr, &ofs, rb, rx, 0, 0, sp, m, false);
+ form_gva(ctx, &vaddr, &ofs, a->b, a->x, 0, 0, a->sp, a->m, false);
paddr = tcg_temp_new();
gen_helper_lpa(paddr, cpu_env, vaddr);
/* Note that physical address result overrides base modification. */
- if (m) {
- save_gpr(ctx, rb, ofs);
+ if (a->m) {
+ save_gpr(ctx, a->b, ofs);
}
- save_gpr(ctx, rt, paddr);
+ save_gpr(ctx, a->t, paddr);
tcg_temp_free(paddr);
return nullify_end(ctx);
+#endif
}
-static bool trans_lci(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_lci(DisasContext *ctx, arg_lci *a)
{
- unsigned rt = extract32(insn, 0, 5);
TCGv_reg ci;
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
@@ -2482,43 +2456,12 @@ static bool trans_lci(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
view of the cache. Our implementation is to return 0 for all,
since the entire address space is coherent. */
ci = tcg_const_reg(0);
- save_gpr(ctx, rt, ci);
+ save_gpr(ctx, a->t, ci);
tcg_temp_free(ci);
cond_free(&ctx->null_cond);
return true;
}
-#endif /* !CONFIG_USER_ONLY */
-
-static const DisasInsn table_mem_mgmt[] = {
- { 0x04003280u, 0xfc003fffu, trans_nop }, /* fdc, disp */
- { 0x04001280u, 0xfc003fffu, trans_nop }, /* fdc, index */
- { 0x040012a0u, 0xfc003fffu, trans_base_idx_mod }, /* fdc, index, base mod */
- { 0x040012c0u, 0xfc003fffu, trans_nop }, /* fdce */
- { 0x040012e0u, 0xfc003fffu, trans_base_idx_mod }, /* fdce, base mod */
- { 0x04000280u, 0xfc001fffu, trans_nop }, /* fic 0a */
- { 0x040002a0u, 0xfc001fffu, trans_base_idx_mod }, /* fic 0a, base mod */
- { 0x040013c0u, 0xfc003fffu, trans_nop }, /* fic 4f */
- { 0x040013e0u, 0xfc003fffu, trans_base_idx_mod }, /* fic 4f, base mod */
- { 0x040002c0u, 0xfc001fffu, trans_nop }, /* fice */
- { 0x040002e0u, 0xfc001fffu, trans_base_idx_mod }, /* fice, base mod */
- { 0x04002700u, 0xfc003fffu, trans_nop }, /* pdc */
- { 0x04002720u, 0xfc003fffu, trans_base_idx_mod }, /* pdc, base mod */
- { 0x04001180u, 0xfc003fa0u, trans_probe }, /* probe */
- { 0x04003180u, 0xfc003fa0u, trans_probe }, /* probei */
-#ifndef CONFIG_USER_ONLY
- { 0x04000000u, 0xfc001fffu, trans_ixtlbx }, /* iitlbp */
- { 0x04000040u, 0xfc001fffu, trans_ixtlbx }, /* iitlba */
- { 0x04001000u, 0xfc001fffu, trans_ixtlbx }, /* idtlbp */
- { 0x04001040u, 0xfc001fffu, trans_ixtlbx }, /* idtlba */
- { 0x04000200u, 0xfc001fdfu, trans_pxtlbx }, /* pitlb */
- { 0x04000240u, 0xfc001fdfu, trans_pxtlbx }, /* pitlbe */
- { 0x04001200u, 0xfc001fdfu, trans_pxtlbx }, /* pdtlb */
- { 0x04001240u, 0xfc001fdfu, trans_pxtlbx }, /* pdtlbe */
- { 0x04001340u, 0xfc003fc0u, trans_lpa },
- { 0x04001300u, 0xfc003fe0u, trans_lci },
-#endif
-};
static bool trans_add(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
{
@@ -4544,9 +4487,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
opc = extract32(insn, 26, 6);
switch (opc) {
- case 0x01:
- translate_table(ctx, insn, table_mem_mgmt);
- return;
case 0x02:
translate_table(ctx, insn, table_arith_log);
return;
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 16ea5e1b46..41c999eeb8 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -22,9 +22,17 @@
####
%assemble_sr3 13:1 14:2
+%assemble_sr3x 13:1 14:2 !function=expand_sr3x
%sm_imm 16:10 !function=expand_sm_imm
+####
+# Argument set definitions
+####
+
+# All insns that need to form a virtual address should use this set.
+&ldst t b x disp sp m scale size
+
####
# System
####
@@ -49,3 +57,33 @@ ssm 000000 .......... 000 01101011 t:5 i=%sm_imm
rfi 000000 ----- ----- --- 01100000 00000
rfi_r 000000 ----- ----- --- 01100101 00000
+
+####
+# Memory Management
+####
+
+@addrx ...... b:5 x:5 .. ........ m:1 ..... \
+ &ldst disp=0 scale=0 t=0 sp=0 size=0
+
+nop 000001 ----- ----- -- 11001010 0 ----- # fdc, disp
+nop_addrx 000001 ..... ..... -- 01001010 . ----- @addrx # fdc, index
+nop_addrx 000001 ..... ..... -- 01001011 . ----- @addrx # fdce
+nop_addrx 000001 ..... ..... --- 0001010 . ----- @addrx # fic 0x0a
+nop_addrx 000001 ..... ..... -- 01001111 . 00000 @addrx # fic 0x4f
+nop_addrx 000001 ..... ..... --- 0001011 . ----- @addrx # fice
+nop_addrx 000001 ..... ..... -- 01001110 . 00000 @addrx # pdc
+
+probe 000001 b:5 ri:5 sp:2 imm:1 100011 write:1 0 t:5
+
+ixtlbx 000001 b:5 r:5 sp:2 0100000 addr:1 0 00000 data=1
+ixtlbx 000001 b:5 r:5 ... 000000 addr:1 0 00000 \
+ sp=%assemble_sr3x data=0
+
+pxtlbx 000001 b:5 x:5 sp:2 0100100 local:1 m:1 ----- data=1
+pxtlbx 000001 b:5 x:5 ... 000100 local:1 m:1 ----- \
+ sp=%assemble_sr3x data=0
+
+lpa 000001 b:5 x:5 sp:2 01001101 m:1 t:5 \
+ &ldst disp=0 scale=0 size=0
+
+lci 000001 ----- ----- -- 01001100 0 t:5
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 07/19] target/hppa: Convert arithmetic/logical insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (5 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 06/19] target/hppa: Convert memory management insns Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 08/19] target/hppa: Convert indexed memory insns Richard Henderson
` (12 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 326 ++++++++++++++++++---------------------
target/hppa/insns.decode | 42 +++++
2 files changed, 195 insertions(+), 173 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 961b890153..6c7d301904 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1217,6 +1217,20 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1,
ctx->null_cond = cond;
}
+static bool do_add_reg(DisasContext *ctx, arg_rrr_cf_sh *a,
+ bool is_l, bool is_tsv, bool is_tc, bool is_c)
+{
+ TCGv_reg tcg_r1, tcg_r2;
+
+ if (a->cf) {
+ nullify_over(ctx);
+ }
+ tcg_r1 = load_gpr(ctx, a->r1);
+ tcg_r2 = load_gpr(ctx, a->r2);
+ do_add(ctx, a->t, tcg_r1, tcg_r2, a->sh, is_l, is_tsv, is_tc, is_c, a->cf);
+ return nullify_end(ctx);
+}
+
static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
TCGv_reg in2, bool is_tsv, bool is_b,
bool is_tc, unsigned cf)
@@ -1283,6 +1297,20 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
ctx->null_cond = cond;
}
+static bool do_sub_reg(DisasContext *ctx, arg_rrr_cf *a,
+ bool is_tsv, bool is_b, bool is_tc)
+{
+ TCGv_reg tcg_r1, tcg_r2;
+
+ if (a->cf) {
+ nullify_over(ctx);
+ }
+ tcg_r1 = load_gpr(ctx, a->r1);
+ tcg_r2 = load_gpr(ctx, a->r2);
+ do_sub(ctx, a->t, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, a->cf);
+ return nullify_end(ctx);
+}
+
static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
TCGv_reg in2, unsigned cf)
{
@@ -1328,6 +1356,20 @@ static void do_log(DisasContext *ctx, unsigned rt, TCGv_reg in1,
}
}
+static bool do_log_reg(DisasContext *ctx, arg_rrr_cf *a,
+ void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
+{
+ TCGv_reg tcg_r1, tcg_r2;
+
+ if (a->cf) {
+ nullify_over(ctx);
+ }
+ tcg_r1 = load_gpr(ctx, a->r1);
+ tcg_r2 = load_gpr(ctx, a->r2);
+ do_log(ctx, a->t, tcg_r1, tcg_r2, a->cf, fn);
+ return nullify_end(ctx);
+}
+
static void do_unit(DisasContext *ctx, unsigned rt, TCGv_reg in1,
TCGv_reg in2, unsigned cf, bool is_tc,
void (*fn)(TCGv_reg, TCGv_reg, TCGv_reg))
@@ -2463,117 +2505,78 @@ static bool trans_lci(DisasContext *ctx, arg_lci *a)
return true;
}
-static bool trans_add(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_add(DisasContext *ctx, arg_rrr_cf_sh *a)
{
- unsigned r2 = extract32(insn, 21, 5);
- unsigned r1 = extract32(insn, 16, 5);
- unsigned cf = extract32(insn, 12, 4);
- unsigned ext = extract32(insn, 8, 4);
- unsigned shift = extract32(insn, 6, 2);
- unsigned rt = extract32(insn, 0, 5);
- TCGv_reg tcg_r1, tcg_r2;
- bool is_c = false;
- bool is_l = false;
- bool is_tc = false;
- bool is_tsv = false;
-
- switch (ext) {
- case 0x6: /* ADD, SHLADD */
- break;
- case 0xa: /* ADD,L, SHLADD,L */
- is_l = true;
- break;
- case 0xe: /* ADD,TSV, SHLADD,TSV (1) */
- is_tsv = true;
- break;
- case 0x7: /* ADD,C */
- is_c = true;
- break;
- case 0xf: /* ADD,C,TSV */
- is_c = is_tsv = true;
- break;
- default:
- return gen_illegal(ctx);
- }
-
- if (cf) {
- nullify_over(ctx);
- }
- tcg_r1 = load_gpr(ctx, r1);
- tcg_r2 = load_gpr(ctx, r2);
- do_add(ctx, rt, tcg_r1, tcg_r2, shift, is_l, is_tsv, is_tc, is_c, cf);
- return nullify_end(ctx);
+ return do_add_reg(ctx, a, false, false, false, false);
}
-static bool trans_sub(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_add_l(DisasContext *ctx, arg_rrr_cf_sh *a)
{
- unsigned r2 = extract32(insn, 21, 5);
- unsigned r1 = extract32(insn, 16, 5);
- unsigned cf = extract32(insn, 12, 4);
- unsigned ext = extract32(insn, 6, 6);
- unsigned rt = extract32(insn, 0, 5);
- TCGv_reg tcg_r1, tcg_r2;
- bool is_b = false;
- bool is_tc = false;
- bool is_tsv = false;
-
- switch (ext) {
- case 0x10: /* SUB */
- break;
- case 0x30: /* SUB,TSV */
- is_tsv = true;
- break;
- case 0x14: /* SUB,B */
- is_b = true;
- break;
- case 0x34: /* SUB,B,TSV */
- is_b = is_tsv = true;
- break;
- case 0x13: /* SUB,TC */
- is_tc = true;
- break;
- case 0x33: /* SUB,TSV,TC */
- is_tc = is_tsv = true;
- break;
- default:
- return gen_illegal(ctx);
- }
-
- if (cf) {
- nullify_over(ctx);
- }
- tcg_r1 = load_gpr(ctx, r1);
- tcg_r2 = load_gpr(ctx, r2);
- do_sub(ctx, rt, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, cf);
- return nullify_end(ctx);
+ return do_add_reg(ctx, a, true, false, false, false);
}
-static bool trans_log(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_add_tsv(DisasContext *ctx, arg_rrr_cf_sh *a)
{
- unsigned r2 = extract32(insn, 21, 5);
- unsigned r1 = extract32(insn, 16, 5);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 0, 5);
- TCGv_reg tcg_r1, tcg_r2;
-
- if (cf) {
- nullify_over(ctx);
- }
- tcg_r1 = load_gpr(ctx, r1);
- tcg_r2 = load_gpr(ctx, r2);
- do_log(ctx, rt, tcg_r1, tcg_r2, cf, di->f.ttt);
- return nullify_end(ctx);
+ return do_add_reg(ctx, a, false, true, false, false);
}
-static bool trans_or(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_add_c(DisasContext *ctx, arg_rrr_cf_sh *a)
{
- unsigned r2 = extract32(insn, 21, 5);
- unsigned r1 = extract32(insn, 16, 5);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 0, 5);
- TCGv_reg tcg_r1, tcg_r2;
+ return do_add_reg(ctx, a, false, false, false, true);
+}
+
+static bool trans_add_c_tsv(DisasContext *ctx, arg_rrr_cf_sh *a)
+{
+ return do_add_reg(ctx, a, false, true, false, true);
+}
+
+static bool trans_sub(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_sub_reg(ctx, a, false, false, false);
+}
+
+static bool trans_sub_tsv(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_sub_reg(ctx, a, true, false, false);
+}
+
+static bool trans_sub_tc(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_sub_reg(ctx, a, false, false, true);
+}
+
+static bool trans_sub_tsv_tc(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_sub_reg(ctx, a, true, false, true);
+}
+
+static bool trans_sub_b(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_sub_reg(ctx, a, false, true, false);
+}
+
+static bool trans_sub_b_tsv(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_sub_reg(ctx, a, true, true, false);
+}
+
+static bool trans_andcm(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_log_reg(ctx, a, tcg_gen_andc_reg);
+}
+
+static bool trans_and(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_log_reg(ctx, a, tcg_gen_and_reg);
+}
+
+static bool trans_or(DisasContext *ctx, arg_rrr_cf *a)
+{
+ if (a->cf == 0) {
+ unsigned r2 = a->r2;
+ unsigned r1 = a->r1;
+ unsigned rt = a->t;
- if (cf == 0) {
if (rt == 0) { /* NOP */
cond_free(&ctx->null_cond);
return true;
@@ -2620,76 +2623,67 @@ static bool trans_or(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
}
#endif
}
-
- if (cf) {
- nullify_over(ctx);
- }
- tcg_r1 = load_gpr(ctx, r1);
- tcg_r2 = load_gpr(ctx, r2);
- do_log(ctx, rt, tcg_r1, tcg_r2, cf, tcg_gen_or_reg);
- return nullify_end(ctx);
+ return do_log_reg(ctx, a, tcg_gen_or_reg);
}
-static bool trans_cmpclr(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_xor(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_log_reg(ctx, a, tcg_gen_xor_reg);
+}
+
+static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf *a)
{
- unsigned r2 = extract32(insn, 21, 5);
- unsigned r1 = extract32(insn, 16, 5);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 0, 5);
TCGv_reg tcg_r1, tcg_r2;
- if (cf) {
+ if (a->cf) {
nullify_over(ctx);
}
- tcg_r1 = load_gpr(ctx, r1);
- tcg_r2 = load_gpr(ctx, r2);
- do_cmpclr(ctx, rt, tcg_r1, tcg_r2, cf);
+ tcg_r1 = load_gpr(ctx, a->r1);
+ tcg_r2 = load_gpr(ctx, a->r2);
+ do_cmpclr(ctx, a->t, tcg_r1, tcg_r2, a->cf);
return nullify_end(ctx);
}
-static bool trans_uxor(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_uxor(DisasContext *ctx, arg_rrr_cf *a)
{
- unsigned r2 = extract32(insn, 21, 5);
- unsigned r1 = extract32(insn, 16, 5);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 0, 5);
TCGv_reg tcg_r1, tcg_r2;
- if (cf) {
+ if (a->cf) {
nullify_over(ctx);
}
- tcg_r1 = load_gpr(ctx, r1);
- tcg_r2 = load_gpr(ctx, r2);
- do_unit(ctx, rt, tcg_r1, tcg_r2, cf, false, tcg_gen_xor_reg);
+ 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, false, tcg_gen_xor_reg);
return nullify_end(ctx);
}
-static bool trans_uaddcm(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool do_uaddcm(DisasContext *ctx, arg_rrr_cf *a, bool is_tc)
{
- unsigned r2 = extract32(insn, 21, 5);
- unsigned r1 = extract32(insn, 16, 5);
- unsigned cf = extract32(insn, 12, 4);
- unsigned is_tc = extract32(insn, 6, 1);
- unsigned rt = extract32(insn, 0, 5);
TCGv_reg tcg_r1, tcg_r2, tmp;
- if (cf) {
+ if (a->cf) {
nullify_over(ctx);
}
- tcg_r1 = load_gpr(ctx, r1);
- tcg_r2 = load_gpr(ctx, r2);
+ tcg_r1 = load_gpr(ctx, a->r1);
+ tcg_r2 = load_gpr(ctx, a->r2);
tmp = get_temp(ctx);
tcg_gen_not_reg(tmp, tcg_r2);
- do_unit(ctx, rt, tcg_r1, tmp, cf, is_tc, tcg_gen_add_reg);
+ do_unit(ctx, a->t, tcg_r1, tmp, a->cf, is_tc, tcg_gen_add_reg);
return nullify_end(ctx);
}
-static bool trans_dcor(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_uaddcm(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_uaddcm(ctx, a, false);
+}
+
+static bool trans_uaddcm_tc(DisasContext *ctx, arg_rrr_cf *a)
+{
+ return do_uaddcm(ctx, a, true);
+}
+
+static bool do_dcor(DisasContext *ctx, arg_rr_cf *a, bool is_i)
{
- unsigned r2 = extract32(insn, 21, 5);
- unsigned cf = extract32(insn, 12, 4);
- unsigned is_i = extract32(insn, 6, 1);
- unsigned rt = extract32(insn, 0, 5);
TCGv_reg tmp;
nullify_over(ctx);
@@ -2701,24 +2695,29 @@ static bool trans_dcor(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
}
tcg_gen_andi_reg(tmp, tmp, 0x11111111);
tcg_gen_muli_reg(tmp, tmp, 6);
- do_unit(ctx, rt, tmp, load_gpr(ctx, r2), cf, false,
+ do_unit(ctx, a->t, tmp, load_gpr(ctx, a->r), a->cf, false,
is_i ? tcg_gen_add_reg : tcg_gen_sub_reg);
-
return nullify_end(ctx);
}
-static bool trans_ds(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_dcor(DisasContext *ctx, arg_rr_cf *a)
+{
+ return do_dcor(ctx, a, false);
+}
+
+static bool trans_dcor_i(DisasContext *ctx, arg_rr_cf *a)
+{
+ return do_dcor(ctx, a, true);
+}
+
+static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
{
- unsigned r2 = extract32(insn, 21, 5);
- unsigned r1 = extract32(insn, 16, 5);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 0, 5);
TCGv_reg dest, add1, add2, addc, zero, in1, in2;
nullify_over(ctx);
- in1 = load_gpr(ctx, r1);
- in2 = load_gpr(ctx, r2);
+ in1 = load_gpr(ctx, a->r1);
+ in2 = load_gpr(ctx, a->r2);
add1 = tcg_temp_new();
add2 = tcg_temp_new();
@@ -2745,7 +2744,7 @@ static bool trans_ds(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
tcg_temp_free(zero);
/* Write back the result register. */
- save_gpr(ctx, rt, dest);
+ save_gpr(ctx, a->t, dest);
/* Write back PSW[CB]. */
tcg_gen_xor_reg(cpu_psw_cb, add1, add2);
@@ -2756,13 +2755,13 @@ static bool trans_ds(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
tcg_gen_xor_reg(cpu_psw_v, cpu_psw_v, in2);
/* Install the new nullification. */
- if (cf) {
+ if (a->cf) {
TCGv_reg sv = NULL;
- if (cf >> 1 == 6) {
+ if (a->cf >> 1 == 6) {
/* ??? The lshift is supposed to contribute to overflow. */
sv = do_add_sv(ctx, dest, add1, add2);
}
- ctx->null_cond = do_cond(cf, dest, cpu_psw_cb_msb, sv);
+ ctx->null_cond = do_cond(a->cf, dest, cpu_psw_cb_msb, sv);
}
tcg_temp_free(add1);
@@ -2772,22 +2771,6 @@ static bool trans_ds(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
return nullify_end(ctx);
}
-static const DisasInsn table_arith_log[] = {
- { 0x08000240u, 0xfc000fe0u, trans_or },
- { 0x08000000u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_andc_reg },
- { 0x08000200u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_and_reg },
- { 0x08000280u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_xor_reg },
- { 0x08000880u, 0xfc000fe0u, trans_cmpclr },
- { 0x08000380u, 0xfc000fe0u, trans_uxor },
- { 0x08000980u, 0xfc000fa0u, trans_uaddcm },
- { 0x08000b80u, 0xfc1f0fa0u, trans_dcor },
- { 0x08000440u, 0xfc000fe0u, trans_ds },
- { 0x08000700u, 0xfc0007e0u, trans_add }, /* add */
- { 0x08000400u, 0xfc0006e0u, trans_sub }, /* sub; sub,b; sub,tsv */
- { 0x080004c0u, 0xfc0007e0u, trans_sub }, /* sub,tc; sub,tsv,tc */
- { 0x08000200u, 0xfc000320u, trans_add }, /* shladd */
-};
-
static bool trans_addi(DisasContext *ctx, uint32_t insn)
{
target_sreg im = low_sextract(insn, 0, 11);
@@ -4487,9 +4470,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
opc = extract32(insn, 26, 6);
switch (opc) {
- case 0x02:
- translate_table(ctx, insn, table_arith_log);
- return;
case 0x03:
translate_table(ctx, insn, table_index_mem);
return;
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 41c999eeb8..a576bb1d4d 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -33,6 +33,19 @@
# All insns that need to form a virtual address should use this set.
&ldst t b x disp sp m scale size
+&rr_cf t r cf
+&rrr_cf t r1 r2 cf
+&rrr_cf_sh t r1 r2 cf sh
+
+####
+# Format definitions
+####
+
+@rr_cf ...... r:5 ..... cf:4 ....... t:5 &rr_cf
+@rrr_cf ...... r2:5 r1:5 cf:4 ....... t:5 &rrr_cf
+@rrr_cf_sh ...... r2:5 r1:5 cf:4 .... sh:2 . t:5 &rrr_cf_sh
+@rrr_cf_sh0 ...... r2:5 r1:5 cf:4 ....... t:5 &rrr_cf_sh sh=0
+
####
# System
####
@@ -87,3 +100,32 @@ lpa 000001 b:5 x:5 sp:2 01001101 m:1 t:5 \
&ldst disp=0 scale=0 size=0
lci 000001 ----- ----- -- 01001100 0 t:5
+
+####
+# Arith/Log
+####
+
+andcm 000010 ..... ..... .... 000000 0 ..... @rrr_cf
+and 000010 ..... ..... .... 001000 0 ..... @rrr_cf
+or 000010 ..... ..... .... 001001 0 ..... @rrr_cf
+xor 000010 ..... ..... .... 001010 0 ..... @rrr_cf
+uxor 000010 ..... ..... .... 001110 0 ..... @rrr_cf
+ds 000010 ..... ..... .... 010001 0 ..... @rrr_cf
+cmpclr 000010 ..... ..... .... 100010 0 ..... @rrr_cf
+uaddcm 000010 ..... ..... .... 100110 0 ..... @rrr_cf
+uaddcm_tc 000010 ..... ..... .... 100111 0 ..... @rrr_cf
+dcor 000010 ..... 00000 .... 101110 0 ..... @rr_cf
+dcor_i 000010 ..... 00000 .... 101111 0 ..... @rr_cf
+
+add 000010 ..... ..... .... 0110.. 0 ..... @rrr_cf_sh
+add_l 000010 ..... ..... .... 1010.. 0 ..... @rrr_cf_sh
+add_tsv 000010 ..... ..... .... 1110.. 0 ..... @rrr_cf_sh
+add_c 000010 ..... ..... .... 011100 0 ..... @rrr_cf_sh0
+add_c_tsv 000010 ..... ..... .... 111100 0 ..... @rrr_cf_sh0
+
+sub 000010 ..... ..... .... 010000 0 ..... @rrr_cf
+sub_tsv 000010 ..... ..... .... 110000 0 ..... @rrr_cf
+sub_tc 000010 ..... ..... .... 010011 0 ..... @rrr_cf
+sub_tsv_tc 000010 ..... ..... .... 110011 0 ..... @rrr_cf
+sub_b 000010 ..... ..... .... 010100 0 ..... @rrr_cf
+sub_b_tsv 000010 ..... ..... .... 110100 0 ..... @rrr_cf
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 08/19] target/hppa: Convert indexed memory insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (6 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 07/19] target/hppa: Convert arithmetic/logical insns Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 09/19] target/hppa: Convert fp multiply-add Richard Henderson
` (11 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 169 +++++++++------------------------------
target/hppa/insns.decode | 24 ++++++
2 files changed, 60 insertions(+), 133 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 6c7d301904..822d93fb23 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -296,6 +296,13 @@ static int expand_sr3x(int val)
return ~val;
}
+/* Convert the M:A bits within a memory insn to the tri-state value
+ we use for the final M. */
+static int ma_to_m(int val)
+{
+ return val & 2 ? (val & 1 ? -1 : 1) : 0;
+}
+
/* Include the auto-generated decoder. */
#include "decode.inc.c"
@@ -1562,7 +1569,7 @@ static void do_store_64(DisasContext *ctx, TCGv_i64 src, unsigned rb,
#define do_store_reg do_store_32
#endif
-static void do_load(DisasContext *ctx, unsigned rt, unsigned rb,
+static bool do_load(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_sreg disp,
unsigned sp, int modify, TCGMemOp mop)
{
@@ -1580,7 +1587,7 @@ static void do_load(DisasContext *ctx, unsigned rt, unsigned rb,
do_load_reg(ctx, dest, rb, rx, scale, disp, sp, modify, mop);
save_gpr(ctx, rt, dest);
- nullify_end(ctx);
+ return nullify_end(ctx);
}
static void do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
@@ -1623,13 +1630,13 @@ static void do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
nullify_end(ctx);
}
-static void do_store(DisasContext *ctx, unsigned rt, unsigned rb,
+static bool do_store(DisasContext *ctx, unsigned rt, unsigned rb,
target_sreg disp, unsigned sp,
int modify, TCGMemOp mop)
{
nullify_over(ctx);
do_store_reg(ctx, load_gpr(ctx, rt), rb, 0, 0, disp, sp, modify, mop);
- nullify_end(ctx);
+ return nullify_end(ctx);
}
static void do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
@@ -2831,119 +2838,57 @@ static bool trans_cmpiclr(DisasContext *ctx, uint32_t insn)
return nullify_end(ctx);
}
-static bool trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ld(DisasContext *ctx, arg_ldst *a)
{
- unsigned rt = extract32(insn, 0, 5);
- unsigned m = extract32(insn, 5, 1);
- unsigned sz = extract32(insn, 6, 2);
- unsigned a = extract32(insn, 13, 1);
- unsigned sp = extract32(insn, 14, 2);
- int disp = low_sextract(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
- int modify = (m ? (a ? -1 : 1) : 0);
- TCGMemOp mop = MO_TE | sz;
-
- do_load(ctx, rt, rb, 0, 0, disp, sp, modify, mop);
- return true;
+ return do_load(ctx, a->t, a->b, a->x, a->scale ? a->size : 0,
+ a->disp, a->sp, a->m, a->size | MO_TE);
}
-static bool trans_ld_idx_x(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_st(DisasContext *ctx, arg_ldst *a)
{
- unsigned rt = extract32(insn, 0, 5);
- unsigned m = extract32(insn, 5, 1);
- unsigned sz = extract32(insn, 6, 2);
- unsigned u = extract32(insn, 13, 1);
- unsigned sp = extract32(insn, 14, 2);
- unsigned rx = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
- TCGMemOp mop = MO_TE | sz;
-
- do_load(ctx, rt, rb, rx, u ? sz : 0, 0, sp, m, mop);
- return true;
+ assert(a->x == 0 && a->scale == 0);
+ return do_store(ctx, a->t, a->b, a->disp, a->sp, a->m, a->size | MO_TE);
}
-static bool trans_st_idx_i(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ldc(DisasContext *ctx, arg_ldst *a)
{
- int disp = low_sextract(insn, 0, 5);
- unsigned m = extract32(insn, 5, 1);
- unsigned sz = extract32(insn, 6, 2);
- unsigned a = extract32(insn, 13, 1);
- unsigned sp = extract32(insn, 14, 2);
- unsigned rr = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
- int modify = (m ? (a ? -1 : 1) : 0);
- TCGMemOp mop = MO_TE | sz;
-
- do_store(ctx, rr, rb, disp, sp, modify, mop);
- return true;
-}
-
-static bool trans_ldcw(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
-{
- unsigned rt = extract32(insn, 0, 5);
- unsigned m = extract32(insn, 5, 1);
- unsigned i = extract32(insn, 12, 1);
- unsigned au = extract32(insn, 13, 1);
- unsigned sp = extract32(insn, 14, 2);
- unsigned rx = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
- TCGMemOp mop = MO_TEUL | MO_ALIGN_16;
+ TCGMemOp mop = MO_TEUL | MO_ALIGN_16 | a->size;
TCGv_reg zero, dest, ofs;
TCGv_tl addr;
- int modify, disp = 0, scale = 0;
nullify_over(ctx);
- if (i) {
- modify = (m ? (au ? -1 : 1) : 0);
- disp = low_sextract(rx, 0, 5);
- rx = 0;
- } else {
- modify = m;
- if (au) {
- scale = mop & MO_SIZE;
- }
- }
- if (modify) {
+ if (a->m) {
/* Base register modification. Make sure if RT == RB,
we see the result of the load. */
dest = get_temp(ctx);
} else {
- dest = dest_gpr(ctx, rt);
+ dest = dest_gpr(ctx, a->t);
}
- form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
- ctx->mmu_idx == MMU_PHYS_IDX);
+ form_gva(ctx, &addr, &ofs, a->b, a->x, a->scale ? a->size : 0,
+ a->disp, a->sp, a->m, ctx->mmu_idx == MMU_PHYS_IDX);
zero = tcg_const_reg(0);
tcg_gen_atomic_xchg_reg(dest, addr, zero, ctx->mmu_idx, mop);
- if (modify) {
- save_gpr(ctx, rb, ofs);
+ if (a->m) {
+ save_gpr(ctx, a->b, ofs);
}
- save_gpr(ctx, rt, dest);
+ save_gpr(ctx, a->t, dest);
return nullify_end(ctx);
}
-static bool trans_stby(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_stby(DisasContext *ctx, arg_stby *a)
{
- target_sreg disp = low_sextract(insn, 0, 5);
- unsigned m = extract32(insn, 5, 1);
- unsigned a = extract32(insn, 13, 1);
- unsigned sp = extract32(insn, 14, 2);
- unsigned rt = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
TCGv_reg ofs, val;
TCGv_tl addr;
nullify_over(ctx);
- form_gva(ctx, &addr, &ofs, rb, 0, 0, disp, sp, m,
+ form_gva(ctx, &addr, &ofs, a->b, 0, 0, a->disp, a->sp, a->m,
ctx->mmu_idx == MMU_PHYS_IDX);
- val = load_gpr(ctx, rt);
- if (a) {
+ val = load_gpr(ctx, a->r);
+ if (a->a) {
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
gen_helper_stby_e_parallel(cpu_env, addr, val);
} else {
@@ -2956,75 +2901,36 @@ static bool trans_stby(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
gen_helper_stby_b(cpu_env, addr, val);
}
}
-
- if (m) {
+ if (a->m) {
tcg_gen_andi_reg(ofs, ofs, ~3);
- save_gpr(ctx, rb, ofs);
+ save_gpr(ctx, a->b, ofs);
}
return nullify_end(ctx);
}
-#ifndef CONFIG_USER_ONLY
-static bool trans_ldwa_idx_i(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_lda(DisasContext *ctx, arg_ldst *a)
{
int hold_mmu_idx = ctx->mmu_idx;
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
-
- /* ??? needs fixing for hppa64 -- ldda does not follow the same
- format wrt the sub-opcode in bits 6:9. */
ctx->mmu_idx = MMU_PHYS_IDX;
- trans_ld_idx_i(ctx, insn, di);
+ trans_ld(ctx, a);
ctx->mmu_idx = hold_mmu_idx;
return true;
}
-static bool trans_ldwa_idx_x(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_sta(DisasContext *ctx, arg_ldst *a)
{
int hold_mmu_idx = ctx->mmu_idx;
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
-
- /* ??? needs fixing for hppa64 -- ldda does not follow the same
- format wrt the sub-opcode in bits 6:9. */
ctx->mmu_idx = MMU_PHYS_IDX;
- trans_ld_idx_x(ctx, insn, di);
+ trans_st(ctx, a);
ctx->mmu_idx = hold_mmu_idx;
return true;
}
-static bool trans_stwa_idx_i(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- int hold_mmu_idx = ctx->mmu_idx;
-
- CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
-
- /* ??? needs fixing for hppa64 -- ldda does not follow the same
- format wrt the sub-opcode in bits 6:9. */
- ctx->mmu_idx = MMU_PHYS_IDX;
- trans_st_idx_i(ctx, insn, di);
- ctx->mmu_idx = hold_mmu_idx;
- return true;
-}
-#endif
-
-static const DisasInsn table_index_mem[] = {
- { 0x0c001000u, 0xfc001300, trans_ld_idx_i }, /* LD[BHWD], im */
- { 0x0c000000u, 0xfc001300, trans_ld_idx_x }, /* LD[BHWD], rx */
- { 0x0c001200u, 0xfc001300, trans_st_idx_i }, /* ST[BHWD] */
- { 0x0c0001c0u, 0xfc0003c0, trans_ldcw },
- { 0x0c001300u, 0xfc0013c0, trans_stby },
-#ifndef CONFIG_USER_ONLY
- { 0x0c000180u, 0xfc00d3c0, trans_ldwa_idx_x }, /* LDWA, rx */
- { 0x0c001180u, 0xfc00d3c0, trans_ldwa_idx_i }, /* LDWA, im */
- { 0x0c001380u, 0xfc00d3c0, trans_stwa_idx_i }, /* STWA, im */
-#endif
-};
-
static bool trans_ldil(DisasContext *ctx, uint32_t insn)
{
unsigned rt = extract32(insn, 21, 5);
@@ -4470,9 +4376,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
opc = extract32(insn, 26, 6);
switch (opc) {
- case 0x03:
- translate_table(ctx, insn, table_index_mem);
- return;
case 0x06:
trans_fmpyadd(ctx, insn, false);
return;
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index a576bb1d4d..38f5fb6be2 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -26,6 +26,10 @@
%sm_imm 16:10 !function=expand_sm_imm
+%im5_0 0:s1 1:4
+%im5_16 16:s1 17:4
+%ma_to_m 5:1 13:1 !function=ma_to_m
+
####
# Argument set definitions
####
@@ -129,3 +133,23 @@ sub_tc 000010 ..... ..... .... 010011 0 ..... @rrr_cf
sub_tsv_tc 000010 ..... ..... .... 110011 0 ..... @rrr_cf
sub_b 000010 ..... ..... .... 010100 0 ..... @rrr_cf
sub_b_tsv 000010 ..... ..... .... 110100 0 ..... @rrr_cf
+
+####
+# Index Mem
+####
+
+@ldstx ...... b:5 x:5 sp:2 scale:1 ....... m:1 t:5 &ldst disp=0
+@ldim5 ...... b:5 ..... sp:2 ......... t:5 \
+ &ldst disp=%im5_16 x=0 scale=0 m=%ma_to_m
+@stim5 ...... b:5 t:5 sp:2 ......... ..... \
+ &ldst disp=%im5_0 x=0 scale=0 m=%ma_to_m
+
+ld 000011 ..... ..... .. . 1 -- 00 size:2 ...... @ldim5
+ld 000011 ..... ..... .. . 0 -- 00 size:2 ...... @ldstx
+st 000011 ..... ..... .. . 1 -- 10 size:2 ...... @stim5
+ldc 000011 ..... ..... .. . 1 -- 0111 ...... @ldim5 size=2
+ldc 000011 ..... ..... .. . 0 -- 0111 ...... @ldstx size=2
+lda 000011 ..... ..... .. . 1 -- 0110 ...... @ldim5 size=2
+lda 000011 ..... ..... .. . 0 -- 0110 ...... @ldstx size=2
+sta 000011 ..... ..... .. . 1 -- 1110 ...... @stim5 size=2
+stby 000011 b:5 r:5 sp:2 a:1 1 -- 1100 m:1 ..... disp=%im5_0
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 09/19] target/hppa: Convert fp multiply-add
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (7 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 08/19] target/hppa: Convert indexed memory insns Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 10/19] target/hppa: Convert conditional branches Richard Henderson
` (10 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 69 +++++++++++++++++++++++-----------------
target/hppa/insns.decode | 12 +++++++
2 files changed, 52 insertions(+), 29 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 822d93fb23..2f4a50e113 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -4255,37 +4255,54 @@ static inline int fmpyadd_s_reg(unsigned r)
return (r & 16) * 2 + 16 + (r & 15);
}
-static bool trans_fmpyadd(DisasContext *ctx, uint32_t insn, bool is_sub)
+static bool do_fmpyadd_s(DisasContext *ctx, arg_mpyadd *a, bool is_sub)
{
- unsigned tm = extract32(insn, 0, 5);
- unsigned f = extract32(insn, 5, 1);
- unsigned ra = extract32(insn, 6, 5);
- unsigned ta = extract32(insn, 11, 5);
- unsigned rm2 = extract32(insn, 16, 5);
- unsigned rm1 = extract32(insn, 21, 5);
+ int tm = fmpyadd_s_reg(a->tm);
+ int ra = fmpyadd_s_reg(a->ra);
+ int ta = fmpyadd_s_reg(a->ta);
+ int rm2 = fmpyadd_s_reg(a->rm2);
+ int rm1 = fmpyadd_s_reg(a->rm1);
nullify_over(ctx);
- /* Independent multiply & add/sub, with undefined behaviour
- if outputs overlap inputs. */
- if (f == 0) {
- tm = fmpyadd_s_reg(tm);
- ra = fmpyadd_s_reg(ra);
- ta = fmpyadd_s_reg(ta);
- rm2 = fmpyadd_s_reg(rm2);
- rm1 = fmpyadd_s_reg(rm1);
- do_fop_weww(ctx, tm, rm1, rm2, gen_helper_fmpy_s);
- do_fop_weww(ctx, ta, ta, ra,
- is_sub ? gen_helper_fsub_s : gen_helper_fadd_s);
- } else {
- do_fop_dedd(ctx, tm, rm1, rm2, gen_helper_fmpy_d);
- do_fop_dedd(ctx, ta, ta, ra,
- is_sub ? gen_helper_fsub_d : gen_helper_fadd_d);
- }
+ do_fop_weww(ctx, tm, rm1, rm2, gen_helper_fmpy_s);
+ do_fop_weww(ctx, ta, ta, ra,
+ is_sub ? gen_helper_fsub_s : gen_helper_fadd_s);
return nullify_end(ctx);
}
+static bool trans_fmpyadd_f(DisasContext *ctx, arg_mpyadd *a)
+{
+ return do_fmpyadd_s(ctx, a, false);
+}
+
+static bool trans_fmpysub_f(DisasContext *ctx, arg_mpyadd *a)
+{
+ return do_fmpyadd_s(ctx, a, true);
+}
+
+static bool do_fmpyadd_d(DisasContext *ctx, arg_mpyadd *a, bool is_sub)
+{
+ nullify_over(ctx);
+
+ do_fop_dedd(ctx, a->tm, a->rm1, a->rm2, gen_helper_fmpy_d);
+ do_fop_dedd(ctx, a->ta, a->ta, a->ra,
+ is_sub ? gen_helper_fsub_d : gen_helper_fadd_d);
+
+ return nullify_end(ctx);
+}
+
+static bool trans_fmpyadd_d(DisasContext *ctx, arg_mpyadd *a)
+{
+ return do_fmpyadd_d(ctx, a, false);
+}
+
+static bool trans_fmpysub_d(DisasContext *ctx, arg_mpyadd *a)
+{
+ return do_fmpyadd_d(ctx, a, true);
+}
+
static bool trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
@@ -4376,9 +4393,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
opc = extract32(insn, 26, 6);
switch (opc) {
- case 0x06:
- trans_fmpyadd(ctx, insn, false);
- return;
case 0x08:
trans_ldil(ctx, insn);
return;
@@ -4456,9 +4470,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
case 0x25:
trans_subi(ctx, insn);
return;
- case 0x26:
- trans_fmpyadd(ctx, insn, true);
- return;
case 0x27:
trans_cmpb(ctx, insn, true, false, true);
return;
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 38f5fb6be2..16a999b05f 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -153,3 +153,15 @@ lda 000011 ..... ..... .. . 1 -- 0110 ...... @ldim5 size=2
lda 000011 ..... ..... .. . 0 -- 0110 ...... @ldstx size=2
sta 000011 ..... ..... .. . 1 -- 1110 ...... @stim5 size=2
stby 000011 b:5 r:5 sp:2 a:1 1 -- 1100 m:1 ..... disp=%im5_0
+
+####
+# Floating-point Multiply Add
+####
+
+&mpyadd rm1 rm2 ta ra tm
+@mpyadd ...... rm1:5 rm2:5 ta:5 ra:5 . tm:5 &mpyadd
+
+fmpyadd_f 000110 ..... ..... ..... ..... 0 ..... @mpyadd
+fmpyadd_d 000110 ..... ..... ..... ..... 1 ..... @mpyadd
+fmpysub_f 100110 ..... ..... ..... ..... 0 ..... @mpyadd
+fmpysub_d 100110 ..... ..... ..... ..... 1 ..... @mpyadd
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 10/19] target/hppa: Convert conditional branches
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (8 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 09/19] target/hppa: Convert fp multiply-add Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 11/19] target/hppa: Convert shift, extract, deposit insns Richard Henderson
` (9 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 221 +++++++++++++++++----------------------
target/hppa/insns.decode | 30 ++++++
2 files changed, 124 insertions(+), 127 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 2f4a50e113..7bdb900130 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -303,6 +303,13 @@ static int ma_to_m(int val)
return val & 2 ? (val & 1 ? -1 : 1) : 0;
}
+/* Used for branch targets. */
+static int expand_shl2(int val)
+{
+ return val << 2;
+}
+
+
/* Include the auto-generated decoder. */
#include "decode.inc.c"
@@ -870,14 +877,6 @@ static inline unsigned assemble_sr3(uint32_t insn)
return s2 * 4 + s0;
}
-static target_sreg assemble_12(uint32_t insn)
-{
- target_ureg x = -(target_ureg)(insn & 1);
- x = (x << 1) | extract32(insn, 2, 1);
- x = (x << 10) | extract32(insn, 3, 10);
- return x;
-}
-
static target_sreg assemble_16(uint32_t insn)
{
/* Take the name from PA2.0, which produces a 16-bit number
@@ -1773,7 +1772,7 @@ static void do_fop_dedd(DisasContext *ctx, unsigned rt,
/* Emit an unconditional branch to a direct target, which may or may not
have already had nullification handled. */
-static void do_dbranch(DisasContext *ctx, target_ureg dest,
+static bool do_dbranch(DisasContext *ctx, target_ureg dest,
unsigned link, bool is_n)
{
if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
@@ -1805,11 +1804,12 @@ static void do_dbranch(DisasContext *ctx, target_ureg dest,
gen_goto_tb(ctx, 1, ctx->iaoq_b, ctx->iaoq_n);
ctx->base.is_jmp = DISAS_NORETURN;
}
+ return true;
}
/* Emit a conditional branch to a direct target. If the branch itself
is nullified, we should have already used nullify_over. */
-static void do_cbranch(DisasContext *ctx, target_sreg disp, bool is_n,
+static bool do_cbranch(DisasContext *ctx, target_sreg disp, bool is_n,
DisasCond *cond)
{
target_ureg dest = iaoq_dest(ctx, disp);
@@ -1821,12 +1821,10 @@ static void do_cbranch(DisasContext *ctx, target_sreg disp, bool is_n,
/* Handle TRUE and NEVER as direct branches. */
if (c == TCG_COND_ALWAYS) {
- do_dbranch(ctx, dest, 0, is_n && disp >= 0);
- return;
+ return do_dbranch(ctx, dest, 0, is_n && disp >= 0);
}
if (c == TCG_COND_NEVER) {
- do_dbranch(ctx, ctx->iaoq_n, 0, is_n && disp < 0);
- return;
+ return do_dbranch(ctx, ctx->iaoq_n, 0, is_n && disp < 0);
}
taken = gen_new_label();
@@ -1873,11 +1871,12 @@ static void do_cbranch(DisasContext *ctx, target_sreg disp, bool is_n,
} else {
ctx->base.is_jmp = DISAS_NORETURN;
}
+ return true;
}
/* Emit an unconditional branch to an indirect target. This handles
nullification of the branch itself. */
-static void do_ibranch(DisasContext *ctx, TCGv_reg dest,
+static bool do_ibranch(DisasContext *ctx, TCGv_reg dest,
unsigned link, bool is_n)
{
TCGv_reg a0, a1, next, tmp;
@@ -1897,7 +1896,7 @@ static void do_ibranch(DisasContext *ctx, TCGv_reg dest,
tcg_gen_addi_reg(cpu_iaoq_b, next, 4);
nullify_set(ctx, 0);
ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
- return;
+ return true;
}
ctx->null_cond.c = TCG_COND_ALWAYS;
}
@@ -1924,7 +1923,7 @@ static void do_ibranch(DisasContext *ctx, TCGv_reg dest,
tcg_gen_movi_reg(cpu_gr[link], ctx->iaoq_n);
}
tcg_gen_lookup_and_goto_ptr();
- nullify_end(ctx);
+ return nullify_end(ctx);
} else {
cond_prep(&ctx->null_cond);
c = ctx->null_cond.c;
@@ -1955,6 +1954,7 @@ static void do_ibranch(DisasContext *ctx, TCGv_reg dest,
cond_free(&ctx->null_cond);
}
}
+ return true;
}
/* Implement
@@ -3154,24 +3154,12 @@ static bool trans_copr_dw(DisasContext *ctx, uint32_t insn)
return true;
}
-static bool trans_cmpb(DisasContext *ctx, uint32_t insn,
- bool is_true, bool is_imm, bool is_dw)
+static bool do_cmpb(DisasContext *ctx, unsigned r, TCGv_reg in1,
+ unsigned c, unsigned f, unsigned n, int disp)
{
- target_sreg disp = assemble_12(insn) * 4;
- unsigned n = extract32(insn, 1, 1);
- unsigned c = extract32(insn, 13, 3);
- unsigned r = extract32(insn, 21, 5);
- unsigned cf = c * 2 + !is_true;
- TCGv_reg dest, in1, in2, sv;
+ TCGv_reg dest, in2, sv;
DisasCond cond;
- nullify_over(ctx);
-
- if (is_imm) {
- in1 = load_const(ctx, low_sextract(insn, 16, 5));
- } else {
- in1 = load_gpr(ctx, extract32(insn, 16, 5));
- }
in2 = load_gpr(ctx, r);
dest = get_temp(ctx);
@@ -3182,29 +3170,28 @@ static bool trans_cmpb(DisasContext *ctx, uint32_t insn,
sv = do_sub_sv(ctx, dest, in1, in2);
}
- cond = do_sub_cond(cf, dest, in1, in2, sv);
- do_cbranch(ctx, disp, n, &cond);
- return true;
+ cond = do_sub_cond(c * 2 + f, dest, in1, in2, sv);
+ return do_cbranch(ctx, disp, n, &cond);
}
-static bool trans_addb(DisasContext *ctx, uint32_t insn,
- bool is_true, bool is_imm)
+static bool trans_cmpb(DisasContext *ctx, arg_cmpb *a)
{
- target_sreg disp = assemble_12(insn) * 4;
- unsigned n = extract32(insn, 1, 1);
- unsigned c = extract32(insn, 13, 3);
- unsigned r = extract32(insn, 21, 5);
- unsigned cf = c * 2 + !is_true;
- TCGv_reg dest, in1, in2, sv, cb_msb;
+ nullify_over(ctx);
+ return do_cmpb(ctx, a->r2, load_gpr(ctx, a->r1), a->c, a->f, a->n, a->disp);
+}
+
+static bool trans_cmpbi(DisasContext *ctx, arg_cmpbi *a)
+{
+ nullify_over(ctx);
+ return do_cmpb(ctx, a->r, load_const(ctx, a->i), a->c, a->f, a->n, a->disp);
+}
+
+static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1,
+ unsigned c, unsigned f, unsigned n, int disp)
+{
+ TCGv_reg dest, in2, sv, cb_msb;
DisasCond cond;
- nullify_over(ctx);
-
- if (is_imm) {
- in1 = load_const(ctx, low_sextract(insn, 16, 5));
- } else {
- in1 = load_gpr(ctx, extract32(insn, 16, 5));
- }
in2 = load_gpr(ctx, r);
dest = dest_gpr(ctx, r);
sv = NULL;
@@ -3225,62 +3212,84 @@ static bool trans_addb(DisasContext *ctx, uint32_t insn,
break;
}
- cond = do_cond(cf, dest, cb_msb, sv);
- do_cbranch(ctx, disp, n, &cond);
- return true;
+ cond = do_cond(c * 2 + f, dest, cb_msb, sv);
+ return do_cbranch(ctx, disp, n, &cond);
}
-static bool trans_bb(DisasContext *ctx, uint32_t insn)
+static bool trans_addb(DisasContext *ctx, arg_addb *a)
+{
+ nullify_over(ctx);
+ return do_addb(ctx, a->r2, load_gpr(ctx, a->r1), a->c, a->f, a->n, a->disp);
+}
+
+static bool trans_addbi(DisasContext *ctx, arg_addbi *a)
+{
+ nullify_over(ctx);
+ return do_addb(ctx, a->r, load_const(ctx, a->i), a->c, a->f, a->n, a->disp);
+}
+
+static bool trans_bb_sar(DisasContext *ctx, arg_bb_sar *a)
{
- target_sreg disp = assemble_12(insn) * 4;
- unsigned n = extract32(insn, 1, 1);
- unsigned c = extract32(insn, 15, 1);
- unsigned r = extract32(insn, 16, 5);
- unsigned p = extract32(insn, 21, 5);
- unsigned i = extract32(insn, 26, 1);
TCGv_reg tmp, tcg_r;
DisasCond cond;
nullify_over(ctx);
tmp = tcg_temp_new();
- tcg_r = load_gpr(ctx, r);
- if (i) {
- tcg_gen_shli_reg(tmp, tcg_r, p);
- } else {
- tcg_gen_shl_reg(tmp, tcg_r, cpu_sar);
- }
+ tcg_r = load_gpr(ctx, a->r);
+ tcg_gen_shl_reg(tmp, tcg_r, cpu_sar);
- cond = cond_make_0(c ? TCG_COND_GE : TCG_COND_LT, tmp);
+ cond = cond_make_0(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
tcg_temp_free(tmp);
- do_cbranch(ctx, disp, n, &cond);
- return true;
+ return do_cbranch(ctx, a->disp, a->n, &cond);
}
-static bool trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
+static bool trans_bb_imm(DisasContext *ctx, arg_bb_imm *a)
+{
+ TCGv_reg tmp, tcg_r;
+ DisasCond cond;
+
+ nullify_over(ctx);
+
+ tmp = tcg_temp_new();
+ tcg_r = load_gpr(ctx, a->r);
+ tcg_gen_shli_reg(tmp, tcg_r, a->p);
+
+ cond = cond_make_0(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
+ tcg_temp_free(tmp);
+ return do_cbranch(ctx, a->disp, a->n, &cond);
+}
+
+static bool trans_movb(DisasContext *ctx, arg_movb *a)
{
- target_sreg disp = assemble_12(insn) * 4;
- unsigned n = extract32(insn, 1, 1);
- unsigned c = extract32(insn, 13, 3);
- unsigned t = extract32(insn, 16, 5);
- unsigned r = extract32(insn, 21, 5);
TCGv_reg dest;
DisasCond cond;
nullify_over(ctx);
- dest = dest_gpr(ctx, r);
- if (is_imm) {
- tcg_gen_movi_reg(dest, low_sextract(t, 0, 5));
- } else if (t == 0) {
+ dest = dest_gpr(ctx, a->r2);
+ if (a->r1 == 0) {
tcg_gen_movi_reg(dest, 0);
} else {
- tcg_gen_mov_reg(dest, cpu_gr[t]);
+ tcg_gen_mov_reg(dest, cpu_gr[a->r1]);
}
- cond = do_sed_cond(c, dest);
- do_cbranch(ctx, disp, n, &cond);
- return true;
+ cond = do_sed_cond(a->c, dest);
+ return do_cbranch(ctx, a->disp, a->n, &cond);
+}
+
+static bool trans_movbi(DisasContext *ctx, arg_movbi *a)
+{
+ TCGv_reg dest;
+ DisasCond cond;
+
+ nullify_over(ctx);
+
+ dest = dest_gpr(ctx, a->r);
+ tcg_gen_movi_reg(dest, a->i);
+
+ cond = do_sed_cond(a->c, dest);
+ return do_cbranch(ctx, a->disp, a->n, &cond);
}
static bool trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
@@ -3605,8 +3614,7 @@ static bool trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
case of "be disp(*,r0)" using a direct branch to disp, so that we can
goto_tb to the TB containing the syscall. */
if (b == 0) {
- do_dbranch(ctx, disp, is_l ? 31 : 0, n);
- return true;
+ return do_dbranch(ctx, disp, is_l ? 31 : 0, n);
}
#else
int sp = assemble_sr3(insn);
@@ -3618,7 +3626,7 @@ static bool trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
tmp = do_ibranch_priv(ctx, tmp);
#ifdef CONFIG_USER_ONLY
- do_ibranch(ctx, tmp, is_l ? 31 : 0, n);
+ return do_ibranch(ctx, tmp, is_l ? 31 : 0, n);
#else
TCGv_i64 new_spc = tcg_temp_new_i64();
@@ -3646,7 +3654,6 @@ static bool trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
ctx->base.is_jmp = DISAS_NORETURN;
return nullify_end(ctx);
#endif
- return true;
}
static bool trans_bl(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
@@ -4452,39 +4459,12 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
trans_store_w(ctx, insn);
return;
- case 0x20:
- trans_cmpb(ctx, insn, true, false, false);
- return;
- case 0x21:
- trans_cmpb(ctx, insn, true, true, false);
- return;
- case 0x22:
- trans_cmpb(ctx, insn, false, false, false);
- return;
- case 0x23:
- trans_cmpb(ctx, insn, false, true, false);
- return;
case 0x24:
trans_cmpiclr(ctx, insn);
return;
case 0x25:
trans_subi(ctx, insn);
return;
- case 0x27:
- trans_cmpb(ctx, insn, true, false, true);
- return;
- case 0x28:
- trans_addb(ctx, insn, true, false);
- return;
- case 0x29:
- trans_addb(ctx, insn, true, true);
- return;
- case 0x2A:
- trans_addb(ctx, insn, false, false);
- return;
- case 0x2B:
- trans_addb(ctx, insn, false, true);
- return;
case 0x2C:
case 0x2D:
trans_addi(ctx, insn);
@@ -4492,20 +4472,7 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
case 0x2E:
translate_table(ctx, insn, table_fp_fused);
return;
- case 0x2F:
- trans_cmpb(ctx, insn, false, false, true);
- return;
- case 0x30:
- case 0x31:
- trans_bb(ctx, insn);
- return;
- case 0x32:
- trans_movb(ctx, insn, false);
- return;
- case 0x33:
- trans_movb(ctx, insn, true);
- return;
case 0x34:
translate_table(ctx, insn, table_sh_ex);
return;
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 16a999b05f..e891fbfac5 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -24,6 +24,8 @@
%assemble_sr3 13:1 14:2
%assemble_sr3x 13:1 14:2 !function=expand_sr3x
+%assemble_12 0:s1 2:1 3:10 !function=expand_shl2
+
%sm_imm 16:10 !function=expand_sm_imm
%im5_0 0:s1 1:4
@@ -41,6 +43,9 @@
&rrr_cf t r1 r2 cf
&rrr_cf_sh t r1 r2 cf sh
+&rrb_c_f disp n c f r1 r2
+&rib_c_f disp n c f r i
+
####
# Format definitions
####
@@ -50,6 +55,11 @@
@rrr_cf_sh ...... r2:5 r1:5 cf:4 .... sh:2 . t:5 &rrr_cf_sh
@rrr_cf_sh0 ...... r2:5 r1:5 cf:4 ....... t:5 &rrr_cf_sh sh=0
+@rrb_cf ...... r2:5 r1:5 c:3 ........... n:1 . \
+ &rrb_c_f disp=%assemble_12
+@rib_cf ...... r:5 ..... c:3 ........... n:1 . \
+ &rib_c_f disp=%assemble_12 i=%im5_16
+
####
# System
####
@@ -165,3 +175,23 @@ fmpyadd_f 000110 ..... ..... ..... ..... 0 ..... @mpyadd
fmpyadd_d 000110 ..... ..... ..... ..... 1 ..... @mpyadd
fmpysub_f 100110 ..... ..... ..... ..... 0 ..... @mpyadd
fmpysub_d 100110 ..... ..... ..... ..... 1 ..... @mpyadd
+
+####
+# Conditional Branches
+####
+
+bb_sar 110000 00000 r:5 c:1 10 ........... n:1 . disp=%assemble_12
+bb_imm 110001 p:5 r:5 c:1 10 ........... n:1 . disp=%assemble_12
+
+movb 110010 ..... ..... ... ........... . . @rrb_cf f=0
+movbi 110011 ..... ..... ... ........... . . @rib_cf f=0
+
+cmpb 100000 ..... ..... ... ........... . . @rrb_cf f=0
+cmpb 100010 ..... ..... ... ........... . . @rrb_cf f=1
+cmpbi 100001 ..... ..... ... ........... . . @rib_cf f=0
+cmpbi 100011 ..... ..... ... ........... . . @rib_cf f=1
+
+addb 101000 ..... ..... ... ........... . . @rrb_cf f=0
+addb 101010 ..... ..... ... ........... . . @rrb_cf f=1
+addbi 101001 ..... ..... ... ........... . . @rib_cf f=0
+addbi 101011 ..... ..... ... ........... . . @rib_cf f=1
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 11/19] target/hppa: Convert shift, extract, deposit insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (9 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 10/19] target/hppa: Convert conditional branches Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 12/19] target/hppa: Convert direct and indirect branches Richard Henderson
` (8 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 215 ++++++++++++++-------------------------
target/hppa/insns.decode | 15 +++
2 files changed, 94 insertions(+), 136 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 7bdb900130..83d898212e 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3292,26 +3292,21 @@ static bool trans_movbi(DisasContext *ctx, arg_movbi *a)
return do_cbranch(ctx, a->disp, a->n, &cond);
}
-static bool trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_shrpw_sar(DisasContext *ctx, arg_shrpw_sar *a)
{
- unsigned rt = extract32(insn, 0, 5);
- unsigned c = extract32(insn, 13, 3);
- unsigned r1 = extract32(insn, 16, 5);
- unsigned r2 = extract32(insn, 21, 5);
TCGv_reg dest;
- if (c) {
+ if (a->c) {
nullify_over(ctx);
}
- dest = dest_gpr(ctx, rt);
- if (r1 == 0) {
- tcg_gen_ext32u_reg(dest, load_gpr(ctx, r2));
+ dest = dest_gpr(ctx, a->t);
+ if (a->r1 == 0) {
+ tcg_gen_ext32u_reg(dest, load_gpr(ctx, a->r2));
tcg_gen_shr_reg(dest, dest, cpu_sar);
- } else if (r1 == r2) {
+ } else if (a->r1 == a->r2) {
TCGv_i32 t32 = tcg_temp_new_i32();
- tcg_gen_trunc_reg_i32(t32, load_gpr(ctx, r2));
+ tcg_gen_trunc_reg_i32(t32, load_gpr(ctx, a->r2));
tcg_gen_rotr_i32(t32, t32, cpu_sar);
tcg_gen_extu_i32_reg(dest, t32);
tcg_temp_free_i32(t32);
@@ -3319,7 +3314,7 @@ static bool trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
TCGv_i64 t = tcg_temp_new_i64();
TCGv_i64 s = tcg_temp_new_i64();
- tcg_gen_concat_reg_i64(t, load_gpr(ctx, r2), load_gpr(ctx, r1));
+ tcg_gen_concat_reg_i64(t, load_gpr(ctx, a->r2), load_gpr(ctx, a->r1));
tcg_gen_extu_reg_i64(s, cpu_sar);
tcg_gen_shr_i64(t, t, s);
tcg_gen_trunc_i64_reg(dest, t);
@@ -3327,79 +3322,67 @@ static bool trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
tcg_temp_free_i64(t);
tcg_temp_free_i64(s);
}
- save_gpr(ctx, rt, dest);
+ save_gpr(ctx, a->t, dest);
/* Install the new nullification. */
cond_free(&ctx->null_cond);
- if (c) {
- ctx->null_cond = do_sed_cond(c, dest);
+ if (a->c) {
+ ctx->null_cond = do_sed_cond(a->c, dest);
}
return nullify_end(ctx);
}
-static bool trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_shrpw_imm(DisasContext *ctx, arg_shrpw_imm *a)
{
- unsigned rt = extract32(insn, 0, 5);
- unsigned cpos = extract32(insn, 5, 5);
- unsigned c = extract32(insn, 13, 3);
- unsigned r1 = extract32(insn, 16, 5);
- unsigned r2 = extract32(insn, 21, 5);
- unsigned sa = 31 - cpos;
+ unsigned sa = 31 - a->cpos;
TCGv_reg dest, t2;
- if (c) {
+ if (a->c) {
nullify_over(ctx);
}
- dest = dest_gpr(ctx, rt);
- t2 = load_gpr(ctx, r2);
- if (r1 == r2) {
+ dest = dest_gpr(ctx, a->t);
+ t2 = load_gpr(ctx, a->r2);
+ if (a->r1 == a->r2) {
TCGv_i32 t32 = tcg_temp_new_i32();
tcg_gen_trunc_reg_i32(t32, t2);
tcg_gen_rotri_i32(t32, t32, sa);
tcg_gen_extu_i32_reg(dest, t32);
tcg_temp_free_i32(t32);
- } else if (r1 == 0) {
+ } else if (a->r1 == 0) {
tcg_gen_extract_reg(dest, t2, sa, 32 - sa);
} else {
TCGv_reg t0 = tcg_temp_new();
tcg_gen_extract_reg(t0, t2, sa, 32 - sa);
- tcg_gen_deposit_reg(dest, t0, cpu_gr[r1], 32 - sa, sa);
+ tcg_gen_deposit_reg(dest, t0, cpu_gr[a->r1], 32 - sa, sa);
tcg_temp_free(t0);
}
- save_gpr(ctx, rt, dest);
+ save_gpr(ctx, a->t, dest);
/* Install the new nullification. */
cond_free(&ctx->null_cond);
- if (c) {
- ctx->null_cond = do_sed_cond(c, dest);
+ if (a->c) {
+ ctx->null_cond = do_sed_cond(a->c, dest);
}
return nullify_end(ctx);
}
-static bool trans_extrw_sar(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_extrw_sar(DisasContext *ctx, arg_extrw_sar *a)
{
- unsigned clen = extract32(insn, 0, 5);
- unsigned is_se = extract32(insn, 10, 1);
- unsigned c = extract32(insn, 13, 3);
- unsigned rt = extract32(insn, 16, 5);
- unsigned rr = extract32(insn, 21, 5);
- unsigned len = 32 - clen;
+ unsigned len = 32 - a->clen;
TCGv_reg dest, src, tmp;
- if (c) {
+ if (a->c) {
nullify_over(ctx);
}
- dest = dest_gpr(ctx, rt);
- src = load_gpr(ctx, rr);
+ dest = dest_gpr(ctx, a->t);
+ src = load_gpr(ctx, a->r);
tmp = tcg_temp_new();
/* Recall that SAR is using big-endian bit numbering. */
tcg_gen_xori_reg(tmp, cpu_sar, TARGET_REGISTER_BITS - 1);
- if (is_se) {
+ if (a->se) {
tcg_gen_sar_reg(dest, src, tmp);
tcg_gen_sextract_reg(dest, dest, 0, len);
} else {
@@ -3407,83 +3390,62 @@ static bool trans_extrw_sar(DisasContext *ctx, uint32_t insn,
tcg_gen_extract_reg(dest, dest, 0, len);
}
tcg_temp_free(tmp);
- save_gpr(ctx, rt, dest);
+ save_gpr(ctx, a->t, dest);
/* Install the new nullification. */
cond_free(&ctx->null_cond);
- if (c) {
- ctx->null_cond = do_sed_cond(c, dest);
+ if (a->c) {
+ ctx->null_cond = do_sed_cond(a->c, dest);
}
return nullify_end(ctx);
}
-static bool trans_extrw_imm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_extrw_imm(DisasContext *ctx, arg_extrw_imm *a)
{
- unsigned clen = extract32(insn, 0, 5);
- unsigned pos = extract32(insn, 5, 5);
- unsigned is_se = extract32(insn, 10, 1);
- unsigned c = extract32(insn, 13, 3);
- unsigned rt = extract32(insn, 16, 5);
- unsigned rr = extract32(insn, 21, 5);
- unsigned len = 32 - clen;
- unsigned cpos = 31 - pos;
+ unsigned len = 32 - a->clen;
+ unsigned cpos = 31 - a->pos;
TCGv_reg dest, src;
- if (c) {
+ if (a->c) {
nullify_over(ctx);
}
- dest = dest_gpr(ctx, rt);
- src = load_gpr(ctx, rr);
- if (is_se) {
+ dest = dest_gpr(ctx, a->t);
+ src = load_gpr(ctx, a->r);
+ if (a->se) {
tcg_gen_sextract_reg(dest, src, cpos, len);
} else {
tcg_gen_extract_reg(dest, src, cpos, len);
}
- save_gpr(ctx, rt, dest);
+ save_gpr(ctx, a->t, dest);
/* Install the new nullification. */
cond_free(&ctx->null_cond);
- if (c) {
- ctx->null_cond = do_sed_cond(c, dest);
+ if (a->c) {
+ ctx->null_cond = do_sed_cond(a->c, dest);
}
return nullify_end(ctx);
}
-static const DisasInsn table_sh_ex[] = {
- { 0xd0000000u, 0xfc001fe0u, trans_shrpw_sar },
- { 0xd0000800u, 0xfc001c00u, trans_shrpw_imm },
- { 0xd0001000u, 0xfc001be0u, trans_extrw_sar },
- { 0xd0001800u, 0xfc001800u, trans_extrw_imm },
-};
-
-static bool trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_depwi_imm(DisasContext *ctx, arg_depwi_imm *a)
{
- unsigned clen = extract32(insn, 0, 5);
- unsigned cpos = extract32(insn, 5, 5);
- unsigned nz = extract32(insn, 10, 1);
- unsigned c = extract32(insn, 13, 3);
- target_sreg val = low_sextract(insn, 16, 5);
- unsigned rt = extract32(insn, 21, 5);
- unsigned len = 32 - clen;
+ unsigned len = 32 - a->clen;
target_sreg mask0, mask1;
TCGv_reg dest;
- if (c) {
+ if (a->c) {
nullify_over(ctx);
}
- if (cpos + len > 32) {
- len = 32 - cpos;
+ if (a->cpos + len > 32) {
+ len = 32 - a->cpos;
}
- dest = dest_gpr(ctx, rt);
- mask0 = deposit64(0, cpos, len, val);
- mask1 = deposit64(-1, cpos, len, val);
+ dest = dest_gpr(ctx, a->t);
+ mask0 = deposit64(0, a->cpos, len, a->i);
+ mask1 = deposit64(-1, a->cpos, len, a->i);
- if (nz) {
- TCGv_reg src = load_gpr(ctx, rt);
+ if (a->nz) {
+ TCGv_reg src = load_gpr(ctx, a->t);
if (mask1 != -1) {
tcg_gen_andi_reg(dest, src, mask1);
src = dest;
@@ -3492,75 +3454,58 @@ static bool trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
} else {
tcg_gen_movi_reg(dest, mask0);
}
- save_gpr(ctx, rt, dest);
+ save_gpr(ctx, a->t, dest);
/* Install the new nullification. */
cond_free(&ctx->null_cond);
- if (c) {
- ctx->null_cond = do_sed_cond(c, dest);
+ if (a->c) {
+ ctx->null_cond = do_sed_cond(a->c, dest);
}
return nullify_end(ctx);
}
-static bool trans_depw_imm(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_depw_imm(DisasContext *ctx, arg_depw_imm *a)
{
- unsigned clen = extract32(insn, 0, 5);
- unsigned cpos = extract32(insn, 5, 5);
- unsigned nz = extract32(insn, 10, 1);
- unsigned c = extract32(insn, 13, 3);
- unsigned rr = extract32(insn, 16, 5);
- unsigned rt = extract32(insn, 21, 5);
- unsigned rs = nz ? rt : 0;
- unsigned len = 32 - clen;
+ unsigned rs = a->nz ? a->t : 0;
+ unsigned len = 32 - a->clen;
TCGv_reg dest, val;
- if (c) {
+ if (a->c) {
nullify_over(ctx);
}
- if (cpos + len > 32) {
- len = 32 - cpos;
+ if (a->cpos + len > 32) {
+ len = 32 - a->cpos;
}
- dest = dest_gpr(ctx, rt);
- val = load_gpr(ctx, rr);
+ dest = dest_gpr(ctx, a->t);
+ val = load_gpr(ctx, a->r);
if (rs == 0) {
- tcg_gen_deposit_z_reg(dest, val, cpos, len);
+ tcg_gen_deposit_z_reg(dest, val, a->cpos, len);
} else {
- tcg_gen_deposit_reg(dest, cpu_gr[rs], val, cpos, len);
+ tcg_gen_deposit_reg(dest, cpu_gr[rs], val, a->cpos, len);
}
- save_gpr(ctx, rt, dest);
+ save_gpr(ctx, a->t, dest);
/* Install the new nullification. */
cond_free(&ctx->null_cond);
- if (c) {
- ctx->null_cond = do_sed_cond(c, dest);
+ if (a->c) {
+ ctx->null_cond = do_sed_cond(a->c, dest);
}
return nullify_end(ctx);
}
-static bool trans_depw_sar(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool do_depw_sar(DisasContext *ctx, unsigned rt, unsigned c,
+ unsigned nz, unsigned clen, TCGv_reg val)
{
- unsigned clen = extract32(insn, 0, 5);
- unsigned nz = extract32(insn, 10, 1);
- unsigned i = extract32(insn, 12, 1);
- unsigned c = extract32(insn, 13, 3);
- unsigned rt = extract32(insn, 21, 5);
unsigned rs = nz ? rt : 0;
unsigned len = 32 - clen;
- TCGv_reg val, mask, tmp, shift, dest;
+ TCGv_reg mask, tmp, shift, dest;
unsigned msb = 1U << (len - 1);
if (c) {
nullify_over(ctx);
}
- if (i) {
- val = load_const(ctx, low_sextract(insn, 16, 5));
- } else {
- val = load_gpr(ctx, extract32(insn, 16, 5));
- }
dest = dest_gpr(ctx, rt);
shift = tcg_temp_new();
tmp = tcg_temp_new();
@@ -3591,11 +3536,15 @@ static bool trans_depw_sar(DisasContext *ctx, uint32_t insn,
return nullify_end(ctx);
}
-static const DisasInsn table_depw[] = {
- { 0xd4000000u, 0xfc000be0u, trans_depw_sar },
- { 0xd4000800u, 0xfc001800u, trans_depw_imm },
- { 0xd4001800u, 0xfc001800u, trans_depw_imm_c },
-};
+static bool trans_depw_sar(DisasContext *ctx, arg_depw_sar *a)
+{
+ return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_gpr(ctx, a->r));
+}
+
+static bool trans_depwi_sar(DisasContext *ctx, arg_depwi_sar *a)
+{
+ return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_const(ctx, a->i));
+}
static bool trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
{
@@ -4473,12 +4422,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
translate_table(ctx, insn, table_fp_fused);
return;
- case 0x34:
- translate_table(ctx, insn, table_sh_ex);
- return;
- case 0x35:
- translate_table(ctx, insn, table_depw);
- return;
case 0x38:
trans_be(ctx, insn, false);
return;
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index e891fbfac5..987cb8738b 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -195,3 +195,18 @@ addb 101000 ..... ..... ... ........... . . @rrb_cf f=0
addb 101010 ..... ..... ... ........... . . @rrb_cf f=1
addbi 101001 ..... ..... ... ........... . . @rib_cf f=0
addbi 101011 ..... ..... ... ........... . . @rib_cf f=1
+
+####
+# Shift, Extract, Deposit
+####
+
+shrpw_sar 110100 r2:5 r1:5 c:3 00 0 00000 t:5
+shrpw_imm 110100 r2:5 r1:5 c:3 01 0 cpos:5 t:5
+
+extrw_sar 110100 r:5 t:5 c:3 10 se:1 00000 clen:5
+extrw_imm 110100 r:5 t:5 c:3 11 se:1 pos:5 clen:5
+
+depw_sar 110101 t:5 r:5 c:3 00 nz:1 00000 clen:5
+depw_imm 110101 t:5 r:5 c:3 01 nz:1 cpos:5 clen:5
+depwi_sar 110101 t:5 ..... c:3 10 nz:1 00000 clen:5 i=%im5_16
+depwi_imm 110101 t:5 ..... c:3 11 nz:1 cpos:5 clen:5 i=%im5_16
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 12/19] target/hppa: Convert direct and indirect branches
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (10 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 11/19] target/hppa: Convert shift, extract, deposit insns Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 13/19] target/hppa: Convert arithmetic immediate insns Richard Henderson
` (7 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 131 +++++++++------------------------------
target/hppa/insns.decode | 34 +++++++++-
2 files changed, 63 insertions(+), 102 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 83d898212e..26b5cd205b 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -895,15 +895,6 @@ static target_sreg assemble_16a(uint32_t insn)
return x << 2;
}
-static target_sreg assemble_17(uint32_t insn)
-{
- target_ureg x = -(target_ureg)(insn & 1);
- x = (x << 5) | extract32(insn, 16, 5);
- x = (x << 1) | extract32(insn, 2, 1);
- x = (x << 10) | extract32(insn, 3, 10);
- return x << 2;
-}
-
static target_sreg assemble_21(uint32_t insn)
{
target_ureg x = -(target_ureg)(insn & 1);
@@ -914,15 +905,6 @@ static target_sreg assemble_21(uint32_t insn)
return x << 11;
}
-static target_sreg assemble_22(uint32_t insn)
-{
- target_ureg x = -(target_ureg)(insn & 1);
- x = (x << 10) | extract32(insn, 16, 10);
- x = (x << 1) | extract32(insn, 2, 1);
- x = (x << 10) | extract32(insn, 3, 10);
- return x << 2;
-}
-
/* The parisc documentation describes only the general interpretation of
the conditions, without describing their exact implementation. The
interpretations do not stand up well when considering ADD,C and SUB,B.
@@ -3546,11 +3528,8 @@ static bool trans_depwi_sar(DisasContext *ctx, arg_depwi_sar *a)
return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_const(ctx, a->i));
}
-static bool trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
+static bool trans_be(DisasContext *ctx, arg_be *a)
{
- unsigned n = extract32(insn, 1, 1);
- unsigned b = extract32(insn, 21, 5);
- target_sreg disp = assemble_17(insn);
TCGv_reg tmp;
#ifdef CONFIG_USER_ONLY
@@ -3562,29 +3541,28 @@ static bool trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
/* Since we don't implement spaces, just branch. Do notice the special
case of "be disp(*,r0)" using a direct branch to disp, so that we can
goto_tb to the TB containing the syscall. */
- if (b == 0) {
- return do_dbranch(ctx, disp, is_l ? 31 : 0, n);
+ if (a->b == 0) {
+ return do_dbranch(ctx, a->disp, a->l, a->n);
}
#else
- int sp = assemble_sr3(insn);
nullify_over(ctx);
#endif
tmp = get_temp(ctx);
- tcg_gen_addi_reg(tmp, load_gpr(ctx, b), disp);
+ tcg_gen_addi_reg(tmp, load_gpr(ctx, a->b), a->disp);
tmp = do_ibranch_priv(ctx, tmp);
#ifdef CONFIG_USER_ONLY
- return do_ibranch(ctx, tmp, is_l ? 31 : 0, n);
+ return do_ibranch(ctx, tmp, a->l, a->n);
#else
TCGv_i64 new_spc = tcg_temp_new_i64();
- load_spr(ctx, new_spc, sp);
- if (is_l) {
+ load_spr(ctx, new_spc, a->sp);
+ if (a->l) {
copy_iaoq_entry(cpu_gr[31], ctx->iaoq_n, ctx->iaoq_n_var);
tcg_gen_mov_i64(cpu_sr[0], cpu_iasq_f);
}
- if (n && use_nullify_skip(ctx)) {
+ if (a->n && use_nullify_skip(ctx)) {
tcg_gen_mov_reg(cpu_iaoq_f, tmp);
tcg_gen_addi_reg(cpu_iaoq_b, cpu_iaoq_f, 4);
tcg_gen_mov_i64(cpu_iasq_f, new_spc);
@@ -3596,7 +3574,7 @@ static bool trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
}
tcg_gen_mov_reg(cpu_iaoq_b, tmp);
tcg_gen_mov_i64(cpu_iasq_b, new_spc);
- nullify_set(ctx, n);
+ nullify_set(ctx, a->n);
}
tcg_temp_free_i64(new_spc);
tcg_gen_lookup_and_goto_ptr();
@@ -3605,22 +3583,14 @@ static bool trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
#endif
}
-static bool trans_bl(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_bl(DisasContext *ctx, arg_bl *a)
{
- unsigned n = extract32(insn, 1, 1);
- unsigned link = extract32(insn, 21, 5);
- target_sreg disp = assemble_17(insn);
-
- do_dbranch(ctx, iaoq_dest(ctx, disp), link, n);
- return true;
+ return do_dbranch(ctx, iaoq_dest(ctx, a->disp), a->l, a->n);
}
-static bool trans_b_gate(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_b_gate(DisasContext *ctx, arg_b_gate *a)
{
- unsigned n = extract32(insn, 1, 1);
- unsigned link = extract32(insn, 21, 5);
- target_sreg disp = assemble_17(insn);
- target_ureg dest = iaoq_dest(ctx, disp);
+ target_ureg dest = iaoq_dest(ctx, a->disp);
/* Make sure the caller hasn't done something weird with the queue.
* ??? This is not quite the same as the PSW[B] bit, which would be
@@ -3659,65 +3629,44 @@ static bool trans_b_gate(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
}
#endif
- do_dbranch(ctx, dest, link, n);
- return true;
+ return do_dbranch(ctx, dest, a->l, a->n);
}
-static bool trans_bl_long(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_blr(DisasContext *ctx, arg_blr *a)
{
- unsigned n = extract32(insn, 1, 1);
- target_sreg disp = assemble_22(insn);
-
- do_dbranch(ctx, iaoq_dest(ctx, disp), 2, n);
- return true;
-}
-
-static bool trans_blr(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
-{
- unsigned n = extract32(insn, 1, 1);
- unsigned rx = extract32(insn, 16, 5);
- unsigned link = extract32(insn, 21, 5);
TCGv_reg tmp = get_temp(ctx);
- tcg_gen_shli_reg(tmp, load_gpr(ctx, rx), 3);
+ tcg_gen_shli_reg(tmp, load_gpr(ctx, a->x), 3);
tcg_gen_addi_reg(tmp, tmp, ctx->iaoq_f + 8);
/* The computation here never changes privilege level. */
- do_ibranch(ctx, tmp, link, n);
- return true;
+ return do_ibranch(ctx, tmp, a->l, a->n);
}
-static bool trans_bv(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_bv(DisasContext *ctx, arg_bv *a)
{
- unsigned n = extract32(insn, 1, 1);
- unsigned rx = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
TCGv_reg dest;
- if (rx == 0) {
- dest = load_gpr(ctx, rb);
+ if (a->x == 0) {
+ dest = load_gpr(ctx, a->b);
} else {
dest = get_temp(ctx);
- tcg_gen_shli_reg(dest, load_gpr(ctx, rx), 3);
- tcg_gen_add_reg(dest, dest, load_gpr(ctx, rb));
+ tcg_gen_shli_reg(dest, load_gpr(ctx, a->x), 3);
+ tcg_gen_add_reg(dest, dest, load_gpr(ctx, a->b));
}
dest = do_ibranch_priv(ctx, dest);
- do_ibranch(ctx, dest, 0, n);
- return true;
+ return do_ibranch(ctx, dest, 0, a->n);
}
-static bool trans_bve(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_bve(DisasContext *ctx, arg_bve *a)
{
- unsigned n = extract32(insn, 1, 1);
- unsigned rb = extract32(insn, 21, 5);
- unsigned link = extract32(insn, 13, 1) ? 2 : 0;
TCGv_reg dest;
#ifdef CONFIG_USER_ONLY
- dest = do_ibranch_priv(ctx, load_gpr(ctx, rb));
- do_ibranch(ctx, dest, link, n);
+ dest = do_ibranch_priv(ctx, load_gpr(ctx, a->b));
+ return do_ibranch(ctx, dest, a->l, a->n);
#else
nullify_over(ctx);
- dest = do_ibranch_priv(ctx, load_gpr(ctx, rb));
+ dest = do_ibranch_priv(ctx, load_gpr(ctx, a->b));
copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
if (ctx->iaoq_b == -1) {
@@ -3725,26 +3674,16 @@ static bool trans_bve(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
}
copy_iaoq_entry(cpu_iaoq_b, -1, dest);
tcg_gen_mov_i64(cpu_iasq_b, space_select(ctx, 0, dest));
- if (link) {
- copy_iaoq_entry(cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
+ if (a->l) {
+ copy_iaoq_entry(cpu_gr[a->l], ctx->iaoq_n, ctx->iaoq_n_var);
}
- nullify_set(ctx, n);
+ nullify_set(ctx, a->n);
tcg_gen_lookup_and_goto_ptr();
ctx->base.is_jmp = DISAS_NORETURN;
return nullify_end(ctx);
#endif
- return true;
}
-static const DisasInsn table_branch[] = {
- { 0xe8000000u, 0xfc006000u, trans_bl }, /* B,L and B,L,PUSH */
- { 0xe800a000u, 0xfc00e000u, trans_bl_long },
- { 0xe8004000u, 0xfc00fffdu, trans_blr },
- { 0xe800c000u, 0xfc00fffdu, trans_bv },
- { 0xe800d000u, 0xfc00dffcu, trans_bve },
- { 0xe8002000u, 0xfc00e000u, trans_b_gate },
-};
-
static bool trans_fop_wew_0c(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
@@ -4422,16 +4361,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
translate_table(ctx, insn, table_fp_fused);
return;
- case 0x38:
- trans_be(ctx, insn, false);
- return;
- case 0x39:
- trans_be(ctx, insn, true);
- return;
- case 0x3A:
- translate_table(ctx, insn, table_branch);
- return;
-
case 0x04: /* spopn */
case 0x05: /* diag */
case 0x0F: /* product specific */
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 987cb8738b..09e3f288a7 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -24,7 +24,9 @@
%assemble_sr3 13:1 14:2
%assemble_sr3x 13:1 14:2 !function=expand_sr3x
-%assemble_12 0:s1 2:1 3:10 !function=expand_shl2
+%assemble_12 0:s1 2:1 3:10 !function=expand_shl2
+%assemble_17 0:s1 16:5 2:1 3:10 !function=expand_shl2
+%assemble_22 0:s1 16:10 2:1 3:10 !function=expand_shl2
%sm_imm 16:10 !function=expand_sm_imm
@@ -210,3 +212,33 @@ depw_sar 110101 t:5 r:5 c:3 00 nz:1 00000 clen:5
depw_imm 110101 t:5 r:5 c:3 01 nz:1 cpos:5 clen:5
depwi_sar 110101 t:5 ..... c:3 10 nz:1 00000 clen:5 i=%im5_16
depwi_imm 110101 t:5 ..... c:3 11 nz:1 cpos:5 clen:5 i=%im5_16
+
+####
+# Branch External
+####
+
+&be b l n disp sp
+@be ...... b:5 ..... ... ........... n:1 . \
+ &be disp=%assemble_17 sp=%assemble_sr3
+
+be 111000 ..... ..... ... ........... . . @be l=0
+be 111001 ..... ..... ... ........... . . @be l=31
+
+####
+# Branch
+####
+
+&bl l n disp
+@bl ...... l:5 ..... ... ........... n:1 . &bl disp=%assemble_17
+
+# B,L and B,L,PUSH
+bl 111010 ..... ..... 000 ........... . . @bl
+bl 111010 ..... ..... 100 ........... . . @bl
+# B,L (long displacement)
+bl 111010 ..... ..... 101 ........... n:1 . &bl l=2 \
+ disp=%assemble_22
+b_gate 111010 ..... ..... 001 ........... . . @bl
+blr 111010 l:5 x:5 010 00000000000 n:1 0
+bv 111010 b:5 x:5 110 00000000000 n:1 0
+bve 111010 b:5 00000 110 10000000000 n:1 - l=0
+bve 111010 b:5 00000 111 10000000000 n:1 - l=2
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 13/19] target/hppa: Convert arithmetic immediate insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (11 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 12/19] target/hppa: Convert direct and indirect branches Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 14/19] target/hppa: Convert offset memory insns Richard Henderson
` (6 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 168 +++++++++++++++++----------------------
target/hppa/insns.decode | 21 +++++
2 files changed, 96 insertions(+), 93 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 26b5cd205b..7e4a65e0d5 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -309,6 +309,12 @@ static int expand_shl2(int val)
return val << 2;
}
+/* Used for assemble_21. */
+static int expand_shl11(int val)
+{
+ return val << 11;
+}
+
/* Include the auto-generated decoder. */
#include "decode.inc.c"
@@ -895,16 +901,6 @@ static target_sreg assemble_16a(uint32_t insn)
return x << 2;
}
-static target_sreg assemble_21(uint32_t insn)
-{
- target_ureg x = -(target_ureg)(insn & 1);
- x = (x << 11) | extract32(insn, 1, 11);
- x = (x << 2) | extract32(insn, 14, 2);
- x = (x << 5) | extract32(insn, 16, 5);
- x = (x << 2) | extract32(insn, 12, 2);
- return x << 11;
-}
-
/* The parisc documentation describes only the general interpretation of
the conditions, without describing their exact implementation. The
interpretations do not stand up well when considering ADD,C and SUB,B.
@@ -1219,6 +1215,20 @@ static bool do_add_reg(DisasContext *ctx, arg_rrr_cf_sh *a,
return nullify_end(ctx);
}
+static bool do_add_imm(DisasContext *ctx, arg_rri_cf *a,
+ bool is_tsv, bool is_tc)
+{
+ TCGv_reg tcg_im, tcg_r2;
+
+ if (a->cf) {
+ nullify_over(ctx);
+ }
+ tcg_im = load_const(ctx, a->i);
+ tcg_r2 = load_gpr(ctx, a->r);
+ do_add(ctx, a->t, tcg_im, tcg_r2, 0, 0, is_tsv, is_tc, 0, a->cf);
+ return nullify_end(ctx);
+}
+
static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
TCGv_reg in2, bool is_tsv, bool is_b,
bool is_tc, unsigned cf)
@@ -1299,6 +1309,19 @@ static bool do_sub_reg(DisasContext *ctx, arg_rrr_cf *a,
return nullify_end(ctx);
}
+static bool do_sub_imm(DisasContext *ctx, arg_rri_cf *a, bool is_tsv)
+{
+ TCGv_reg tcg_im, tcg_r2;
+
+ if (a->cf) {
+ nullify_over(ctx);
+ }
+ tcg_im = load_const(ctx, a->i);
+ tcg_r2 = load_gpr(ctx, a->r);
+ do_sub(ctx, a->t, tcg_im, tcg_r2, is_tsv, 0, 0, a->cf);
+ return nullify_end(ctx);
+}
+
static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
TCGv_reg in2, unsigned cf)
{
@@ -2760,62 +2783,47 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
return nullify_end(ctx);
}
-static bool trans_addi(DisasContext *ctx, uint32_t insn)
+static bool trans_addi(DisasContext *ctx, arg_rri_cf *a)
{
- target_sreg im = low_sextract(insn, 0, 11);
- unsigned e1 = extract32(insn, 11, 1);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 16, 5);
- unsigned r2 = extract32(insn, 21, 5);
- unsigned o1 = extract32(insn, 26, 1);
- TCGv_reg tcg_im, tcg_r2;
-
- if (cf) {
- nullify_over(ctx);
- }
-
- tcg_im = load_const(ctx, im);
- tcg_r2 = load_gpr(ctx, r2);
- do_add(ctx, rt, tcg_im, tcg_r2, 0, false, e1, !o1, false, cf);
-
- return nullify_end(ctx);
+ return do_add_imm(ctx, a, false, false);
}
-static bool trans_subi(DisasContext *ctx, uint32_t insn)
+static bool trans_addi_tsv(DisasContext *ctx, arg_rri_cf *a)
{
- target_sreg im = low_sextract(insn, 0, 11);
- unsigned e1 = extract32(insn, 11, 1);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 16, 5);
- unsigned r2 = extract32(insn, 21, 5);
- TCGv_reg tcg_im, tcg_r2;
-
- if (cf) {
- nullify_over(ctx);
- }
-
- tcg_im = load_const(ctx, im);
- tcg_r2 = load_gpr(ctx, r2);
- do_sub(ctx, rt, tcg_im, tcg_r2, e1, false, false, cf);
-
- return nullify_end(ctx);
+ return do_add_imm(ctx, a, true, false);
}
-static bool trans_cmpiclr(DisasContext *ctx, uint32_t insn)
+static bool trans_addi_tc(DisasContext *ctx, arg_rri_cf *a)
+{
+ return do_add_imm(ctx, a, false, true);
+}
+
+static bool trans_addi_tc_tsv(DisasContext *ctx, arg_rri_cf *a)
+{
+ return do_add_imm(ctx, a, true, true);
+}
+
+static bool trans_subi(DisasContext *ctx, arg_rri_cf *a)
+{
+ return do_sub_imm(ctx, a, false);
+}
+
+static bool trans_subi_tsv(DisasContext *ctx, arg_rri_cf *a)
+{
+ return do_sub_imm(ctx, a, true);
+}
+
+static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf *a)
{
- target_sreg im = low_sextract(insn, 0, 11);
- unsigned cf = extract32(insn, 12, 4);
- unsigned rt = extract32(insn, 16, 5);
- unsigned r2 = extract32(insn, 21, 5);
TCGv_reg tcg_im, tcg_r2;
- if (cf) {
+ if (a->cf) {
nullify_over(ctx);
}
- tcg_im = load_const(ctx, im);
- tcg_r2 = load_gpr(ctx, r2);
- do_cmpclr(ctx, rt, tcg_im, tcg_r2, cf);
+ tcg_im = load_const(ctx, a->i);
+ tcg_r2 = load_gpr(ctx, a->r);
+ do_cmpclr(ctx, a->t, tcg_im, tcg_r2, a->cf);
return nullify_end(ctx);
}
@@ -2913,46 +2921,39 @@ static bool trans_sta(DisasContext *ctx, arg_ldst *a)
return true;
}
-static bool trans_ldil(DisasContext *ctx, uint32_t insn)
+static bool trans_ldil(DisasContext *ctx, arg_ldil *a)
{
- unsigned rt = extract32(insn, 21, 5);
- target_sreg i = assemble_21(insn);
- TCGv_reg tcg_rt = dest_gpr(ctx, rt);
+ TCGv_reg tcg_rt = dest_gpr(ctx, a->t);
- tcg_gen_movi_reg(tcg_rt, i);
- save_gpr(ctx, rt, tcg_rt);
+ tcg_gen_movi_reg(tcg_rt, a->i);
+ save_gpr(ctx, a->t, tcg_rt);
cond_free(&ctx->null_cond);
return true;
}
-static bool trans_addil(DisasContext *ctx, uint32_t insn)
+static bool trans_addil(DisasContext *ctx, arg_addil *a)
{
- unsigned rt = extract32(insn, 21, 5);
- target_sreg i = assemble_21(insn);
- TCGv_reg tcg_rt = load_gpr(ctx, rt);
+ TCGv_reg tcg_rt = load_gpr(ctx, a->r);
TCGv_reg tcg_r1 = dest_gpr(ctx, 1);
- tcg_gen_addi_reg(tcg_r1, tcg_rt, i);
+ tcg_gen_addi_reg(tcg_r1, tcg_rt, a->i);
save_gpr(ctx, 1, tcg_r1);
cond_free(&ctx->null_cond);
return true;
}
-static bool trans_ldo(DisasContext *ctx, uint32_t insn)
+static bool trans_ldo(DisasContext *ctx, arg_ldo *a)
{
- unsigned rb = extract32(insn, 21, 5);
- unsigned rt = extract32(insn, 16, 5);
- target_sreg i = assemble_16(insn);
- TCGv_reg tcg_rt = dest_gpr(ctx, rt);
+ TCGv_reg tcg_rt = dest_gpr(ctx, a->t);
/* Special case rb == 0, for the LDI pseudo-op.
The COPY pseudo-op is handled for free within tcg_gen_addi_tl. */
- if (rb == 0) {
- tcg_gen_movi_reg(tcg_rt, i);
+ if (a->b == 0) {
+ tcg_gen_movi_reg(tcg_rt, a->i);
} else {
- tcg_gen_addi_reg(tcg_rt, cpu_gr[rb], i);
+ tcg_gen_addi_reg(tcg_rt, cpu_gr[a->b], a->i);
}
- save_gpr(ctx, rt, tcg_rt);
+ save_gpr(ctx, a->t, tcg_rt);
cond_free(&ctx->null_cond);
return true;
}
@@ -4288,24 +4289,15 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
opc = extract32(insn, 26, 6);
switch (opc) {
- case 0x08:
- trans_ldil(ctx, insn);
- return;
case 0x09:
trans_copr_w(ctx, insn);
return;
- case 0x0A:
- trans_addil(ctx, insn);
- return;
case 0x0B:
trans_copr_dw(ctx, insn);
return;
case 0x0C:
translate_table(ctx, insn, table_float_0c);
return;
- case 0x0D:
- trans_ldo(ctx, insn);
- return;
case 0x0E:
translate_table(ctx, insn, table_float_0e);
return;
@@ -4347,16 +4339,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
trans_store_w(ctx, insn);
return;
- case 0x24:
- trans_cmpiclr(ctx, insn);
- return;
- case 0x25:
- trans_subi(ctx, insn);
- return;
- case 0x2C:
- case 0x2D:
- trans_addi(ctx, insn);
- return;
case 0x2E:
translate_table(ctx, insn, table_fp_fused);
return;
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 09e3f288a7..3e774ae1ad 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -28,6 +28,11 @@
%assemble_17 0:s1 16:5 2:1 3:10 !function=expand_shl2
%assemble_22 0:s1 16:10 2:1 3:10 !function=expand_shl2
+%assemble_21 0:s1 1:11 14:2 16:5 12:2 !function=expand_shl11
+
+%lowsign_11 0:s1 1:10
+%lowsign_14 0:s1 1:13
+
%sm_imm 16:10 !function=expand_sm_imm
%im5_0 0:s1 1:4
@@ -44,6 +49,7 @@
&rr_cf t r cf
&rrr_cf t r1 r2 cf
&rrr_cf_sh t r1 r2 cf sh
+&rri_cf t r i cf
&rrb_c_f disp n c f r1 r2
&rib_c_f disp n c f r i
@@ -56,6 +62,7 @@
@rrr_cf ...... r2:5 r1:5 cf:4 ....... t:5 &rrr_cf
@rrr_cf_sh ...... r2:5 r1:5 cf:4 .... sh:2 . t:5 &rrr_cf_sh
@rrr_cf_sh0 ...... r2:5 r1:5 cf:4 ....... t:5 &rrr_cf_sh sh=0
+@rri_cf ...... r:5 t:5 cf:4 . ........... &rri_cf i=%lowsign_11
@rrb_cf ...... r2:5 r1:5 c:3 ........... n:1 . \
&rrb_c_f disp=%assemble_12
@@ -146,6 +153,20 @@ sub_tsv_tc 000010 ..... ..... .... 110011 0 ..... @rrr_cf
sub_b 000010 ..... ..... .... 010100 0 ..... @rrr_cf
sub_b_tsv 000010 ..... ..... .... 110100 0 ..... @rrr_cf
+ldil 001000 t:5 ..................... i=%assemble_21
+addil 001010 r:5 ..................... i=%assemble_21
+ldo 001101 b:5 t:5 -- .............. i=%lowsign_14
+
+addi 101101 ..... ..... .... 0 ........... @rri_cf
+addi_tsv 101101 ..... ..... .... 1 ........... @rri_cf
+addi_tc 101100 ..... ..... .... 0 ........... @rri_cf
+addi_tc_tsv 101100 ..... ..... .... 1 ........... @rri_cf
+
+subi 100101 ..... ..... .... 0 ........... @rri_cf
+subi_tsv 100101 ..... ..... .... 1 ........... @rri_cf
+
+cmpiclr 100100 ..... ..... .... 0 ........... @rri_cf
+
####
# Index Mem
####
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 14/19] target/hppa: Convert offset memory insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (12 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 13/19] target/hppa: Convert arithmetic immediate insns Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 15/19] target/hppa: Convert fp indexed " Richard Henderson
` (5 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 215 +++++++++------------------------------
target/hppa/insns.decode | 49 +++++++++
2 files changed, 99 insertions(+), 165 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 7e4a65e0d5..4ce65bcc61 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -303,12 +303,29 @@ static int ma_to_m(int val)
return val & 2 ? (val & 1 ? -1 : 1) : 0;
}
-/* Used for branch targets. */
+/* Convert the sign of the displacement to a pre or post-modify. */
+static int pos_to_m(int val)
+{
+ return val ? 1 : -1;
+}
+
+static int neg_to_m(int val)
+{
+ return val ? -1 : 1;
+}
+
+/* Used for branch targets and fp memory ops. */
static int expand_shl2(int val)
{
return val << 2;
}
+/* Used for fp memory ops. */
+static int expand_shl3(int val)
+{
+ return val << 3;
+}
+
/* Used for assemble_21. */
static int expand_shl11(int val)
{
@@ -883,24 +900,6 @@ static inline unsigned assemble_sr3(uint32_t insn)
return s2 * 4 + s0;
}
-static target_sreg assemble_16(uint32_t insn)
-{
- /* Take the name from PA2.0, which produces a 16-bit number
- only with wide mode; otherwise a 14-bit number. Since we don't
- implement wide mode, this is always the 14-bit number. */
- return low_sextract(insn, 0, 14);
-}
-
-static target_sreg assemble_16a(uint32_t insn)
-{
- /* Take the name from PA2.0, which produces a 14-bit shifted number
- only with wide mode; otherwise a 12-bit shifted number. Since we
- don't implement wide mode, this is always the 12-bit number. */
- target_ureg x = -(target_ureg)(insn & 1);
- x = (x << 11) | extract32(insn, 2, 11);
- return x << 2;
-}
-
/* The parisc documentation describes only the general interpretation of
the conditions, without describing their exact implementation. The
interpretations do not stand up well when considering ADD,C and SUB,B.
@@ -1594,7 +1593,7 @@ static bool do_load(DisasContext *ctx, unsigned rt, unsigned rb,
return nullify_end(ctx);
}
-static void do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
+static bool do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_sreg disp,
unsigned sp, int modify)
{
@@ -1611,10 +1610,16 @@ static void do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
gen_helper_loaded_fr0(cpu_env);
}
- nullify_end(ctx);
+ return nullify_end(ctx);
}
-static void do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
+static bool trans_fldw(DisasContext *ctx, arg_ldst *a)
+{
+ return do_floadw(ctx, a->t, a->b, a->x, a->scale ? 2 : 0,
+ a->disp, a->sp, a->m);
+}
+
+static bool do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_sreg disp,
unsigned sp, int modify)
{
@@ -1631,7 +1636,13 @@ static void do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
gen_helper_loaded_fr0(cpu_env);
}
- nullify_end(ctx);
+ return nullify_end(ctx);
+}
+
+static bool trans_fldd(DisasContext *ctx, arg_ldst *a)
+{
+ return do_floadd(ctx, a->t, a->b, a->x, a->scale ? 3 : 0,
+ a->disp, a->sp, a->m);
}
static bool do_store(DisasContext *ctx, unsigned rt, unsigned rb,
@@ -1643,7 +1654,7 @@ static bool do_store(DisasContext *ctx, unsigned rt, unsigned rb,
return nullify_end(ctx);
}
-static void do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
+static bool do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_sreg disp,
unsigned sp, int modify)
{
@@ -1655,10 +1666,16 @@ static void do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
do_store_32(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUL);
tcg_temp_free_i32(tmp);
- nullify_end(ctx);
+ return nullify_end(ctx);
}
-static void do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
+static bool trans_fstw(DisasContext *ctx, arg_ldst *a)
+{
+ return do_fstorew(ctx, a->t, a->b, a->x, a->scale ? 2 : 0,
+ a->disp, a->sp, a->m);
+}
+
+static bool do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_sreg disp,
unsigned sp, int modify)
{
@@ -1670,7 +1687,13 @@ static void do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
do_store_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEQ);
tcg_temp_free_i64(tmp);
- nullify_end(ctx);
+ return nullify_end(ctx);
+}
+
+static bool trans_fstd(DisasContext *ctx, arg_ldst *a)
+{
+ return do_fstored(ctx, a->t, a->b, a->x, a->scale ? 3 : 0,
+ a->disp, a->sp, a->m);
}
static void do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
@@ -2958,107 +2981,6 @@ static bool trans_ldo(DisasContext *ctx, arg_ldo *a)
return true;
}
-static bool trans_load(DisasContext *ctx, uint32_t insn,
- bool is_mod, TCGMemOp mop)
-{
- unsigned rb = extract32(insn, 21, 5);
- unsigned rt = extract32(insn, 16, 5);
- unsigned sp = extract32(insn, 14, 2);
- target_sreg i = assemble_16(insn);
-
- do_load(ctx, rt, rb, 0, 0, i, sp, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
- return true;
-}
-
-static bool trans_load_w(DisasContext *ctx, uint32_t insn)
-{
- unsigned rb = extract32(insn, 21, 5);
- unsigned rt = extract32(insn, 16, 5);
- unsigned sp = extract32(insn, 14, 2);
- target_sreg i = assemble_16a(insn);
- unsigned ext2 = extract32(insn, 1, 2);
-
- switch (ext2) {
- case 0:
- case 1:
- /* FLDW without modification. */
- do_floadw(ctx, ext2 * 32 + rt, rb, 0, 0, i, sp, 0);
- break;
- case 2:
- /* LDW with modification. Note that the sign of I selects
- post-dec vs pre-inc. */
- do_load(ctx, rt, rb, 0, 0, i, sp, (i < 0 ? 1 : -1), MO_TEUL);
- break;
- default:
- return gen_illegal(ctx);
- }
- return true;
-}
-
-static bool trans_fload_mod(DisasContext *ctx, uint32_t insn)
-{
- target_sreg i = assemble_16a(insn);
- unsigned t1 = extract32(insn, 1, 1);
- unsigned a = extract32(insn, 2, 1);
- unsigned sp = extract32(insn, 14, 2);
- unsigned t0 = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
-
- /* FLDW with modification. */
- do_floadw(ctx, t1 * 32 + t0, rb, 0, 0, i, sp, (a ? -1 : 1));
- return true;
-}
-
-static bool trans_store(DisasContext *ctx, uint32_t insn,
- bool is_mod, TCGMemOp mop)
-{
- unsigned rb = extract32(insn, 21, 5);
- unsigned rt = extract32(insn, 16, 5);
- unsigned sp = extract32(insn, 14, 2);
- target_sreg i = assemble_16(insn);
-
- do_store(ctx, rt, rb, i, sp, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
- return true;
-}
-
-static bool trans_store_w(DisasContext *ctx, uint32_t insn)
-{
- unsigned rb = extract32(insn, 21, 5);
- unsigned rt = extract32(insn, 16, 5);
- unsigned sp = extract32(insn, 14, 2);
- target_sreg i = assemble_16a(insn);
- unsigned ext2 = extract32(insn, 1, 2);
-
- switch (ext2) {
- case 0:
- case 1:
- /* FSTW without modification. */
- do_fstorew(ctx, ext2 * 32 + rt, rb, 0, 0, i, sp, 0);
- break;
- case 2:
- /* STW with modification. */
- do_store(ctx, rt, rb, i, sp, (i < 0 ? 1 : -1), MO_TEUL);
- break;
- default:
- return gen_illegal(ctx);
- }
- return true;
-}
-
-static bool trans_fstore_mod(DisasContext *ctx, uint32_t insn)
-{
- target_sreg i = assemble_16a(insn);
- unsigned t1 = extract32(insn, 1, 1);
- unsigned a = extract32(insn, 2, 1);
- unsigned sp = extract32(insn, 14, 2);
- unsigned t0 = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
-
- /* FSTW with modification. */
- do_fstorew(ctx, t1 * 32 + t0, rb, 0, 0, i, sp, (a ? -1 : 1));
- return true;
-}
-
static bool trans_copr_w(DisasContext *ctx, uint32_t insn)
{
unsigned t0 = extract32(insn, 0, 5);
@@ -4302,43 +4224,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
translate_table(ctx, insn, table_float_0e);
return;
- case 0x10:
- trans_load(ctx, insn, false, MO_UB);
- return;
- case 0x11:
- trans_load(ctx, insn, false, MO_TEUW);
- return;
- case 0x12:
- trans_load(ctx, insn, false, MO_TEUL);
- return;
- case 0x13:
- trans_load(ctx, insn, true, MO_TEUL);
- return;
- case 0x16:
- trans_fload_mod(ctx, insn);
- return;
- case 0x17:
- trans_load_w(ctx, insn);
- return;
- case 0x18:
- trans_store(ctx, insn, false, MO_UB);
- return;
- case 0x19:
- trans_store(ctx, insn, false, MO_TEUW);
- return;
- case 0x1A:
- trans_store(ctx, insn, false, MO_TEUL);
- return;
- case 0x1B:
- trans_store(ctx, insn, true, MO_TEUL);
- return;
- case 0x1E:
- trans_fstore_mod(ctx, insn);
- return;
- case 0x1F:
- trans_store_w(ctx, insn);
- return;
-
case 0x2E:
translate_table(ctx, insn, table_fp_fused);
return;
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 3e774ae1ad..40b23823d0 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -24,7 +24,9 @@
%assemble_sr3 13:1 14:2
%assemble_sr3x 13:1 14:2 !function=expand_sr3x
+%assemble_11a 0:s1 4:10 !function=expand_shl3
%assemble_12 0:s1 2:1 3:10 !function=expand_shl2
+%assemble_12a 0:s1 3:11 !function=expand_shl2
%assemble_17 0:s1 16:5 2:1 3:10 !function=expand_shl2
%assemble_22 0:s1 16:10 2:1 3:10 !function=expand_shl2
@@ -35,9 +37,15 @@
%sm_imm 16:10 !function=expand_sm_imm
+%rm64 1:1 16:5
+
%im5_0 0:s1 1:4
%im5_16 16:s1 17:4
%ma_to_m 5:1 13:1 !function=ma_to_m
+%ma2_to_m 2:2 !function=ma_to_m
+%pos_to_m 0:1 !function=pos_to_m
+%neg_to_m 0:1 !function=neg_to_m
+%a_to_m 2:1 !function=neg_to_m
####
# Argument set definitions
@@ -187,6 +195,47 @@ lda 000011 ..... ..... .. . 0 -- 0110 ...... @ldstx size=2
sta 000011 ..... ..... .. . 1 -- 1110 ...... @stim5 size=2
stby 000011 b:5 r:5 sp:2 a:1 1 -- 1100 m:1 ..... disp=%im5_0
+####
+# Offset Mem
+####
+
+@ldstim14 ...... b:5 t:5 sp:2 .............. \
+ &ldst disp=%lowsign_14 x=0 scale=0 m=0
+@ldstim14m ...... b:5 t:5 sp:2 .............. \
+ &ldst disp=%lowsign_14 x=0 scale=0 m=%neg_to_m
+@ldstim12m ...... b:5 t:5 sp:2 .............. \
+ &ldst disp=%assemble_12a x=0 scale=0 m=%pos_to_m
+
+# LDB, LDH, LDW, LDWM
+ld 010000 ..... ..... .. .............. @ldstim14 size=0
+ld 010001 ..... ..... .. .............. @ldstim14 size=1
+ld 010010 ..... ..... .. .............. @ldstim14 size=2
+ld 010011 ..... ..... .. .............. @ldstim14m size=2
+ld 010111 ..... ..... .. ...........10. @ldstim12m size=2
+
+# STB, STH, STW, STWM
+st 011000 ..... ..... .. .............. @ldstim14 size=0
+st 011001 ..... ..... .. .............. @ldstim14 size=1
+st 011010 ..... ..... .. .............. @ldstim14 size=2
+st 011011 ..... ..... .. .............. @ldstim14m size=2
+st 011111 ..... ..... .. ...........10. @ldstim12m size=2
+
+fldw 010110 b:5 ..... sp:2 .............. \
+ &ldst disp=%assemble_12a t=%rm64 m=%a_to_m x=0 scale=0 size=2
+fldw 010111 b:5 ..... sp:2 ...........0.. \
+ &ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
+
+fstw 011110 b:5 ..... sp:2 .............. \
+ &ldst disp=%assemble_12a t=%rm64 m=%a_to_m x=0 scale=0 size=2
+fstw 011111 b:5 ..... sp:2 ...........0.. \
+ &ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
+
+fldd 010100 b:5 t:5 sp:2 .......... .. 1 . \
+ &ldst disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3
+
+fstd 011100 b:5 t:5 sp:2 .......... .. 1 . \
+ &ldst disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3
+
####
# Floating-point Multiply Add
####
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 15/19] target/hppa: Convert fp indexed memory insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (13 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 14/19] target/hppa: Convert offset memory insns Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 16/19] target/hppa: Convert halt/reset insns Richard Henderson
` (4 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 93 ----------------------------------------
target/hppa/insns.decode | 21 +++++++++
2 files changed, 21 insertions(+), 93 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 4ce65bcc61..4ecd522e51 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -855,15 +855,6 @@ static void gen_goto_tb(DisasContext *ctx, int which,
}
}
-/* PA has a habit of taking the LSB of a field and using that as the sign,
- with the rest of the field becoming the least significant bits. */
-static target_sreg low_sextract(uint32_t val, int pos, int len)
-{
- target_ureg x = -(target_ureg)extract32(val, pos, 1);
- x = (x << (len - 1)) | extract32(val, pos + 1, len - 1);
- return x;
-}
-
static unsigned assemble_rt64(uint32_t insn)
{
unsigned r1 = extract32(insn, 6, 1);
@@ -2981,84 +2972,6 @@ static bool trans_ldo(DisasContext *ctx, arg_ldo *a)
return true;
}
-static bool trans_copr_w(DisasContext *ctx, uint32_t insn)
-{
- unsigned t0 = extract32(insn, 0, 5);
- unsigned m = extract32(insn, 5, 1);
- unsigned t1 = extract32(insn, 6, 1);
- unsigned ext3 = extract32(insn, 7, 3);
- /* unsigned cc = extract32(insn, 10, 2); */
- unsigned i = extract32(insn, 12, 1);
- unsigned ua = extract32(insn, 13, 1);
- unsigned sp = extract32(insn, 14, 2);
- unsigned rx = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
- unsigned rt = t1 * 32 + t0;
- int modify = (m ? (ua ? -1 : 1) : 0);
- int disp, scale;
-
- if (i == 0) {
- scale = (ua ? 2 : 0);
- disp = 0;
- modify = m;
- } else {
- disp = low_sextract(rx, 0, 5);
- scale = 0;
- rx = 0;
- modify = (m ? (ua ? -1 : 1) : 0);
- }
-
- switch (ext3) {
- case 0: /* FLDW */
- do_floadw(ctx, rt, rb, rx, scale, disp, sp, modify);
- break;
- case 4: /* FSTW */
- do_fstorew(ctx, rt, rb, rx, scale, disp, sp, modify);
- break;
- default:
- return gen_illegal(ctx);
- }
- return true;
-}
-
-static bool trans_copr_dw(DisasContext *ctx, uint32_t insn)
-{
- unsigned rt = extract32(insn, 0, 5);
- unsigned m = extract32(insn, 5, 1);
- unsigned ext4 = extract32(insn, 6, 4);
- /* unsigned cc = extract32(insn, 10, 2); */
- unsigned i = extract32(insn, 12, 1);
- unsigned ua = extract32(insn, 13, 1);
- unsigned sp = extract32(insn, 14, 2);
- unsigned rx = extract32(insn, 16, 5);
- unsigned rb = extract32(insn, 21, 5);
- int modify = (m ? (ua ? -1 : 1) : 0);
- int disp, scale;
-
- if (i == 0) {
- scale = (ua ? 3 : 0);
- disp = 0;
- modify = m;
- } else {
- disp = low_sextract(rx, 0, 5);
- scale = 0;
- rx = 0;
- modify = (m ? (ua ? -1 : 1) : 0);
- }
-
- switch (ext4) {
- case 0: /* FLDD */
- do_floadd(ctx, rt, rb, rx, scale, disp, sp, modify);
- break;
- case 8: /* FSTD */
- do_fstored(ctx, rt, rb, rx, scale, disp, sp, modify);
- break;
- default:
- return gen_illegal(ctx);
- }
- return true;
-}
-
static bool do_cmpb(DisasContext *ctx, unsigned r, TCGv_reg in1,
unsigned c, unsigned f, unsigned n, int disp)
{
@@ -4211,12 +4124,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
opc = extract32(insn, 26, 6);
switch (opc) {
- case 0x09:
- trans_copr_w(ctx, insn);
- return;
- case 0x0B:
- trans_copr_dw(ctx, insn);
- return;
case 0x0C:
translate_table(ctx, insn, table_float_0c);
return;
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 40b23823d0..25ac09d9d6 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -38,6 +38,7 @@
%sm_imm 16:10 !function=expand_sm_imm
%rm64 1:1 16:5
+%rt64 6:1 0:5
%im5_0 0:s1 1:4
%im5_16 16:s1 17:4
@@ -195,6 +196,26 @@ lda 000011 ..... ..... .. . 0 -- 0110 ...... @ldstx size=2
sta 000011 ..... ..... .. . 1 -- 1110 ...... @stim5 size=2
stby 000011 b:5 r:5 sp:2 a:1 1 -- 1100 m:1 ..... disp=%im5_0
+@fldstwx ...... b:5 x:5 sp:2 scale:1 ....... m:1 ..... \
+ &ldst t=%rt64 disp=0 size=2
+@fldstwi ...... b:5 ..... sp:2 . ....... . ..... \
+ &ldst t=%rt64 disp=%im5_16 m=%ma_to_m x=0 scale=0 size=2
+
+fldw 001001 ..... ..... .. . 0 -- 000 . . ..... @fldstwx
+fldw 001001 ..... ..... .. . 1 -- 000 . . ..... @fldstwi
+fstw 001001 ..... ..... .. . 0 -- 100 . . ..... @fldstwx
+fstw 001001 ..... ..... .. . 1 -- 100 . . ..... @fldstwi
+
+@fldstdx ...... b:5 x:5 sp:2 scale:1 ....... m:1 t:5 \
+ &ldst disp=0 size=3
+@fldstdi ...... b:5 ..... sp:2 . ....... . t:5 \
+ &ldst disp=%im5_16 m=%ma_to_m x=0 scale=0 size=3
+
+fldd 001011 ..... ..... .. . 0 -- 000 0 . ..... @fldstdx
+fldd 001011 ..... ..... .. . 1 -- 000 0 . ..... @fldstdi
+fstd 001011 ..... ..... .. . 0 -- 100 0 . ..... @fldstdx
+fstd 001011 ..... ..... .. . 1 -- 100 0 . ..... @fldstdi
+
####
# Offset Mem
####
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 16/19] target/hppa: Convert halt/reset insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (14 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 15/19] target/hppa: Convert fp indexed " Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 17/19] target/hppa: Convert fp fused multiply-add insns Richard Henderson
` (3 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 49 ++++++++++++----------------------------
target/hppa/insns.decode | 5 ++++
2 files changed, 20 insertions(+), 34 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 4ecd522e51..c73a7ab3db 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2376,20 +2376,27 @@ static bool trans_rfi_r(DisasContext *ctx, arg_rfi_r *a)
return do_rfi(ctx, true);
}
-#ifndef CONFIG_USER_ONLY
-static bool gen_hlt(DisasContext *ctx, int reset)
+static bool trans_halt(DisasContext *ctx, arg_halt *a)
{
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
+#ifndef CONFIG_USER_ONLY
nullify_over(ctx);
- if (reset) {
- gen_helper_reset(cpu_env);
- } else {
- gen_helper_halt(cpu_env);
- }
+ gen_helper_halt(cpu_env);
ctx->base.is_jmp = DISAS_NORETURN;
return nullify_end(ctx);
+#endif
+}
+
+static bool trans_reset(DisasContext *ctx, arg_reset *a)
+{
+ CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
+#ifndef CONFIG_USER_ONLY
+ nullify_over(ctx);
+ gen_helper_reset(cpu_env);
+ ctx->base.is_jmp = DISAS_NORETURN;
+ return nullify_end(ctx);
+#endif
}
-#endif /* !CONFIG_USER_ONLY */
static bool trans_nop_addrx(DisasContext *ctx, arg_ldst *a)
{
@@ -4134,32 +4141,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
case 0x2E:
translate_table(ctx, insn, table_fp_fused);
return;
-
- case 0x04: /* spopn */
- case 0x05: /* diag */
- case 0x0F: /* product specific */
- break;
-
- case 0x07: /* unassigned */
- case 0x15: /* unassigned */
- case 0x1D: /* unassigned */
- case 0x37: /* unassigned */
- break;
- case 0x3F:
-#ifndef CONFIG_USER_ONLY
- /* Unassigned, but use as system-halt. */
- if (insn == 0xfffdead0) {
- gen_hlt(ctx, 0); /* halt system */
- return;
- }
- if (insn == 0xfffdead1) {
- gen_hlt(ctx, 1); /* reset system */
- return;
- }
-#endif
- break;
- default:
- break;
}
gen_illegal(ctx);
}
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 25ac09d9d6..f564e54f1d 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -103,6 +103,11 @@ ssm 000000 .......... 000 01101011 t:5 i=%sm_imm
rfi 000000 ----- ----- --- 01100000 00000
rfi_r 000000 ----- ----- --- 01100101 00000
+# These are artificial instructions used by QEMU firmware.
+# They are allocated from the unassigned instruction space.
+halt 1111 1111 1111 1101 1110 1010 1101 0000
+reset 1111 1111 1111 1101 1110 1010 1101 0001
+
####
# Memory Management
####
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 17/19] target/hppa: Convert fp fused multiply-add insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (15 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 16/19] target/hppa: Convert halt/reset insns Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 18/19] target/hppa: Convert fp operate insns Richard Henderson
` (2 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 77 +++++++++++++---------------------------
target/hppa/insns.decode | 12 +++++++
2 files changed, 36 insertions(+), 53 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index c73a7ab3db..3889851109 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -876,14 +876,6 @@ static unsigned assemble_rb64(uint32_t insn)
return r1 * 32 + r0;
}
-static unsigned assemble_rc64(uint32_t insn)
-{
- unsigned r2 = extract32(insn, 8, 1);
- unsigned r1 = extract32(insn, 13, 3);
- unsigned r0 = extract32(insn, 9, 2);
- return r2 * 32 + r1 * 4 + r0;
-}
-
static inline unsigned assemble_sr3(uint32_t insn)
{
unsigned s2 = extract32(insn, 13, 1);
@@ -4041,67 +4033,50 @@ static bool trans_fmpysub_d(DisasContext *ctx, arg_mpyadd *a)
return do_fmpyadd_d(ctx, a, true);
}
-static bool trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fmpyfadd_f(DisasContext *ctx, arg_fmpyfadd_f *a)
{
- unsigned rt = assemble_rt64(insn);
- unsigned neg = extract32(insn, 5, 1);
- unsigned rm1 = assemble_ra64(insn);
- unsigned rm2 = assemble_rb64(insn);
- unsigned ra3 = assemble_rc64(insn);
- TCGv_i32 a, b, c;
+ TCGv_i32 x, y, z;
nullify_over(ctx);
- a = load_frw0_i32(rm1);
- b = load_frw0_i32(rm2);
- c = load_frw0_i32(ra3);
+ x = load_frw0_i32(a->rm1);
+ y = load_frw0_i32(a->rm2);
+ z = load_frw0_i32(a->ra3);
- if (neg) {
- gen_helper_fmpynfadd_s(a, cpu_env, a, b, c);
+ if (a->neg) {
+ gen_helper_fmpynfadd_s(x, cpu_env, x, y, z);
} else {
- gen_helper_fmpyfadd_s(a, cpu_env, a, b, c);
+ gen_helper_fmpyfadd_s(x, cpu_env, x, y, z);
}
- tcg_temp_free_i32(b);
- tcg_temp_free_i32(c);
- save_frw_i32(rt, a);
- tcg_temp_free_i32(a);
+ tcg_temp_free_i32(y);
+ tcg_temp_free_i32(z);
+ save_frw_i32(a->t, x);
+ tcg_temp_free_i32(x);
return nullify_end(ctx);
}
-static bool trans_fmpyfadd_d(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fmpyfadd_d(DisasContext *ctx, arg_fmpyfadd_d *a)
{
- unsigned rt = extract32(insn, 0, 5);
- unsigned neg = extract32(insn, 5, 1);
- unsigned rm1 = extract32(insn, 21, 5);
- unsigned rm2 = extract32(insn, 16, 5);
- unsigned ra3 = assemble_rc64(insn);
- TCGv_i64 a, b, c;
+ TCGv_i64 x, y, z;
nullify_over(ctx);
- a = load_frd0(rm1);
- b = load_frd0(rm2);
- c = load_frd0(ra3);
+ x = load_frd0(a->rm1);
+ y = load_frd0(a->rm2);
+ z = load_frd0(a->ra3);
- if (neg) {
- gen_helper_fmpynfadd_d(a, cpu_env, a, b, c);
+ if (a->neg) {
+ gen_helper_fmpynfadd_d(x, cpu_env, x, y, z);
} else {
- gen_helper_fmpyfadd_d(a, cpu_env, a, b, c);
+ gen_helper_fmpyfadd_d(x, cpu_env, x, y, z);
}
- tcg_temp_free_i64(b);
- tcg_temp_free_i64(c);
- save_frd(rt, a);
- tcg_temp_free_i64(a);
+ tcg_temp_free_i64(y);
+ tcg_temp_free_i64(z);
+ save_frd(a->t, x);
+ tcg_temp_free_i64(x);
return nullify_end(ctx);
}
-static const DisasInsn table_fp_fused[] = {
- { 0xb8000000u, 0xfc000800u, trans_fmpyfadd_s },
- { 0xb8000800u, 0xfc0019c0u, trans_fmpyfadd_d }
-};
-
static void translate_table_int(DisasContext *ctx, uint32_t insn,
const DisasInsn table[], size_t n)
{
@@ -4137,10 +4112,6 @@ static void translate_one(DisasContext *ctx, uint32_t insn)
case 0x0E:
translate_table(ctx, insn, table_float_0e);
return;
-
- case 0x2E:
- translate_table(ctx, insn, table_fp_fused);
- return;
}
gen_illegal(ctx);
}
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index f564e54f1d..1c8102f76e 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -39,6 +39,10 @@
%rm64 1:1 16:5
%rt64 6:1 0:5
+%ra64 7:1 21:5
+%rb64 12:1 16:5
+%rc64 8:1 13:3 9:2
+%rc32 13:3 9:2
%im5_0 0:s1 1:4
%im5_16 16:s1 17:4
@@ -338,3 +342,11 @@ blr 111010 l:5 x:5 010 00000000000 n:1 0
bv 111010 b:5 x:5 110 00000000000 n:1 0
bve 111010 b:5 00000 110 10000000000 n:1 - l=0
bve 111010 b:5 00000 111 10000000000 n:1 - l=2
+
+####
+# FP Fused Multiple-Add
+####
+
+fmpyfadd_f 101110 ..... ..... ... . 0 ... . . neg:1 ..... \
+ rm1=%ra64 rm2=%rb64 ra3=%rc64 t=%rt64
+fmpyfadd_d 101110 rm1:5 rm2:5 ... 0 1 ..0 0 0 neg:1 t:5 ra3=%rc32
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 18/19] target/hppa: Convert fp operate insns
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (16 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 17/19] target/hppa: Convert fp fused multiply-add insns Richard Henderson
@ 2019-02-07 11:53 ` Richard Henderson
2019-02-07 11:54 ` [Qemu-devel] [PATCH 19/19] target/hppa: Merge translate_one into hppa_tr_translate_insn Richard Henderson
2019-02-11 8:21 ` [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Sven Schnelle
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:53 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 791 ++++++++++++++++-----------------------
target/hppa/insns.decode | 175 +++++++++
2 files changed, 507 insertions(+), 459 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 3889851109..ecec5c42d1 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -348,21 +348,6 @@ static int expand_shl11(int val)
to recognize unmasked interrupts. */
#define DISAS_IAQ_N_STALE_EXIT DISAS_TARGET_2
-typedef struct DisasInsn {
- uint32_t insn, mask;
- bool (*trans)(DisasContext *ctx, uint32_t insn,
- const struct DisasInsn *f);
- union {
- void (*ttt)(TCGv_reg, TCGv_reg, TCGv_reg);
- void (*weww)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32);
- void (*dedd)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64);
- void (*wew)(TCGv_i32, TCGv_env, TCGv_i32);
- void (*ded)(TCGv_i64, TCGv_env, TCGv_i64);
- void (*wed)(TCGv_i32, TCGv_env, TCGv_i64);
- void (*dew)(TCGv_i64, TCGv_env, TCGv_i32);
- } f;
-} DisasInsn;
-
/* global register indexes */
static TCGv_reg cpu_gr[32];
static TCGv_i64 cpu_sr[4];
@@ -855,34 +840,6 @@ static void gen_goto_tb(DisasContext *ctx, int which,
}
}
-static unsigned assemble_rt64(uint32_t insn)
-{
- unsigned r1 = extract32(insn, 6, 1);
- unsigned r0 = extract32(insn, 0, 5);
- return r1 * 32 + r0;
-}
-
-static unsigned assemble_ra64(uint32_t insn)
-{
- unsigned r1 = extract32(insn, 7, 1);
- unsigned r0 = extract32(insn, 21, 5);
- return r1 * 32 + r0;
-}
-
-static unsigned assemble_rb64(uint32_t insn)
-{
- unsigned r1 = extract32(insn, 12, 1);
- unsigned r0 = extract32(insn, 16, 5);
- return r1 * 32 + r0;
-}
-
-static inline unsigned assemble_sr3(uint32_t insn)
-{
- unsigned s2 = extract32(insn, 13, 1);
- unsigned s0 = extract32(insn, 14, 2);
- return s2 * 4 + s0;
-}
-
/* The parisc documentation describes only the general interpretation of
the conditions, without describing their exact implementation. The
interpretations do not stand up well when considering ADD,C and SUB,B.
@@ -1679,7 +1636,7 @@ static bool trans_fstd(DisasContext *ctx, arg_ldst *a)
a->disp, a->sp, a->m);
}
-static void do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
+static bool do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
{
TCGv_i32 tmp;
@@ -1691,10 +1648,10 @@ static void do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
save_frw_i32(rt, tmp);
tcg_temp_free_i32(tmp);
- nullify_end(ctx);
+ return nullify_end(ctx);
}
-static void do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
+static bool do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
{
TCGv_i32 dst;
@@ -1709,10 +1666,10 @@ static void do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
tcg_temp_free_i64(src);
save_frw_i32(rt, dst);
tcg_temp_free_i32(dst);
- nullify_end(ctx);
+ return nullify_end(ctx);
}
-static void do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
+static bool do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
{
TCGv_i64 tmp;
@@ -1724,10 +1681,10 @@ static void do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
save_frd(rt, tmp);
tcg_temp_free_i64(tmp);
- nullify_end(ctx);
+ return nullify_end(ctx);
}
-static void do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
+static bool do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
{
TCGv_i32 src;
@@ -1742,10 +1699,10 @@ static void do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
tcg_temp_free_i32(src);
save_frd(rt, dst);
tcg_temp_free_i64(dst);
- nullify_end(ctx);
+ return nullify_end(ctx);
}
-static void do_fop_weww(DisasContext *ctx, unsigned rt,
+static bool do_fop_weww(DisasContext *ctx, unsigned rt,
unsigned ra, unsigned rb,
void (*func)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
{
@@ -1760,10 +1717,10 @@ static void do_fop_weww(DisasContext *ctx, unsigned rt,
tcg_temp_free_i32(b);
save_frw_i32(rt, a);
tcg_temp_free_i32(a);
- nullify_end(ctx);
+ return nullify_end(ctx);
}
-static void do_fop_dedd(DisasContext *ctx, unsigned rt,
+static bool do_fop_dedd(DisasContext *ctx, unsigned rt,
unsigned ra, unsigned rb,
void (*func)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64))
{
@@ -1778,7 +1735,7 @@ static void do_fop_dedd(DisasContext *ctx, unsigned rt,
tcg_temp_free_i64(b);
save_frd(rt, a);
tcg_temp_free_i64(a);
- nullify_end(ctx);
+ return nullify_end(ctx);
}
/* Emit an unconditional branch to a direct target, which may or may not
@@ -3519,150 +3476,258 @@ static bool trans_bve(DisasContext *ctx, arg_bve *a)
#endif
}
-static bool trans_fop_wew_0c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned rt = extract32(insn, 0, 5);
- unsigned ra = extract32(insn, 21, 5);
- do_fop_wew(ctx, rt, ra, di->f.wew);
- return true;
-}
+/*
+ * Float class 0
+ */
-static bool trans_fop_wew_0e(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned rt = assemble_rt64(insn);
- unsigned ra = assemble_ra64(insn);
- do_fop_wew(ctx, rt, ra, di->f.wew);
- return true;
-}
-
-static bool trans_fop_ded(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned rt = extract32(insn, 0, 5);
- unsigned ra = extract32(insn, 21, 5);
- do_fop_ded(ctx, rt, ra, di->f.ded);
- return true;
-}
-
-static bool trans_fop_wed_0c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned rt = extract32(insn, 0, 5);
- unsigned ra = extract32(insn, 21, 5);
- do_fop_wed(ctx, rt, ra, di->f.wed);
- return true;
-}
-
-static bool trans_fop_wed_0e(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned rt = assemble_rt64(insn);
- unsigned ra = extract32(insn, 21, 5);
- do_fop_wed(ctx, rt, ra, di->f.wed);
- return true;
-}
-
-static bool trans_fop_dew_0c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned rt = extract32(insn, 0, 5);
- unsigned ra = extract32(insn, 21, 5);
- do_fop_dew(ctx, rt, ra, di->f.dew);
- return true;
-}
-
-static bool trans_fop_dew_0e(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned rt = extract32(insn, 0, 5);
- unsigned ra = assemble_ra64(insn);
- do_fop_dew(ctx, rt, ra, di->f.dew);
- return true;
-}
-
-static bool trans_fop_weww_0c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned rt = extract32(insn, 0, 5);
- unsigned rb = extract32(insn, 16, 5);
- unsigned ra = extract32(insn, 21, 5);
- do_fop_weww(ctx, rt, ra, rb, di->f.weww);
- return true;
-}
-
-static bool trans_fop_weww_0e(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned rt = assemble_rt64(insn);
- unsigned rb = assemble_rb64(insn);
- unsigned ra = assemble_ra64(insn);
- do_fop_weww(ctx, rt, ra, rb, di->f.weww);
- return true;
-}
-
-static bool trans_fop_dedd(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned rt = extract32(insn, 0, 5);
- unsigned rb = extract32(insn, 16, 5);
- unsigned ra = extract32(insn, 21, 5);
- do_fop_dedd(ctx, rt, ra, rb, di->f.dedd);
- return true;
-}
-
-static void gen_fcpy_s(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
+static void gen_fcpy_f(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
{
tcg_gen_mov_i32(dst, src);
}
+static bool trans_fcpy_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_fcpy_f);
+}
+
static void gen_fcpy_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
{
tcg_gen_mov_i64(dst, src);
}
-static void gen_fabs_s(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
+static bool trans_fcpy_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_fcpy_d);
+}
+
+static void gen_fabs_f(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
{
tcg_gen_andi_i32(dst, src, INT32_MAX);
}
+static bool trans_fabs_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_fabs_f);
+}
+
static void gen_fabs_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
{
tcg_gen_andi_i64(dst, src, INT64_MAX);
}
-static void gen_fneg_s(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
+static bool trans_fabs_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_fabs_d);
+}
+
+static bool trans_fsqrt_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_helper_fsqrt_s);
+}
+
+static bool trans_fsqrt_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_helper_fsqrt_d);
+}
+
+static bool trans_frnd_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_helper_frnd_s);
+}
+
+static bool trans_frnd_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_helper_frnd_d);
+}
+
+static void gen_fneg_f(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
{
tcg_gen_xori_i32(dst, src, INT32_MIN);
}
+static bool trans_fneg_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_fneg_f);
+}
+
static void gen_fneg_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
{
tcg_gen_xori_i64(dst, src, INT64_MIN);
}
-static void gen_fnegabs_s(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
+static bool trans_fneg_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_fneg_d);
+}
+
+static void gen_fnegabs_f(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
{
tcg_gen_ori_i32(dst, src, INT32_MIN);
}
+static bool trans_fnegabs_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_fnegabs_f);
+}
+
static void gen_fnegabs_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
{
tcg_gen_ori_i64(dst, src, INT64_MIN);
}
-static void do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
- unsigned y, unsigned c)
+static bool trans_fnegabs_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_fnegabs_d);
+}
+
+/*
+ * Float class 1
+ */
+
+static bool trans_fcnv_d_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_d_s);
+}
+
+static bool trans_fcnv_f_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_s_d);
+}
+
+static bool trans_fcnv_w_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_w_s);
+}
+
+static bool trans_fcnv_q_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_dw_s);
+}
+
+static bool trans_fcnv_w_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_w_d);
+}
+
+static bool trans_fcnv_q_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_dw_d);
+}
+
+static bool trans_fcnv_f_w(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_s_w);
+}
+
+static bool trans_fcnv_d_w(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_d_w);
+}
+
+static bool trans_fcnv_f_q(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_s_dw);
+}
+
+static bool trans_fcnv_d_q(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_d_dw);
+}
+
+static bool trans_fcnv_t_f_w(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_t_s_w);
+}
+
+static bool trans_fcnv_t_d_w(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_t_d_w);
+}
+
+static bool trans_fcnv_t_f_q(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_t_s_dw);
+}
+
+static bool trans_fcnv_t_d_q(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_t_d_dw);
+}
+
+static bool trans_fcnv_uw_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_uw_s);
+}
+
+static bool trans_fcnv_uq_f(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_udw_s);
+}
+
+static bool trans_fcnv_uw_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_uw_d);
+}
+
+static bool trans_fcnv_uq_d(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_udw_d);
+}
+
+static bool trans_fcnv_f_uw(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_s_uw);
+}
+
+static bool trans_fcnv_d_uw(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_d_uw);
+}
+
+static bool trans_fcnv_f_uq(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_s_udw);
+}
+
+static bool trans_fcnv_d_uq(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_d_udw);
+}
+
+static bool trans_fcnv_t_f_uw(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_t_s_uw);
+}
+
+static bool trans_fcnv_t_d_uw(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_t_d_uw);
+}
+
+static bool trans_fcnv_t_f_uq(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_t_s_udw);
+}
+
+static bool trans_fcnv_t_d_uq(DisasContext *ctx, arg_fclass01 *a)
+{
+ return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_t_d_udw);
+}
+
+/*
+ * Float class 2
+ */
+
+static bool trans_fcmp_f(DisasContext *ctx, arg_fclass2 *a)
{
TCGv_i32 ta, tb, tc, ty;
nullify_over(ctx);
- ta = load_frw0_i32(ra);
- tb = load_frw0_i32(rb);
- ty = tcg_const_i32(y);
- tc = tcg_const_i32(c);
+ ta = load_frw0_i32(a->r1);
+ tb = load_frw0_i32(a->r2);
+ ty = tcg_const_i32(a->y);
+ tc = tcg_const_i32(a->c);
gen_helper_fcmp_s(cpu_env, ta, tb, ty, tc);
@@ -3671,46 +3736,20 @@ static void do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
tcg_temp_free_i32(ty);
tcg_temp_free_i32(tc);
- nullify_end(ctx);
+ return nullify_end(ctx);
}
-static bool trans_fcmp_s_0c(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_fcmp_d(DisasContext *ctx, arg_fclass2 *a)
{
- unsigned c = extract32(insn, 0, 5);
- unsigned y = extract32(insn, 13, 3);
- unsigned rb = extract32(insn, 16, 5);
- unsigned ra = extract32(insn, 21, 5);
- do_fcmp_s(ctx, ra, rb, y, c);
- return true;
-}
-
-static bool trans_fcmp_s_0e(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned c = extract32(insn, 0, 5);
- unsigned y = extract32(insn, 13, 3);
- unsigned rb = assemble_rb64(insn);
- unsigned ra = assemble_ra64(insn);
- do_fcmp_s(ctx, ra, rb, y, c);
- return true;
-}
-
-static bool trans_fcmp_d(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
-{
- unsigned c = extract32(insn, 0, 5);
- unsigned y = extract32(insn, 13, 3);
- unsigned rb = extract32(insn, 16, 5);
- unsigned ra = extract32(insn, 21, 5);
TCGv_i64 ta, tb;
TCGv_i32 tc, ty;
nullify_over(ctx);
- ta = load_frd0(ra);
- tb = load_frd0(rb);
- ty = tcg_const_i32(y);
- tc = tcg_const_i32(c);
+ ta = load_frd0(a->r1);
+ tb = load_frd0(a->r2);
+ ty = tcg_const_i32(a->y);
+ tc = tcg_const_i32(a->c);
gen_helper_fcmp_d(cpu_env, ta, tb, ty, tc);
@@ -3722,263 +3761,129 @@ static bool trans_fcmp_d(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
return nullify_end(ctx);
}
-static bool trans_ftest_t(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
+static bool trans_ftest(DisasContext *ctx, arg_ftest *a)
{
- unsigned y = extract32(insn, 13, 3);
- unsigned cbit = (y ^ 1) - 1;
TCGv_reg t;
nullify_over(ctx);
- t = tcg_temp_new();
- tcg_gen_ld32u_reg(t, cpu_env, offsetof(CPUHPPAState, fr0_shadow));
- tcg_gen_extract_reg(t, t, 21 - cbit, 1);
- ctx->null_cond = cond_make_0(TCG_COND_NE, t);
- tcg_temp_free(t);
-
- return nullify_end(ctx);
-}
-
-static bool trans_ftest_q(DisasContext *ctx, uint32_t insn,
- const DisasInsn *di)
-{
- unsigned c = extract32(insn, 0, 5);
- int mask;
- bool inv = false;
- TCGv_reg t;
-
- nullify_over(ctx);
-
- t = tcg_temp_new();
+ t = get_temp(ctx);
tcg_gen_ld32u_reg(t, cpu_env, offsetof(CPUHPPAState, fr0_shadow));
- switch (c) {
- case 0: /* simple */
- tcg_gen_andi_reg(t, t, 0x4000000);
- ctx->null_cond = cond_make_0(TCG_COND_NE, t);
- goto done;
- case 2: /* rej */
- inv = true;
- /* fallthru */
- case 1: /* acc */
- mask = 0x43ff800;
- break;
- case 6: /* rej8 */
- inv = true;
- /* fallthru */
- case 5: /* acc8 */
- mask = 0x43f8000;
- break;
- case 9: /* acc6 */
- mask = 0x43e0000;
- break;
- case 13: /* acc4 */
- mask = 0x4380000;
- break;
- case 17: /* acc2 */
- mask = 0x4200000;
- break;
- default:
- return gen_illegal(ctx);
- }
- if (inv) {
- TCGv_reg c = load_const(ctx, mask);
- tcg_gen_or_reg(t, t, c);
- ctx->null_cond = cond_make(TCG_COND_EQ, t, c);
+ if (a->y == 1) {
+ int mask;
+ bool inv = false;
+
+ switch (a->c) {
+ case 0: /* simple */
+ tcg_gen_andi_reg(t, t, 0x4000000);
+ ctx->null_cond = cond_make_0(TCG_COND_NE, t);
+ goto done;
+ case 2: /* rej */
+ inv = true;
+ /* fallthru */
+ case 1: /* acc */
+ mask = 0x43ff800;
+ break;
+ case 6: /* rej8 */
+ inv = true;
+ /* fallthru */
+ case 5: /* acc8 */
+ mask = 0x43f8000;
+ break;
+ case 9: /* acc6 */
+ mask = 0x43e0000;
+ break;
+ case 13: /* acc4 */
+ mask = 0x4380000;
+ break;
+ case 17: /* acc2 */
+ mask = 0x4200000;
+ break;
+ default:
+ gen_illegal(ctx);
+ return true;
+ }
+ if (inv) {
+ TCGv_reg c = load_const(ctx, mask);
+ tcg_gen_or_reg(t, t, c);
+ ctx->null_cond = cond_make(TCG_COND_EQ, t, c);
+ } else {
+ tcg_gen_andi_reg(t, t, mask);
+ ctx->null_cond = cond_make_0(TCG_COND_EQ, t);
+ }
} else {
- tcg_gen_andi_reg(t, t, mask);
- ctx->null_cond = cond_make_0(TCG_COND_EQ, t);
+ unsigned cbit = (a->y ^ 1) - 1;
+
+ tcg_gen_extract_reg(t, t, 21 - cbit, 1);
+ ctx->null_cond = cond_make_0(TCG_COND_NE, t);
+ tcg_temp_free(t);
}
+
done:
return nullify_end(ctx);
}
-static bool trans_xmpyu(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+/*
+ * Float class 2
+ */
+
+static bool trans_fadd_f(DisasContext *ctx, arg_fclass3 *a)
{
- unsigned rt = extract32(insn, 0, 5);
- unsigned rb = assemble_rb64(insn);
- unsigned ra = assemble_ra64(insn);
- TCGv_i64 a, b;
+ return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fadd_s);
+}
+
+static bool trans_fadd_d(DisasContext *ctx, arg_fclass3 *a)
+{
+ return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fadd_d);
+}
+
+static bool trans_fsub_f(DisasContext *ctx, arg_fclass3 *a)
+{
+ return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fsub_s);
+}
+
+static bool trans_fsub_d(DisasContext *ctx, arg_fclass3 *a)
+{
+ return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fsub_d);
+}
+
+static bool trans_fmpy_f(DisasContext *ctx, arg_fclass3 *a)
+{
+ return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fmpy_s);
+}
+
+static bool trans_fmpy_d(DisasContext *ctx, arg_fclass3 *a)
+{
+ return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fmpy_d);
+}
+
+static bool trans_fdiv_f(DisasContext *ctx, arg_fclass3 *a)
+{
+ return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fdiv_s);
+}
+
+static bool trans_fdiv_d(DisasContext *ctx, arg_fclass3 *a)
+{
+ return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fdiv_d);
+}
+
+static bool trans_xmpyu(DisasContext *ctx, arg_xmpyu *a)
+{
+ TCGv_i64 x, y;
nullify_over(ctx);
- a = load_frw0_i64(ra);
- b = load_frw0_i64(rb);
- tcg_gen_mul_i64(a, a, b);
- save_frd(rt, a);
- tcg_temp_free_i64(a);
- tcg_temp_free_i64(b);
+ x = load_frw0_i64(a->r1);
+ y = load_frw0_i64(a->r2);
+ tcg_gen_mul_i64(x, x, y);
+ save_frd(a->t, x);
+ tcg_temp_free_i64(x);
+ tcg_temp_free_i64(y);
return nullify_end(ctx);
}
-#define FOP_DED trans_fop_ded, .f.ded
-#define FOP_DEDD trans_fop_dedd, .f.dedd
-
-#define FOP_WEW trans_fop_wew_0c, .f.wew
-#define FOP_DEW trans_fop_dew_0c, .f.dew
-#define FOP_WED trans_fop_wed_0c, .f.wed
-#define FOP_WEWW trans_fop_weww_0c, .f.weww
-
-static const DisasInsn table_float_0c[] = {
- /* floating point class zero */
- { 0x30004000, 0xfc1fffe0, FOP_WEW = gen_fcpy_s },
- { 0x30006000, 0xfc1fffe0, FOP_WEW = gen_fabs_s },
- { 0x30008000, 0xfc1fffe0, FOP_WEW = gen_helper_fsqrt_s },
- { 0x3000a000, 0xfc1fffe0, FOP_WEW = gen_helper_frnd_s },
- { 0x3000c000, 0xfc1fffe0, FOP_WEW = gen_fneg_s },
- { 0x3000e000, 0xfc1fffe0, FOP_WEW = gen_fnegabs_s },
-
- { 0x30004800, 0xfc1fffe0, FOP_DED = gen_fcpy_d },
- { 0x30006800, 0xfc1fffe0, FOP_DED = gen_fabs_d },
- { 0x30008800, 0xfc1fffe0, FOP_DED = gen_helper_fsqrt_d },
- { 0x3000a800, 0xfc1fffe0, FOP_DED = gen_helper_frnd_d },
- { 0x3000c800, 0xfc1fffe0, FOP_DED = gen_fneg_d },
- { 0x3000e800, 0xfc1fffe0, FOP_DED = gen_fnegabs_d },
-
- /* floating point class three */
- { 0x30000600, 0xfc00ffe0, FOP_WEWW = gen_helper_fadd_s },
- { 0x30002600, 0xfc00ffe0, FOP_WEWW = gen_helper_fsub_s },
- { 0x30004600, 0xfc00ffe0, FOP_WEWW = gen_helper_fmpy_s },
- { 0x30006600, 0xfc00ffe0, FOP_WEWW = gen_helper_fdiv_s },
-
- { 0x30000e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fadd_d },
- { 0x30002e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fsub_d },
- { 0x30004e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fmpy_d },
- { 0x30006e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fdiv_d },
-
- /* floating point class one */
- /* float/float */
- { 0x30000a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_d_s },
- { 0x30002200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_s_d },
- /* int/float */
- { 0x30008200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_w_s },
- { 0x30008a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_dw_s },
- { 0x3000a200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_w_d },
- { 0x3000aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_dw_d },
- /* float/int */
- { 0x30010200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_s_w },
- { 0x30010a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_d_w },
- { 0x30012200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_s_dw },
- { 0x30012a00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_d_dw },
- /* float/int truncate */
- { 0x30018200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_t_s_w },
- { 0x30018a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_t_d_w },
- { 0x3001a200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_t_s_dw },
- { 0x3001aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_t_d_dw },
- /* uint/float */
- { 0x30028200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_uw_s },
- { 0x30028a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_udw_s },
- { 0x3002a200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_uw_d },
- { 0x3002aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_udw_d },
- /* float/uint */
- { 0x30030200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_s_uw },
- { 0x30030a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_d_uw },
- { 0x30032200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_s_udw },
- { 0x30032a00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_d_udw },
- /* float/uint truncate */
- { 0x30038200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_t_s_uw },
- { 0x30038a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_t_d_uw },
- { 0x3003a200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_t_s_udw },
- { 0x3003aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_t_d_udw },
-
- /* floating point class two */
- { 0x30000400, 0xfc001fe0, trans_fcmp_s_0c },
- { 0x30000c00, 0xfc001fe0, trans_fcmp_d },
- { 0x30002420, 0xffffffe0, trans_ftest_q },
- { 0x30000420, 0xffff1fff, trans_ftest_t },
-
- /* FID. Note that ra == rt == 0, which via fcpy puts 0 into fr0.
- This is machine/revision == 0, which is reserved for simulator. */
- { 0x30000000, 0xffffffff, FOP_WEW = gen_fcpy_s },
-};
-
-#undef FOP_WEW
-#undef FOP_DEW
-#undef FOP_WED
-#undef FOP_WEWW
-#define FOP_WEW trans_fop_wew_0e, .f.wew
-#define FOP_DEW trans_fop_dew_0e, .f.dew
-#define FOP_WED trans_fop_wed_0e, .f.wed
-#define FOP_WEWW trans_fop_weww_0e, .f.weww
-
-static const DisasInsn table_float_0e[] = {
- /* floating point class zero */
- { 0x38004000, 0xfc1fff20, FOP_WEW = gen_fcpy_s },
- { 0x38006000, 0xfc1fff20, FOP_WEW = gen_fabs_s },
- { 0x38008000, 0xfc1fff20, FOP_WEW = gen_helper_fsqrt_s },
- { 0x3800a000, 0xfc1fff20, FOP_WEW = gen_helper_frnd_s },
- { 0x3800c000, 0xfc1fff20, FOP_WEW = gen_fneg_s },
- { 0x3800e000, 0xfc1fff20, FOP_WEW = gen_fnegabs_s },
-
- { 0x38004800, 0xfc1fffe0, FOP_DED = gen_fcpy_d },
- { 0x38006800, 0xfc1fffe0, FOP_DED = gen_fabs_d },
- { 0x38008800, 0xfc1fffe0, FOP_DED = gen_helper_fsqrt_d },
- { 0x3800a800, 0xfc1fffe0, FOP_DED = gen_helper_frnd_d },
- { 0x3800c800, 0xfc1fffe0, FOP_DED = gen_fneg_d },
- { 0x3800e800, 0xfc1fffe0, FOP_DED = gen_fnegabs_d },
-
- /* floating point class three */
- { 0x38000600, 0xfc00ef20, FOP_WEWW = gen_helper_fadd_s },
- { 0x38002600, 0xfc00ef20, FOP_WEWW = gen_helper_fsub_s },
- { 0x38004600, 0xfc00ef20, FOP_WEWW = gen_helper_fmpy_s },
- { 0x38006600, 0xfc00ef20, FOP_WEWW = gen_helper_fdiv_s },
-
- { 0x38000e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fadd_d },
- { 0x38002e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fsub_d },
- { 0x38004e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fmpy_d },
- { 0x38006e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fdiv_d },
-
- { 0x38004700, 0xfc00ef60, trans_xmpyu },
-
- /* floating point class one */
- /* float/float */
- { 0x38000a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_d_s },
- { 0x38002200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_s_d },
- /* int/float */
- { 0x38008200, 0xfc1ffe20, FOP_WEW = gen_helper_fcnv_w_s },
- { 0x38008a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_dw_s },
- { 0x3800a200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_w_d },
- { 0x3800aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_dw_d },
- /* float/int */
- { 0x38010200, 0xfc1ffe20, FOP_WEW = gen_helper_fcnv_s_w },
- { 0x38010a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_d_w },
- { 0x38012200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_s_dw },
- { 0x38012a00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_d_dw },
- /* float/int truncate */
- { 0x38018200, 0xfc1ffe20, FOP_WEW = gen_helper_fcnv_t_s_w },
- { 0x38018a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_t_d_w },
- { 0x3801a200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_t_s_dw },
- { 0x3801aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_t_d_dw },
- /* uint/float */
- { 0x38028200, 0xfc1ffe20, FOP_WEW = gen_helper_fcnv_uw_s },
- { 0x38028a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_udw_s },
- { 0x3802a200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_uw_d },
- { 0x3802aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_udw_d },
- /* float/uint */
- { 0x38030200, 0xfc1ffe20, FOP_WEW = gen_helper_fcnv_s_uw },
- { 0x38030a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_d_uw },
- { 0x38032200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_s_udw },
- { 0x38032a00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_d_udw },
- /* float/uint truncate */
- { 0x38038200, 0xfc1ffe20, FOP_WEW = gen_helper_fcnv_t_s_uw },
- { 0x38038a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_t_d_uw },
- { 0x3803a200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_t_s_udw },
- { 0x3803aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_t_d_udw },
-
- /* floating point class two */
- { 0x38000400, 0xfc000f60, trans_fcmp_s_0e },
- { 0x38000c00, 0xfc001fe0, trans_fcmp_d },
-};
-
-#undef FOP_WEW
-#undef FOP_DEW
-#undef FOP_WED
-#undef FOP_WEWW
-#undef FOP_DED
-#undef FOP_DEDD
-
/* Convert the fmpyadd single-precision register encodings to standard. */
static inline int fmpyadd_s_reg(unsigned r)
{
@@ -4077,43 +3982,11 @@ static bool trans_fmpyfadd_d(DisasContext *ctx, arg_fmpyfadd_d *a)
return nullify_end(ctx);
}
-static void translate_table_int(DisasContext *ctx, uint32_t insn,
- const DisasInsn table[], size_t n)
-{
- size_t i;
- for (i = 0; i < n; ++i) {
- if ((insn & table[i].mask) == table[i].insn) {
- table[i].trans(ctx, insn, &table[i]);
- return;
- }
- }
- qemu_log_mask(LOG_UNIMP, "UNIMP insn %08x @ " TARGET_FMT_lx "\n",
- insn, ctx->base.pc_next);
- gen_illegal(ctx);
-}
-
-#define translate_table(ctx, insn, table) \
- translate_table_int(ctx, insn, table, ARRAY_SIZE(table))
-
static void translate_one(DisasContext *ctx, uint32_t insn)
{
- uint32_t opc;
-
- /* Transition to the auto-generated decoder. */
- if (decode(ctx, insn)) {
- return;
+ if (!decode(ctx, insn)) {
+ gen_illegal(ctx);
}
-
- opc = extract32(insn, 26, 6);
- switch (opc) {
- case 0x0C:
- translate_table(ctx, insn, table_float_0c);
- return;
- case 0x0E:
- translate_table(ctx, insn, table_float_0e);
- return;
- }
- gen_illegal(ctx);
}
static void hppa_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index 1c8102f76e..e1d02d9280 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -350,3 +350,178 @@ bve 111010 b:5 00000 111 10000000000 n:1 - l=2
fmpyfadd_f 101110 ..... ..... ... . 0 ... . . neg:1 ..... \
rm1=%ra64 rm2=%rb64 ra3=%rc64 t=%rt64
fmpyfadd_d 101110 rm1:5 rm2:5 ... 0 1 ..0 0 0 neg:1 t:5 ra3=%rc32
+
+####
+# FP operations
+####
+
+&fclass01 r t
+&fclass2 r1 r2 c y
+&fclass3 r1 r2 t
+
+@f0c_0 ...... r:5 00000 ..... 00 000 0 t:5 &fclass01
+@f0c_1 ...... r:5 000.. ..... 01 000 0 t:5 &fclass01
+@f0c_2 ...... r1:5 r2:5 y:3 .. 10 000 . c:5 &fclass2
+@f0c_3 ...... r1:5 r2:5 ..... 11 000 0 t:5 &fclass3
+
+@f0e_f_0 ...... ..... 00000 ... 0 0 000 .. 0 ..... \
+ &fclass01 r=%ra64 t=%rt64
+@f0e_d_0 ...... r:5 00000 ... 0 1 000 00 0 t:5 &fclass01
+
+@f0e_ff_1 ...... ..... 000 ... 0000 010 .. 0 ..... \
+ &fclass01 r=%ra64 t=%rt64
+@f0e_fd_1 ...... ..... 000 ... 0100 010 .0 0 t:5 &fclass01 r=%ra64
+@f0e_df_1 ...... r:5 000 ... 0001 010 0. 0 ..... &fclass01 t=%rt64
+@f0e_dd_1 ...... r:5 000 ... 0101 010 00 0 t:5 &fclass01
+
+@f0e_f_2 ...... ..... ..... y:3 .0 100 .00 c:5 \
+ &fclass2 r1=%ra64 r2=%rb64
+@f0e_d_2 ...... r1:5 r2:5 y:3 01 100 000 c:5 &fclass2
+
+@f0e_f_3 ...... ..... ..... ... .0 110 ..0 ..... \
+ &fclass3 r1=%ra64 r2=%rb64 t=%rt64
+@f0e_d_3 ...... r1:5 r2:5 ... 01 110 000 t:5
+
+# Floating point class 0
+
+# FID. With r = t = 0, which via fcpy puts 0 into fr0.
+# This is machine/revision = 0, which is reserved for simulator.
+fcpy_f 001100 00000 00000 00000 000000 00000 \
+ &fclass01 r=0 t=0
+
+fcpy_f 001100 ..... ..... 010 00 ...... ..... @f0c_0
+fabs_f 001100 ..... ..... 011 00 ...... ..... @f0c_0
+fsqrt_f 001100 ..... ..... 100 00 ...... ..... @f0c_0
+frnd_f 001100 ..... ..... 101 00 ...... ..... @f0c_0
+fneg_f 001100 ..... ..... 110 00 ...... ..... @f0c_0
+fnegabs_f 001100 ..... ..... 111 00 ...... ..... @f0c_0
+
+fcpy_d 001100 ..... ..... 010 01 ...... ..... @f0c_0
+fabs_d 001100 ..... ..... 011 01 ...... ..... @f0c_0
+fsqrt_d 001100 ..... ..... 100 01 ...... ..... @f0c_0
+frnd_d 001100 ..... ..... 101 01 ...... ..... @f0c_0
+fneg_d 001100 ..... ..... 110 01 ...... ..... @f0c_0
+fnegabs_d 001100 ..... ..... 111 01 ...... ..... @f0c_0
+
+fcpy_f 001110 ..... ..... 010 ........ ..... @f0e_f_0
+fabs_f 001110 ..... ..... 011 ........ ..... @f0e_f_0
+fsqrt_f 001110 ..... ..... 100 ........ ..... @f0e_f_0
+frnd_f 001110 ..... ..... 101 ........ ..... @f0e_f_0
+fneg_f 001110 ..... ..... 110 ........ ..... @f0e_f_0
+fnegabs_f 001110 ..... ..... 111 ........ ..... @f0e_f_0
+
+fcpy_d 001110 ..... ..... 010 ........ ..... @f0e_d_0
+fabs_d 001110 ..... ..... 011 ........ ..... @f0e_d_0
+fsqrt_d 001110 ..... ..... 100 ........ ..... @f0e_d_0
+frnd_d 001110 ..... ..... 101 ........ ..... @f0e_d_0
+fneg_d 001110 ..... ..... 110 ........ ..... @f0e_d_0
+fnegabs_d 001110 ..... ..... 111 ........ ..... @f0e_d_0
+
+# Floating point class 1
+
+# float/float
+fcnv_d_f 001100 ..... ... 000 00 01 ...... ..... @f0c_1
+fcnv_f_d 001100 ..... ... 000 01 00 ...... ..... @f0c_1
+
+fcnv_d_f 001110 ..... ... 000 .......... ..... @f0e_df_1
+fcnv_f_d 001110 ..... ... 000 .......... ..... @f0e_fd_1
+
+# int/float
+fcnv_w_f 001100 ..... ... 001 00 00 ...... ..... @f0c_1
+fcnv_q_f 001100 ..... ... 001 00 01 ...... ..... @f0c_1
+fcnv_w_d 001100 ..... ... 001 01 00 ...... ..... @f0c_1
+fcnv_q_d 001100 ..... ... 001 01 01 ...... ..... @f0c_1
+
+fcnv_w_f 001110 ..... ... 001 .......... ..... @f0e_ff_1
+fcnv_q_f 001110 ..... ... 001 .......... ..... @f0e_df_1
+fcnv_w_d 001110 ..... ... 001 .......... ..... @f0e_fd_1
+fcnv_q_d 001110 ..... ... 001 .......... ..... @f0e_dd_1
+
+# float/int
+fcnv_f_w 001100 ..... ... 010 00 00 ...... ..... @f0c_1
+fcnv_d_w 001100 ..... ... 010 00 01 ...... ..... @f0c_1
+fcnv_f_q 001100 ..... ... 010 01 00 ...... ..... @f0c_1
+fcnv_d_q 001100 ..... ... 010 01 01 ...... ..... @f0c_1
+
+fcnv_f_w 001110 ..... ... 010 .......... ..... @f0e_ff_1
+fcnv_d_w 001110 ..... ... 010 .......... ..... @f0e_df_1
+fcnv_f_q 001110 ..... ... 010 .......... ..... @f0e_fd_1
+fcnv_d_q 001110 ..... ... 010 .......... ..... @f0e_dd_1
+
+# float/int truncate
+fcnv_t_f_w 001100 ..... ... 011 00 00 ...... ..... @f0c_1
+fcnv_t_d_w 001100 ..... ... 011 00 01 ...... ..... @f0c_1
+fcnv_t_f_q 001100 ..... ... 011 01 00 ...... ..... @f0c_1
+fcnv_t_d_q 001100 ..... ... 011 01 01 ...... ..... @f0c_1
+
+fcnv_t_f_w 001110 ..... ... 011 .......... ..... @f0e_ff_1
+fcnv_t_d_w 001110 ..... ... 011 .......... ..... @f0e_df_1
+fcnv_t_f_q 001110 ..... ... 011 .......... ..... @f0e_fd_1
+fcnv_t_d_q 001110 ..... ... 011 .......... ..... @f0e_dd_1
+
+# uint/float
+fcnv_uw_f 001100 ..... ... 101 00 00 ...... ..... @f0c_1
+fcnv_uq_f 001100 ..... ... 101 00 01 ...... ..... @f0c_1
+fcnv_uw_d 001100 ..... ... 101 01 00 ...... ..... @f0c_1
+fcnv_uq_d 001100 ..... ... 101 01 01 ...... ..... @f0c_1
+
+fcnv_uw_f 001110 ..... ... 101 .......... ..... @f0e_ff_1
+fcnv_uq_f 001110 ..... ... 101 .......... ..... @f0e_df_1
+fcnv_uw_d 001110 ..... ... 101 .......... ..... @f0e_fd_1
+fcnv_uq_d 001110 ..... ... 101 .......... ..... @f0e_dd_1
+
+# float/int
+fcnv_f_uw 001100 ..... ... 110 00 00 ...... ..... @f0c_1
+fcnv_d_uw 001100 ..... ... 110 00 01 ...... ..... @f0c_1
+fcnv_f_uq 001100 ..... ... 110 01 00 ...... ..... @f0c_1
+fcnv_d_uq 001100 ..... ... 110 01 01 ...... ..... @f0c_1
+
+fcnv_f_uw 001110 ..... ... 110 .......... ..... @f0e_ff_1
+fcnv_d_uw 001110 ..... ... 110 .......... ..... @f0e_df_1
+fcnv_f_uq 001110 ..... ... 110 .......... ..... @f0e_fd_1
+fcnv_d_uq 001110 ..... ... 110 .......... ..... @f0e_dd_1
+
+# float/int truncate
+fcnv_t_f_uw 001100 ..... ... 111 00 00 ...... ..... @f0c_1
+fcnv_t_d_uw 001100 ..... ... 111 00 01 ...... ..... @f0c_1
+fcnv_t_f_uq 001100 ..... ... 111 01 00 ...... ..... @f0c_1
+fcnv_t_d_uq 001100 ..... ... 111 01 01 ...... ..... @f0c_1
+
+fcnv_t_f_uw 001110 ..... ... 111 .......... ..... @f0e_ff_1
+fcnv_t_d_uw 001110 ..... ... 111 .......... ..... @f0e_df_1
+fcnv_t_f_uq 001110 ..... ... 111 .......... ..... @f0e_fd_1
+fcnv_t_d_uq 001110 ..... ... 111 .......... ..... @f0e_dd_1
+
+# Floating point class 2
+
+ftest 001100 00000 00000 y:3 00 10000 1 c:5
+
+fcmp_f 001100 ..... ..... ... 00 ..... 0 ..... @f0c_2
+fcmp_d 001100 ..... ..... ... 01 ..... 0 ..... @f0c_2
+
+fcmp_f 001110 ..... ..... ... ..... ... ..... @f0e_f_2
+fcmp_d 001110 ..... ..... ... ..... ... ..... @f0e_d_2
+
+# Floating point class 3
+
+fadd_f 001100 ..... ..... 000 00 ...... ..... @f0c_3
+fsub_f 001100 ..... ..... 001 00 ...... ..... @f0c_3
+fmpy_f 001100 ..... ..... 010 00 ...... ..... @f0c_3
+fdiv_f 001100 ..... ..... 011 00 ...... ..... @f0c_3
+
+fadd_d 001100 ..... ..... 000 01 ...... ..... @f0c_3
+fsub_d 001100 ..... ..... 001 01 ...... ..... @f0c_3
+fmpy_d 001100 ..... ..... 010 01 ...... ..... @f0c_3
+fdiv_d 001100 ..... ..... 011 01 ...... ..... @f0c_3
+
+fadd_f 001110 ..... ..... 000 ..... ... ..... @f0e_f_3
+fsub_f 001110 ..... ..... 001 ..... ... ..... @f0e_f_3
+fmpy_f 001110 ..... ..... 010 ..... ... ..... @f0e_f_3
+fdiv_f 001110 ..... ..... 011 ..... ... ..... @f0e_f_3
+
+fadd_d 001110 ..... ..... 000 ..... ... ..... @f0e_d_3
+fsub_d 001110 ..... ..... 001 ..... ... ..... @f0e_d_3
+fmpy_d 001110 ..... ..... 010 ..... ... ..... @f0e_d_3
+fdiv_d 001110 ..... ..... 011 ..... ... ..... @f0e_d_3
+
+xmpyu 001110 ..... ..... 010 .0111 .00 t:5 r1=%ra64 r2=%rb64
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 19/19] target/hppa: Merge translate_one into hppa_tr_translate_insn
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (17 preceding siblings ...)
2019-02-07 11:53 ` [Qemu-devel] [PATCH 18/19] target/hppa: Convert fp operate insns Richard Henderson
@ 2019-02-07 11:54 ` Richard Henderson
2019-02-11 8:21 ` [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Sven Schnelle
19 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2019-02-07 11:54 UTC (permalink / raw)
To: qemu-devel; +Cc: deller, svens
Now that the implementation is entirely within the generated
decode function, eliminate the wrapper.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index ecec5c42d1..6836fb6245 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3982,13 +3982,6 @@ static bool trans_fmpyfadd_d(DisasContext *ctx, arg_fmpyfadd_d *a)
return nullify_end(ctx);
}
-static void translate_one(DisasContext *ctx, uint32_t insn)
-{
- if (!decode(ctx, insn)) {
- gen_illegal(ctx);
- }
-}
-
static void hppa_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
@@ -4094,7 +4087,9 @@ static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
ret = DISAS_NEXT;
} else {
ctx->insn = insn;
- translate_one(ctx, insn);
+ if (!decode(ctx, insn)) {
+ gen_illegal(ctx);
+ }
ret = ctx->base.is_jmp;
assert(ctx->null_lab == NULL);
}
--
2.17.2
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
` (18 preceding siblings ...)
2019-02-07 11:54 ` [Qemu-devel] [PATCH 19/19] target/hppa: Merge translate_one into hppa_tr_translate_insn Richard Henderson
@ 2019-02-11 8:21 ` Sven Schnelle
2019-02-11 9:05 ` Helge Deller
19 siblings, 1 reply; 22+ messages in thread
From: Sven Schnelle @ 2019-02-11 8:21 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel, deller
Hi Richard,
On Thu, Feb 07, 2019 at 11:53:41AM +0000, Richard Henderson wrote:
> Helge or Sven, if you have a chance to do a bit more testing in
> the next week, I would appreciate it. Otherwise we can fix any
> other minor problems on mainline.
I tested this during the weekend with my HP-UX branch and found no
problems. Feel free to add
Tested-by: Sven Schnelle <svens@stackframe.org>
Regards
Sven
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree
2019-02-11 8:21 ` [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Sven Schnelle
@ 2019-02-11 9:05 ` Helge Deller
0 siblings, 0 replies; 22+ messages in thread
From: Helge Deller @ 2019-02-11 9:05 UTC (permalink / raw)
To: Richard Henderson; +Cc: Sven Schnelle, qemu-devel
On 11.02.19 09:21, Sven Schnelle wrote:
> Hi Richard,
>
> On Thu, Feb 07, 2019 at 11:53:41AM +0000, Richard Henderson wrote:
>
>> Helge or Sven, if you have a chance to do a bit more testing in
>> the next week, I would appreciate it. Otherwise we can fix any
>> other minor problems on mainline.
>
> I tested this during the weekend with my HP-UX branch and found no
> problems. Feel free to add
>
> Tested-by: Sven Schnelle <svens@stackframe.org>
No issues found here either:
Tested-by: Helge Deller <deller@gmx.de>
Thanks!
Helge
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2019-02-11 9:05 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-02-07 11:53 [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 01/19] target/hppa: Use DisasContextBase.is_jmp Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 02/19] target/hppa: Begin using scripts/decodetree.py Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 03/19] target/hppa: Convert move to/from system registers Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 04/19] target/hppa: Convert remainder of system insns Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 05/19] target/hppa: Unify specializations of OR Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 06/19] target/hppa: Convert memory management insns Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 07/19] target/hppa: Convert arithmetic/logical insns Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 08/19] target/hppa: Convert indexed memory insns Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 09/19] target/hppa: Convert fp multiply-add Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 10/19] target/hppa: Convert conditional branches Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 11/19] target/hppa: Convert shift, extract, deposit insns Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 12/19] target/hppa: Convert direct and indirect branches Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 13/19] target/hppa: Convert arithmetic immediate insns Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 14/19] target/hppa: Convert offset memory insns Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 15/19] target/hppa: Convert fp indexed " Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 16/19] target/hppa: Convert halt/reset insns Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 17/19] target/hppa: Convert fp fused multiply-add insns Richard Henderson
2019-02-07 11:53 ` [Qemu-devel] [PATCH 18/19] target/hppa: Convert fp operate insns Richard Henderson
2019-02-07 11:54 ` [Qemu-devel] [PATCH 19/19] target/hppa: Merge translate_one into hppa_tr_translate_insn Richard Henderson
2019-02-11 8:21 ` [Qemu-devel] [PATCH 00/19] target/hppa: Convert to decodetree Sven Schnelle
2019-02-11 9:05 ` Helge Deller
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.