* [Qemu-devel] [PULL 00/24] target/hppa patch queue
@ 2019-02-12 4:56 Richard Henderson
2019-02-12 4:56 ` [Qemu-devel] [PULL 01/24] target/hppa: Use DisasContextBase.is_jmp Richard Henderson
` (25 more replies)
0 siblings, 26 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:56 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
The following changes since commit 22c5f446514a2a4bb0dbe1fea26713da92fc85fa:
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190211' into staging (2019-02-11 17:04:57 +0000)
are available in the Git repository at:
https://github.com/rth7680/qemu.git tags/pull-hppa-20190211
for you to fetch changes up to 23e76627deba013509b5f1a1e1c53e8e111145aa:
hw/hppa: forward requests to CPU HPA (2019-02-11 20:49:06 -0800)
----------------------------------------------------------------
Convert to decodetree.
Fix signed overflow conditions.
Fix dcor.
Add CPU MIE to PCI address space.
----------------------------------------------------------------
Richard Henderson (20):
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: Rearrange log conditions
Sven Schnelle (4):
target/hppa: move GETPC to HELPER() functions
target/hppa: Fix addition '</<=' conditions
target/hppa: fix dcor instruction
hw/hppa: forward requests to CPU HPA
hw/hppa/dino.c | 8 +-
target/hppa/op_helper.c | 16 +-
target/hppa/translate.c | 3355 ++++++++++++++++++---------------------------
target/hppa/Makefile.objs | 8 +
target/hppa/insns.decode | 527 +++++++
5 files changed, 1915 insertions(+), 1999 deletions(-)
create mode 100644 target/hppa/insns.decode
^ permalink raw reply [flat|nested] 30+ messages in thread
* [Qemu-devel] [PULL 01/24] target/hppa: Use DisasContextBase.is_jmp
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
@ 2019-02-12 4:56 ` Richard Henderson
2019-02-12 4:56 ` [Qemu-devel] [PULL 02/24] target/hppa: Begin using scripts/decodetree.py Richard Henderson
` (24 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:56 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Instead of returning DisasJumpType, immediately store it.
Return true in preparation for conversion to the decodetree script.
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 02/24] target/hppa: Begin using scripts/decodetree.py
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
2019-02-12 4:56 ` [Qemu-devel] [PULL 01/24] target/hppa: Use DisasContextBase.is_jmp Richard Henderson
@ 2019-02-12 4:56 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 03/24] target/hppa: Convert move to/from system registers Richard Henderson
` (23 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:56 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Convert the BREAK instruction to start.
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 03/24] target/hppa: Convert move to/from system registers
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
2019-02-12 4:56 ` [Qemu-devel] [PULL 01/24] target/hppa: Use DisasContextBase.is_jmp Richard Henderson
2019-02-12 4:56 ` [Qemu-devel] [PULL 02/24] target/hppa: Begin using scripts/decodetree.py Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 04/24] target/hppa: Convert remainder of system insns Richard Henderson
` (22 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 04/24] target/hppa: Convert remainder of system insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (2 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 03/24] target/hppa: Convert move to/from system registers Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 05/24] target/hppa: Unify specializations of OR Richard Henderson
` (21 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 05/24] target/hppa: Unify specializations of OR
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (3 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 04/24] target/hppa: Convert remainder of system insns Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 06/24] target/hppa: Convert memory management insns Richard Henderson
` (20 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
With decodetree.py, the specializations would conflict so we
must have a single entry point for all variants of OR.
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 06/24] target/hppa: Convert memory management insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (4 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 05/24] target/hppa: Unify specializations of OR Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 07/24] target/hppa: Convert arithmetic/logical insns Richard Henderson
` (19 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 07/24] target/hppa: Convert arithmetic/logical insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (5 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 06/24] target/hppa: Convert memory management insns Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 08/24] target/hppa: Convert indexed memory insns Richard Henderson
` (18 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 08/24] target/hppa: Convert indexed memory insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (6 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 07/24] target/hppa: Convert arithmetic/logical insns Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 09/24] target/hppa: Convert fp multiply-add Richard Henderson
` (17 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 09/24] target/hppa: Convert fp multiply-add
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (7 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 08/24] target/hppa: Convert indexed memory insns Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 10/24] target/hppa: Convert conditional branches Richard Henderson
` (16 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 10/24] target/hppa: Convert conditional branches
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (8 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 09/24] target/hppa: Convert fp multiply-add Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 11/24] target/hppa: Convert shift, extract, deposit insns Richard Henderson
` (15 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 11/24] target/hppa: Convert shift, extract, deposit insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (9 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 10/24] target/hppa: Convert conditional branches Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 12/24] target/hppa: Convert direct and indirect branches Richard Henderson
` (14 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 12/24] target/hppa: Convert direct and indirect branches
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (10 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 11/24] target/hppa: Convert shift, extract, deposit insns Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 13/24] target/hppa: Convert arithmetic immediate insns Richard Henderson
` (13 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 13/24] target/hppa: Convert arithmetic immediate insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (11 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 12/24] target/hppa: Convert direct and indirect branches Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 14/24] target/hppa: Convert offset memory insns Richard Henderson
` (12 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 14/24] target/hppa: Convert offset memory insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (12 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 13/24] target/hppa: Convert arithmetic immediate insns Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 15/24] target/hppa: Convert fp indexed " Richard Henderson
` (11 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 15/24] target/hppa: Convert fp indexed memory insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (13 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 14/24] target/hppa: Convert offset memory insns Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 16/24] target/hppa: Convert halt/reset insns Richard Henderson
` (10 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 16/24] target/hppa: Convert halt/reset insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (14 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 15/24] target/hppa: Convert fp indexed " Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 17/24] target/hppa: Convert fp fused multiply-add insns Richard Henderson
` (9 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 17/24] target/hppa: Convert fp fused multiply-add insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (15 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 16/24] target/hppa: Convert halt/reset insns Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 18/24] target/hppa: Convert fp operate insns Richard Henderson
` (8 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 18/24] target/hppa: Convert fp operate insns
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (16 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 17/24] target/hppa: Convert fp fused multiply-add insns Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 19/24] target/hppa: Merge translate_one into hppa_tr_translate_insn Richard Henderson
` (7 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 19/24] target/hppa: Merge translate_one into hppa_tr_translate_insn
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (17 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 18/24] target/hppa: Convert fp operate insns Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 20/24] target/hppa: move GETPC to HELPER() functions Richard Henderson
` (6 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
Now that the implementation is entirely within the generated
decode function, eliminate the wrapper.
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Sven Schnelle <svens@stackframe.org>
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] 30+ messages in thread
* [Qemu-devel] [PULL 20/24] target/hppa: move GETPC to HELPER() functions
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (18 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 19/24] target/hppa: Merge translate_one into hppa_tr_translate_insn Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 21/24] target/hppa: Rearrange log conditions Richard Henderson
` (5 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell, Sven Schnelle
From: Sven Schnelle <svens@stackframe.org>
When QEMU is compiled with -O0, these functions are inlined
which will cause a wrong restart address generated for the TB.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Message-Id: <20190211181907.2219-2-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/op_helper.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index 6bf478e7b0..268caaaa20 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -81,10 +81,8 @@ static void atomic_store_3(CPUHPPAState *env, target_ulong addr, uint32_t val,
}
static void do_stby_b(CPUHPPAState *env, target_ulong addr, target_ureg val,
- bool parallel)
+ bool parallel, uintptr_t ra)
{
- uintptr_t ra = GETPC();
-
switch (addr & 3) {
case 3:
cpu_stb_data_ra(env, addr, val, ra);
@@ -109,20 +107,18 @@ static void do_stby_b(CPUHPPAState *env, target_ulong addr, target_ureg val,
void HELPER(stby_b)(CPUHPPAState *env, target_ulong addr, target_ureg val)
{
- do_stby_b(env, addr, val, false);
+ do_stby_b(env, addr, val, false, GETPC());
}
void HELPER(stby_b_parallel)(CPUHPPAState *env, target_ulong addr,
target_ureg val)
{
- do_stby_b(env, addr, val, true);
+ do_stby_b(env, addr, val, true, GETPC());
}
static void do_stby_e(CPUHPPAState *env, target_ulong addr, target_ureg val,
- bool parallel)
+ bool parallel, uintptr_t ra)
{
- uintptr_t ra = GETPC();
-
switch (addr & 3) {
case 3:
/* The 3 byte store must appear atomic. */
@@ -151,13 +147,13 @@ static void do_stby_e(CPUHPPAState *env, target_ulong addr, target_ureg val,
void HELPER(stby_e)(CPUHPPAState *env, target_ulong addr, target_ureg val)
{
- do_stby_e(env, addr, val, false);
+ do_stby_e(env, addr, val, false, GETPC());
}
void HELPER(stby_e_parallel)(CPUHPPAState *env, target_ulong addr,
target_ureg val)
{
- do_stby_e(env, addr, val, true);
+ do_stby_e(env, addr, val, true, GETPC());
}
target_ureg HELPER(probe)(CPUHPPAState *env, target_ulong addr,
--
2.17.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [Qemu-devel] [PULL 21/24] target/hppa: Rearrange log conditions
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (19 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 20/24] target/hppa: move GETPC to HELPER() functions Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 22/24] target/hppa: Fix addition '</<=' conditions Richard Henderson
` (4 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell
We will be fixing do_cond vs signed overflow, which requires
that do_log_cond not rely on do_cond.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 56 +++++++++++++++++++++++++++++++++++------
1 file changed, 49 insertions(+), 7 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 6836fb6245..aae5714235 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -432,6 +432,15 @@ static DisasCond cond_make_f(void)
};
}
+static DisasCond cond_make_t(void)
+{
+ return (DisasCond){
+ .c = TCG_COND_ALWAYS,
+ .a0 = NULL,
+ .a1 = NULL,
+ };
+}
+
static DisasCond cond_make_n(void)
{
return (DisasCond){
@@ -930,17 +939,50 @@ static DisasCond do_sub_cond(unsigned cf, TCGv_reg res,
return cond;
}
-/* Similar, but for logicals, where the carry and overflow bits are not
- computed, and use of them is undefined. */
+/*
+ * Similar, but for logicals, where the carry and overflow bits are not
+ * computed, and use of them is undefined.
+ *
+ * Undefined or not, hardware does not trap. It seems reasonable to
+ * assume hardware treats cases c={4,5,6} as if C=0 & V=0, since that's
+ * how cases c={2,3} are treated.
+ */
static DisasCond do_log_cond(unsigned cf, TCGv_reg res)
{
- switch (cf >> 1) {
- case 4: case 5: case 6:
- cf &= 1;
- break;
+ switch (cf) {
+ case 0: /* never */
+ case 9: /* undef, C */
+ case 11: /* undef, C & !Z */
+ case 12: /* undef, V */
+ return cond_make_f();
+
+ case 1: /* true */
+ case 8: /* undef, !C */
+ case 10: /* undef, !C | Z */
+ case 13: /* undef, !V */
+ return cond_make_t();
+
+ case 2: /* == */
+ return cond_make_0(TCG_COND_EQ, res);
+ case 3: /* <> */
+ return cond_make_0(TCG_COND_NE, res);
+ case 4: /* < */
+ return cond_make_0(TCG_COND_LT, res);
+ case 5: /* >= */
+ return cond_make_0(TCG_COND_GE, res);
+ case 6: /* <= */
+ return cond_make_0(TCG_COND_LE, res);
+ case 7: /* > */
+ return cond_make_0(TCG_COND_GT, res);
+
+ case 14: /* OD */
+ case 15: /* EV */
+ return do_cond(cf, res, NULL, NULL);
+
+ default:
+ g_assert_not_reached();
}
- return do_cond(cf, res, res, res);
}
/* Similar, but for shift/extract/deposit conditions. */
--
2.17.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [Qemu-devel] [PULL 22/24] target/hppa: Fix addition '</<=' conditions
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (20 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 21/24] target/hppa: Rearrange log conditions Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 23/24] target/hppa: fix dcor instruction Richard Henderson
` (3 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell, Sven Schnelle
From: Sven Schnelle <svens@stackframe.org>
These conditions include the signed overflow bit. See page 5-3
of the Parisc 1.1 Architecture Reference Manual for details.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
[rth: More changes for c == 3, to compute (N^V)|Z properly.]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 95 +++++++++++++++++++++++++----------------
1 file changed, 58 insertions(+), 37 deletions(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index aae5714235..026ba5cb3e 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -452,15 +452,19 @@ static DisasCond cond_make_n(void)
};
}
+static DisasCond cond_make_0_tmp(TCGCond c, TCGv_reg a0)
+{
+ assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
+ return (DisasCond){
+ .c = c, .a0 = a0, .a1_is_0 = true
+ };
+}
+
static DisasCond cond_make_0(TCGCond c, TCGv_reg a0)
{
- DisasCond r = { .c = c, .a1 = NULL, .a1_is_0 = true };
-
- assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
- r.a0 = tcg_temp_new();
- tcg_gen_mov_reg(r.a0, a0);
-
- return r;
+ TCGv_reg tmp = tcg_temp_new();
+ tcg_gen_mov_reg(tmp, a0);
+ return cond_make_0_tmp(c, tmp);
}
static DisasCond cond_make(TCGCond c, TCGv_reg a0, TCGv_reg a1)
@@ -849,12 +853,20 @@ static void gen_goto_tb(DisasContext *ctx, int which,
}
}
-/* 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.
- However, considering the Addition, Subtraction and Logical conditions
- as a whole it would appear that these relations are similar to what
- a traditional NZCV set of flags would produce. */
+static bool cond_need_sv(int c)
+{
+ return c == 2 || c == 3 || c == 6;
+}
+
+static bool cond_need_cb(int c)
+{
+ return c == 4 || c == 5;
+}
+
+/*
+ * Compute conditional for arithmetic. See Page 5-3, Table 5-1, of
+ * the Parisc 1.1 Architecture Reference Manual for details.
+ */
static DisasCond do_cond(unsigned cf, TCGv_reg res,
TCGv_reg cb_msb, TCGv_reg sv)
@@ -863,17 +875,32 @@ static DisasCond do_cond(unsigned cf, TCGv_reg res,
TCGv_reg tmp;
switch (cf >> 1) {
- case 0: /* Never / TR */
+ case 0: /* Never / TR (0 / 1) */
cond = cond_make_f();
break;
case 1: /* = / <> (Z / !Z) */
cond = cond_make_0(TCG_COND_EQ, res);
break;
- case 2: /* < / >= (N / !N) */
- cond = cond_make_0(TCG_COND_LT, res);
+ case 2: /* < / >= (N ^ V / !(N ^ V) */
+ tmp = tcg_temp_new();
+ tcg_gen_xor_reg(tmp, res, sv);
+ cond = cond_make_0_tmp(TCG_COND_LT, tmp);
break;
- case 3: /* <= / > (N | Z / !N & !Z) */
- cond = cond_make_0(TCG_COND_LE, res);
+ case 3: /* <= / > (N ^ V) | Z / !((N ^ V) | Z) */
+ /*
+ * Simplify:
+ * (N ^ V) | Z
+ * ((res < 0) ^ (sv < 0)) | !res
+ * ((res ^ sv) < 0) | !res
+ * (~(res ^ sv) >= 0) | !res
+ * !(~(res ^ sv) >> 31) | !res
+ * !(~(res ^ sv) >> 31 & res)
+ */
+ tmp = tcg_temp_new();
+ tcg_gen_eqv_reg(tmp, res, sv);
+ tcg_gen_sari_reg(tmp, tmp, TARGET_REGISTER_BITS - 1);
+ tcg_gen_and_reg(tmp, tmp, res);
+ cond = cond_make_0_tmp(TCG_COND_EQ, tmp);
break;
case 4: /* NUV / UV (!C / C) */
cond = cond_make_0(TCG_COND_EQ, cb_msb);
@@ -882,8 +909,7 @@ static DisasCond do_cond(unsigned cf, TCGv_reg res,
tmp = tcg_temp_new();
tcg_gen_neg_reg(tmp, cb_msb);
tcg_gen_and_reg(tmp, tmp, res);
- cond = cond_make_0(TCG_COND_EQ, tmp);
- tcg_temp_free(tmp);
+ cond = cond_make_0_tmp(TCG_COND_EQ, tmp);
break;
case 6: /* SV / NSV (V / !V) */
cond = cond_make_0(TCG_COND_LT, sv);
@@ -891,8 +917,7 @@ static DisasCond do_cond(unsigned cf, TCGv_reg res,
case 7: /* OD / EV */
tmp = tcg_temp_new();
tcg_gen_andi_reg(tmp, res, 1);
- cond = cond_make_0(TCG_COND_NE, tmp);
- tcg_temp_free(tmp);
+ cond = cond_make_0_tmp(TCG_COND_NE, tmp);
break;
default:
g_assert_not_reached();
@@ -930,7 +955,7 @@ static DisasCond do_sub_cond(unsigned cf, TCGv_reg res,
cond = cond_make(TCG_COND_LEU, in1, in2);
break;
default:
- return do_cond(cf, res, sv, sv);
+ return do_cond(cf, res, NULL, sv);
}
if (cf & 1) {
cond.c = tcg_invert_cond(cond.c);
@@ -1129,7 +1154,7 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1,
in1 = tmp;
}
- if (!is_l || c == 4 || c == 5) {
+ if (!is_l || cond_need_cb(c)) {
TCGv_reg zero = tcg_const_reg(0);
cb_msb = get_temp(ctx);
tcg_gen_add2_reg(dest, cb_msb, in1, zero, in2, zero);
@@ -1151,7 +1176,7 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_reg in1,
/* Compute signed overflow if required. */
sv = NULL;
- if (is_tsv || c == 6) {
+ if (is_tsv || cond_need_sv(c)) {
sv = do_add_sv(ctx, dest, in1, in2);
if (is_tsv) {
/* ??? Need to include overflow from shift. */
@@ -1242,7 +1267,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_reg in1,
/* Compute signed overflow if required. */
sv = NULL;
- if (is_tsv || c == 6) {
+ if (is_tsv || cond_need_sv(c)) {
sv = do_sub_sv(ctx, dest, in1, in2);
if (is_tsv) {
gen_helper_tsv(cpu_env, sv);
@@ -1314,7 +1339,7 @@ static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_reg in1,
/* Compute signed overflow if required. */
sv = NULL;
- if ((cf >> 1) == 6) {
+ if (cond_need_sv(cf >> 1)) {
sv = do_sub_sv(ctx, dest, in1, in2);
}
@@ -2781,7 +2806,7 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
/* Install the new nullification. */
if (a->cf) {
TCGv_reg sv = NULL;
- if (a->cf >> 1 == 6) {
+ if (cond_need_sv(a->cf >> 1)) {
/* ??? The lshift is supposed to contribute to overflow. */
sv = do_add_sv(ctx, dest, add1, add2);
}
@@ -2982,7 +3007,7 @@ static bool do_cmpb(DisasContext *ctx, unsigned r, TCGv_reg in1,
tcg_gen_sub_reg(dest, in1, in2);
sv = NULL;
- if (c == 6) {
+ if (cond_need_sv(c)) {
sv = do_sub_sv(ctx, dest, in1, in2);
}
@@ -3013,19 +3038,15 @@ static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1,
sv = NULL;
cb_msb = NULL;
- switch (c) {
- default:
- tcg_gen_add_reg(dest, in1, in2);
- break;
- case 4: case 5:
+ if (cond_need_cb(c)) {
cb_msb = get_temp(ctx);
tcg_gen_movi_reg(cb_msb, 0);
tcg_gen_add2_reg(dest, cb_msb, in1, cb_msb, in2, cb_msb);
- break;
- case 6:
+ } else {
tcg_gen_add_reg(dest, in1, in2);
+ }
+ if (cond_need_sv(c)) {
sv = do_add_sv(ctx, dest, in1, in2);
- break;
}
cond = do_cond(c * 2 + f, dest, cb_msb, sv);
--
2.17.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [Qemu-devel] [PULL 23/24] target/hppa: fix dcor instruction
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (21 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 22/24] target/hppa: Fix addition '</<=' conditions Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 24/24] hw/hppa: forward requests to CPU HPA Richard Henderson
` (2 subsequent siblings)
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell, Sven Schnelle
From: Sven Schnelle <svens@stackframe.org>
It looks like the operands where exchanged. HP bootrom tests the
following sequence:
0x00000000f0004064: ldil L%-66666800,r7
0x00000000f0004068: addi 19f,r7,r7
0x00000000f000406c: addi -1,r0,rp
0x00000000f0004070: addi f,r0,r4
0x00000000f0004074: addi 1,r4,r5
0x00000000f0004078: dcor rp,r6
0x00000000f000407c: cmpb,<>,n r6,r7,0xf000411
This returned 0x66666661 instead of the expected 0x9999999f in QEMU.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Message-Id: <20190211181907.2219-6-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/hppa/translate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 026ba5cb3e..b4fd307b77 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2744,7 +2744,7 @@ static bool do_dcor(DisasContext *ctx, arg_rr_cf *a, bool is_i)
}
tcg_gen_andi_reg(tmp, tmp, 0x11111111);
tcg_gen_muli_reg(tmp, tmp, 6);
- do_unit(ctx, a->t, tmp, load_gpr(ctx, a->r), a->cf, false,
+ do_unit(ctx, a->t, load_gpr(ctx, a->r), tmp, a->cf, false,
is_i ? tcg_gen_add_reg : tcg_gen_sub_reg);
return nullify_end(ctx);
}
--
2.17.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [Qemu-devel] [PULL 24/24] hw/hppa: forward requests to CPU HPA
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (22 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 23/24] target/hppa: fix dcor instruction Richard Henderson
@ 2019-02-12 4:57 ` Richard Henderson
2019-02-12 13:15 ` [Qemu-devel] [PULL 00/24] target/hppa patch queue Peter Maydell
2019-02-13 16:33 ` no-reply
25 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2019-02-12 4:57 UTC (permalink / raw
To: qemu-devel; +Cc: peter.maydell, Sven Schnelle
From: Sven Schnelle <svens@stackframe.org>
HP-UX 10.20 uses busmaster writes to the CPU EIR to signal
interrupts from the SCSI constroller. (Similar to what is known
as MSI on x86)
Signed-off-by: Sven Schnelle <svens@stackframe.org>
Message-Id: <20190211192039.5457-1-svens@stackframe.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
hw/hppa/dino.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
index 31e09942b5..360716de57 100644
--- a/hw/hppa/dino.c
+++ b/hw/hppa/dino.c
@@ -105,6 +105,7 @@ typedef struct DinoState {
MemoryRegion bm;
MemoryRegion bm_ram_alias;
MemoryRegion bm_pci_alias;
+ MemoryRegion bm_cpu_alias;
MemoryRegion cpu0_eir_mem;
} DinoState;
@@ -473,12 +474,17 @@ PCIBus *dino_init(MemoryRegion *addr_space,
memory_region_init_alias(&s->bm_pci_alias, OBJECT(s),
"bm-pci", &s->pci_mem,
0xf0000000 + DINO_MEM_CHUNK_SIZE,
- 31 * DINO_MEM_CHUNK_SIZE);
+ 30 * DINO_MEM_CHUNK_SIZE);
+ memory_region_init_alias(&s->bm_cpu_alias, OBJECT(s),
+ "bm-cpu", addr_space, 0xfff00000,
+ 0xfffff);
memory_region_add_subregion(&s->bm, 0,
&s->bm_ram_alias);
memory_region_add_subregion(&s->bm,
0xf0000000 + DINO_MEM_CHUNK_SIZE,
&s->bm_pci_alias);
+ memory_region_add_subregion(&s->bm, 0xfff00000,
+ &s->bm_cpu_alias);
address_space_init(&s->bm_as, &s->bm, "pci-bm");
pci_setup_iommu(b, dino_pcihost_set_iommu, s);
--
2.17.2
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [Qemu-devel] [PULL 00/24] target/hppa patch queue
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (23 preceding siblings ...)
2019-02-12 4:57 ` [Qemu-devel] [PULL 24/24] hw/hppa: forward requests to CPU HPA Richard Henderson
@ 2019-02-12 13:15 ` Peter Maydell
2019-02-13 18:40 ` Philippe Mathieu-Daudé
2019-02-13 16:33 ` no-reply
25 siblings, 1 reply; 30+ messages in thread
From: Peter Maydell @ 2019-02-12 13:15 UTC (permalink / raw
To: Richard Henderson; +Cc: QEMU Developers
On Tue, 12 Feb 2019 at 04:57, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The following changes since commit 22c5f446514a2a4bb0dbe1fea26713da92fc85fa:
>
> Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190211' into staging (2019-02-11 17:04:57 +0000)
>
> are available in the Git repository at:
>
> https://github.com/rth7680/qemu.git tags/pull-hppa-20190211
>
> for you to fetch changes up to 23e76627deba013509b5f1a1e1c53e8e111145aa:
>
> hw/hppa: forward requests to CPU HPA (2019-02-11 20:49:06 -0800)
>
> ----------------------------------------------------------------
> Convert to decodetree.
> Fix signed overflow conditions.
> Fix dcor.
> Add CPU MIE to PCI address space.
Hi -- clang compiles fail with:
In file included from
/home/petmay01/linaro/qemu-for-merges/target/hppa/translate.c:337:
target/hppa/decode.inc.c:471:16: error: redefinition of typedef
'arg_be' is a C11 feature [-Werror,-Wtypedef-redefinition]
typedef arg_be arg_be;
^
target/hppa/decode.inc.c:9:3: note: previous definition is here
} arg_be;
^
target/hppa/decode.inc.c:473:16: error: redefinition of typedef
'arg_bl' is a C11 feature [-Werror,-Wtypedef-redefinition]
typedef arg_bl arg_bl;
^
target/hppa/decode.inc.c:15:3: note: previous definition is here
} arg_bl;
^
thanks
-- PMM
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [Qemu-devel] [PULL 00/24] target/hppa patch queue
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
` (24 preceding siblings ...)
2019-02-12 13:15 ` [Qemu-devel] [PULL 00/24] target/hppa patch queue Peter Maydell
@ 2019-02-13 16:33 ` no-reply
25 siblings, 0 replies; 30+ messages in thread
From: no-reply @ 2019-02-13 16:33 UTC (permalink / raw
To: richard.henderson; +Cc: fam, qemu-devel, peter.maydell
Patchew URL: https://patchew.org/QEMU/20190212045721.28041-1-richard.henderson@linaro.org/
Hi,
This series seems to have some coding style problems. See output below for
more information:
Subject: [Qemu-devel] [PULL 00/24] target/hppa patch queue
Type: series
Message-id: 20190212045721.28041-1-richard.henderson@linaro.org
=== TEST SCRIPT BEGIN ===
#!/bin/bash
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
* [new tag] patchew/1550029560-30530-1-git-send-email-sandra@codesourcery.com -> patchew/1550029560-30530-1-git-send-email-sandra@codesourcery.com
* [new tag] patchew/20190211170136.18680-1-richard.henderson@linaro.org -> patchew/20190211170136.18680-1-richard.henderson@linaro.org
t [tag update] patchew/20190212025241.5330-1-stefanha@redhat.com -> patchew/20190212025241.5330-1-stefanha@redhat.com
* [new tag] patchew/20190212045721.28041-1-richard.henderson@linaro.org -> patchew/20190212045721.28041-1-richard.henderson@linaro.org
t [tag update] patchew/20190212145722.31891-1-philmd@redhat.com -> patchew/20190212145722.31891-1-philmd@redhat.com
Switched to a new branch 'test'
b5c5dfdaab hw/hppa: forward requests to CPU HPA
a48430e571 target/hppa: fix dcor instruction
b2d7de36d5 target/hppa: Fix addition '</<=' conditions
17311c79d0 target/hppa: Rearrange log conditions
ae9e01783f target/hppa: move GETPC to HELPER() functions
3b8707f153 target/hppa: Merge translate_one into hppa_tr_translate_insn
20fbaff776 target/hppa: Convert fp operate insns
4ca5b0d631 target/hppa: Convert fp fused multiply-add insns
d6841b65b3 target/hppa: Convert halt/reset insns
d9a029560f target/hppa: Convert fp indexed memory insns
55f466ba55 target/hppa: Convert offset memory insns
af0da59913 target/hppa: Convert arithmetic immediate insns
1df30dbecf target/hppa: Convert direct and indirect branches
758773e229 target/hppa: Convert shift, extract, deposit insns
612ad6b258 target/hppa: Convert conditional branches
d2cdb6e898 target/hppa: Convert fp multiply-add
ee9ae782f0 target/hppa: Convert indexed memory insns
0848256b5d target/hppa: Convert arithmetic/logical insns
76a314ee8a target/hppa: Convert memory management insns
0883ff944e target/hppa: Unify specializations of OR
7a5fb6d9b7 target/hppa: Convert remainder of system insns
1786cd8d4e target/hppa: Convert move to/from system registers
cd64b4ccf9 target/hppa: Begin using scripts/decodetree.py
568947bacd target/hppa: Use DisasContextBase.is_jmp
=== OUTPUT BEGIN ===
1/24 Checking commit 568947bacdff (target/hppa: Use DisasContextBase.is_jmp)
2/24 Checking commit cd64b4ccf907 (target/hppa: Begin using scripts/decodetree.py)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#31:
new file mode 100644
WARNING: Block comments use a trailing */ on a separate line
#80: FILE: target/hppa/translate.c:668:
+ it may be tail-called from a translate function. */
total: 0 errors, 2 warnings, 101 lines checked
Patch 2/24 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/24 Checking commit 1786cd8d4e2b (target/hppa: Convert move to/from system registers)
4/24 Checking commit 7a5fb6d9b7eb (target/hppa: Convert remainder of system insns)
5/24 Checking commit 0883ff944ef7 (target/hppa: Unify specializations of OR)
WARNING: Block comments use a leading /* on a separate line
#56: FILE: target/hppa/translate.c:2650:
+ /* These are QEMU extensions and are nops in the real architecture:
WARNING: Block comments use a leading /* on a separate line
#65: FILE: target/hppa/translate.c:2659:
+ /* No need to check for supervisor, as userland can only pause
WARNING: Block comments use * on subsequent lines
#66: FILE: target/hppa/translate.c:2660:
+ /* No need to check for supervisor, as userland can only pause
+ until the next timer interrupt. */
WARNING: Block comments use a trailing */ on a separate line
#66: FILE: target/hppa/translate.c:2660:
+ until the next timer interrupt. */
total: 0 errors, 4 warnings, 128 lines checked
Patch 5/24 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
6/24 Checking commit 76a314ee8ad5 (target/hppa: Convert memory management insns)
7/24 Checking commit 0848256b5d0b (target/hppa: Convert arithmetic/logical insns)
8/24 Checking commit ee9ae782f0e4 (target/hppa: Convert indexed memory insns)
WARNING: Block comments use a leading /* on a separate line
#59: FILE: target/hppa/translate.c:299:
+/* Convert the M:A bits within a memory insn to the tri-state value
WARNING: Block comments use * on subsequent lines
#60: FILE: target/hppa/translate.c:300:
+/* Convert the M:A bits within a memory insn to the tri-state value
+ we use for the final M. */
WARNING: Block comments use a trailing */ on a separate line
#60: FILE: target/hppa/translate.c:300:
+ we use for the final M. */
total: 0 errors, 3 warnings, 305 lines checked
Patch 8/24 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
9/24 Checking commit d2cdb6e8983d (target/hppa: Convert fp multiply-add)
10/24 Checking commit 612ad6b25869 (target/hppa: Convert conditional branches)
11/24 Checking commit 758773e22930 (target/hppa: Convert shift, extract, deposit insns)
12/24 Checking commit 1df30dbecfa7 (target/hppa: Convert direct and indirect branches)
13/24 Checking commit af0da59913e5 (target/hppa: Convert arithmetic immediate insns)
14/24 Checking commit 55f466ba5585 (target/hppa: Convert offset memory insns)
15/24 Checking commit d9a029560fc8 (target/hppa: Convert fp indexed memory insns)
16/24 Checking commit d6841b65b327 (target/hppa: Convert halt/reset insns)
17/24 Checking commit 4ca5b0d63107 (target/hppa: Convert fp fused multiply-add insns)
18/24 Checking commit 20fbaff77686 (target/hppa: Convert fp operate insns)
19/24 Checking commit 3b8707f153aa (target/hppa: Merge translate_one into hppa_tr_translate_insn)
20/24 Checking commit ae9e01783f8e (target/hppa: move GETPC to HELPER() functions)
21/24 Checking commit 17311c79d00f (target/hppa: Rearrange log conditions)
22/24 Checking commit b2d7de36d5ec (target/hppa: Fix addition '</<=' conditions)
ERROR: space prohibited between function name and open parenthesis '('
#25: FILE: target/hppa/translate.c:457:
+ assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
total: 1 errors, 0 warnings, 186 lines checked
Patch 22/24 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
23/24 Checking commit a48430e5710f (target/hppa: fix dcor instruction)
24/24 Checking commit b5c5dfdaab59 (hw/hppa: forward requests to CPU HPA)
=== OUTPUT END ===
Test command exited with code: 1
The full log is available at
http://patchew.org/logs/20190212045721.28041-1-richard.henderson@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [Qemu-devel] [PULL 00/24] target/hppa patch queue
2019-02-12 13:15 ` [Qemu-devel] [PULL 00/24] target/hppa patch queue Peter Maydell
@ 2019-02-13 18:40 ` Philippe Mathieu-Daudé
2019-02-14 10:04 ` Peter Maydell
0 siblings, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-02-13 18:40 UTC (permalink / raw
To: Peter Maydell, Richard Henderson; +Cc: QEMU Developers
Hi Peter,
On 2/12/19 2:15 PM, Peter Maydell wrote:
> On Tue, 12 Feb 2019 at 04:57, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> The following changes since commit 22c5f446514a2a4bb0dbe1fea26713da92fc85fa:
>>
>> Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190211' into staging (2019-02-11 17:04:57 +0000)
>>
>> are available in the Git repository at:
>>
>> https://github.com/rth7680/qemu.git tags/pull-hppa-20190211
>>
>> for you to fetch changes up to 23e76627deba013509b5f1a1e1c53e8e111145aa:
>>
>> hw/hppa: forward requests to CPU HPA (2019-02-11 20:49:06 -0800)
>>
>> ----------------------------------------------------------------
>> Convert to decodetree.
>> Fix signed overflow conditions.
>> Fix dcor.
>> Add CPU MIE to PCI address space.
>
> Hi -- clang compiles fail with:
>
> In file included from
> /home/petmay01/linaro/qemu-for-merges/target/hppa/translate.c:337:
> target/hppa/decode.inc.c:471:16: error: redefinition of typedef
> 'arg_be' is a C11 feature [-Werror,-Wtypedef-redefinition]
> typedef arg_be arg_be;
> ^
> target/hppa/decode.inc.c:9:3: note: previous definition is here
> } arg_be;
> ^
> target/hppa/decode.inc.c:473:16: error: redefinition of typedef
> 'arg_bl' is a C11 feature [-Werror,-Wtypedef-redefinition]
> typedef arg_bl arg_bl;
> ^
> target/hppa/decode.inc.c:15:3: note: previous definition is here
> } arg_bl;
> ^
What Clang version is that?
I can not reproduce using:
clang version 7.0.1 (Fedora 7.0.1-1.fc29)
>
> thanks
> -- PMM
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [Qemu-devel] [PULL 00/24] target/hppa patch queue
2019-02-13 18:40 ` Philippe Mathieu-Daudé
@ 2019-02-14 10:04 ` Peter Maydell
2019-02-14 11:32 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 30+ messages in thread
From: Peter Maydell @ 2019-02-14 10:04 UTC (permalink / raw
To: Philippe Mathieu-Daudé; +Cc: Richard Henderson, QEMU Developers
On Wed, 13 Feb 2019 at 18:40, Philippe Mathieu-Daudé <philmd@redhat.com> wrote:
> What Clang version is that?
>
> I can not reproduce using:
>
> clang version 7.0.1 (Fedora 7.0.1-1.fc29)
OSX: Apple LLVM version 10.0.0 (clang-1000.11.45.5)
and Ubuntu bionic: clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
thanks
-- PMM
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [Qemu-devel] [PULL 00/24] target/hppa patch queue
2019-02-14 10:04 ` Peter Maydell
@ 2019-02-14 11:32 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-02-14 11:32 UTC (permalink / raw
To: Peter Maydell; +Cc: Richard Henderson, QEMU Developers
Hi Peter,
On 2/14/19 11:04 AM, Peter Maydell wrote:
> On Wed, 13 Feb 2019 at 18:40, Philippe Mathieu-Daudé <philmd@redhat.com> wrote:
>> What Clang version is that?
>>
>> I can not reproduce using:
>>
>> clang version 7.0.1 (Fedora 7.0.1-1.fc29)
>
> OSX: Apple LLVM version 10.0.0 (clang-1000.11.45.5)> and Ubuntu bionic: clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
I can not reproduce on Bionic:
$ clang --version
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
./configure --host-cc=clang \
--cxx=clang++ \
--cc=clang \
--extra-cflags=-Werror=typedef-redefinition
Host C compiler clang
C++ compiler clang++
Objective-C compiler clang
QEMU_CFLAGS -I/usr/include/pixman-1 -I$(SRC_PATH)/dtc/libfdt
-Werror -pthread -I/usr/include/glib-2.0
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include -fPIE -DPIE -m64 -mcx16
-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings
-Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -std=gnu99
-Werror=typedef-redefinition -Wno-error=address-of-packed-member
-Wno-string-plus-int -Wno-initializer-overrides -Wexpansion-to-defined
-Wendif-labels -Wno-shift-negative-value -Wno-missing-include-dirs
-Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self
-Wignored-qualifiers -Wold-style-definition -Wtype-limits
-fstack-protector-strong -I/usr/include/p11-kit-1
-I/usr/include/libpng16 -I/usr/include/spice-server
-I/usr/include/spice-1 -I$(SRC_PATH)/capstone/include
[...]
$ make subdir-hppa-softmmu
[...]
$ hppa-softmmu/qemu-system-hppa --version
QEMU emulator version 3.1.50 (v3.1.0-1733-gcb82c5728c-dirty)
I don't have handy OSX setup except Travis, I'll see what I can do.
Regards,
Phil.
^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2019-02-14 11:32 UTC | newest]
Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-02-12 4:56 [Qemu-devel] [PULL 00/24] target/hppa patch queue Richard Henderson
2019-02-12 4:56 ` [Qemu-devel] [PULL 01/24] target/hppa: Use DisasContextBase.is_jmp Richard Henderson
2019-02-12 4:56 ` [Qemu-devel] [PULL 02/24] target/hppa: Begin using scripts/decodetree.py Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 03/24] target/hppa: Convert move to/from system registers Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 04/24] target/hppa: Convert remainder of system insns Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 05/24] target/hppa: Unify specializations of OR Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 06/24] target/hppa: Convert memory management insns Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 07/24] target/hppa: Convert arithmetic/logical insns Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 08/24] target/hppa: Convert indexed memory insns Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 09/24] target/hppa: Convert fp multiply-add Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 10/24] target/hppa: Convert conditional branches Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 11/24] target/hppa: Convert shift, extract, deposit insns Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 12/24] target/hppa: Convert direct and indirect branches Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 13/24] target/hppa: Convert arithmetic immediate insns Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 14/24] target/hppa: Convert offset memory insns Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 15/24] target/hppa: Convert fp indexed " Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 16/24] target/hppa: Convert halt/reset insns Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 17/24] target/hppa: Convert fp fused multiply-add insns Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 18/24] target/hppa: Convert fp operate insns Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 19/24] target/hppa: Merge translate_one into hppa_tr_translate_insn Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 20/24] target/hppa: move GETPC to HELPER() functions Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 21/24] target/hppa: Rearrange log conditions Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 22/24] target/hppa: Fix addition '</<=' conditions Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 23/24] target/hppa: fix dcor instruction Richard Henderson
2019-02-12 4:57 ` [Qemu-devel] [PULL 24/24] hw/hppa: forward requests to CPU HPA Richard Henderson
2019-02-12 13:15 ` [Qemu-devel] [PULL 00/24] target/hppa patch queue Peter Maydell
2019-02-13 18:40 ` Philippe Mathieu-Daudé
2019-02-14 10:04 ` Peter Maydell
2019-02-14 11:32 ` Philippe Mathieu-Daudé
2019-02-13 16:33 ` no-reply
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.