提交 e6d767b7 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/rth/tags/pull-pa-20170907' into staging

Conversion to TranslatorOps

# gpg: Signature made Thu 07 Sep 2017 19:42:48 BST
# gpg:                using RSA key 0x64DF38E8AF7E215F
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* remotes/rth/tags/pull-pa-20170907:
  target/hppa: Convert to TranslatorOps
  target/hppa: Convert to DisasContextBase
  target/hppa: Convert to DisasJumpType
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -24,10 +24,9 @@
#include "exec/exec-all.h"
#include "tcg-op.h"
#include "exec/cpu_ldst.h"
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
#include "exec/translator.h"
#include "trace-tcg.h"
#include "exec/log.h"
......@@ -39,7 +38,7 @@ typedef struct DisasCond {
} DisasCond;
typedef struct DisasContext {
struct TranslationBlock *tb;
DisasContextBase base;
CPUState *cs;
target_ulong iaoq_f;
......@@ -53,36 +52,25 @@ typedef struct DisasContext {
DisasCond null_cond;
TCGLabel *null_lab;
bool singlestep_enabled;
bool psw_n_nonzero;
} DisasContext;
/* Return values from translate_one, indicating the state of the TB.
Note that zero indicates that we are not exiting the TB. */
typedef enum {
NO_EXIT,
/* We have emitted one or more goto_tb. No fixup required. */
EXIT_GOTO_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. */
EXIT_IAQ_N_UPDATED,
/* 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 exiting the TB, but have neither emitted a goto_tb, nor
updated the iaq for the next instruction to be executed. */
EXIT_IAQ_N_STALE,
/* 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
/* We are ending the TB with a noreturn function call, e.g. longjmp.
No following code will be executed. */
EXIT_NORETURN,
} ExitStatus;
/* We are exiting the TB, but have neither emitted a goto_tb, nor
updated the iaq for the next instruction to be executed. */
#define DISAS_IAQ_N_STALE DISAS_TARGET_1
typedef struct DisasInsn {
uint32_t insn, mask;
ExitStatus (*trans)(DisasContext *ctx, uint32_t insn,
const struct DisasInsn *f);
DisasJumpType (*trans)(DisasContext *ctx, uint32_t insn,
const struct DisasInsn *f);
union {
void (*ttt)(TCGv, TCGv, TCGv);
void (*weww)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32);
......@@ -415,7 +403,7 @@ 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 ExitStatus nullify_end(DisasContext *ctx, ExitStatus status)
static DisasJumpType nullify_end(DisasContext *ctx, DisasJumpType status)
{
TCGLabel *null_lab = ctx->null_lab;
......@@ -441,9 +429,9 @@ static ExitStatus nullify_end(DisasContext *ctx, ExitStatus status)
ctx->null_cond = cond_make_n();
}
assert(status != EXIT_GOTO_TB && status != EXIT_IAQ_N_UPDATED);
if (status == EXIT_NORETURN) {
status = NO_EXIT;
assert(status != DISAS_NORETURN && status != DISAS_IAQ_N_UPDATED);
if (status == DISAS_NORETURN) {
status = DISAS_NEXT;
}
return status;
}
......@@ -469,16 +457,16 @@ static void gen_excp_1(int exception)
tcg_temp_free_i32(t);
}
static ExitStatus gen_excp(DisasContext *ctx, int exception)
static DisasJumpType 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 EXIT_NORETURN;
return DISAS_NORETURN;
}
static ExitStatus gen_illegal(DisasContext *ctx)
static DisasJumpType gen_illegal(DisasContext *ctx)
{
nullify_over(ctx);
return nullify_end(ctx, gen_excp(ctx, EXCP_SIGILL));
......@@ -487,7 +475,7 @@ static ExitStatus gen_illegal(DisasContext *ctx)
static bool use_goto_tb(DisasContext *ctx, target_ulong dest)
{
/* Suppress goto_tb in the case of single-steping and IO. */
if ((ctx->tb->cflags & CF_LAST_IO) || ctx->singlestep_enabled) {
if ((ctx->base.tb->cflags & CF_LAST_IO) || ctx->base.singlestep_enabled) {
return false;
}
return true;
......@@ -510,11 +498,11 @@ static void gen_goto_tb(DisasContext *ctx, int which,
tcg_gen_goto_tb(which);
tcg_gen_movi_tl(cpu_iaoq_f, f);
tcg_gen_movi_tl(cpu_iaoq_b, b);
tcg_gen_exit_tb((uintptr_t)ctx->tb + which);
tcg_gen_exit_tb((uintptr_t)ctx->base.tb + which);
} else {
copy_iaoq_entry(cpu_iaoq_f, f, cpu_iaoq_b);
copy_iaoq_entry(cpu_iaoq_b, b, ctx->iaoq_n_var);
if (ctx->singlestep_enabled) {
if (ctx->base.singlestep_enabled) {
gen_excp_1(EXCP_DEBUG);
} else {
tcg_gen_lookup_and_goto_ptr(cpu_iaoq_f);
......@@ -839,9 +827,9 @@ static TCGv do_sub_sv(DisasContext *ctx, TCGv res, TCGv in1, TCGv in2)
return sv;
}
static ExitStatus do_add(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
unsigned shift, bool is_l, bool is_tsv, bool is_tc,
bool is_c, unsigned cf)
static DisasJumpType do_add(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
unsigned shift, bool is_l, bool is_tsv, bool is_tc,
bool is_c, unsigned cf)
{
TCGv dest, cb, cb_msb, sv, tmp;
unsigned c = cf >> 1;
......@@ -908,11 +896,11 @@ static ExitStatus do_add(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
/* Install the new nullification. */
cond_free(&ctx->null_cond);
ctx->null_cond = cond;
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus do_sub(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
bool is_tsv, bool is_b, bool is_tc, unsigned cf)
static DisasJumpType do_sub(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
bool is_tsv, bool is_b, bool is_tc, unsigned cf)
{
TCGv dest, sv, cb, cb_msb, zero, tmp;
unsigned c = cf >> 1;
......@@ -974,11 +962,11 @@ static ExitStatus do_sub(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
/* Install the new nullification. */
cond_free(&ctx->null_cond);
ctx->null_cond = cond;
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus do_cmpclr(DisasContext *ctx, unsigned rt, TCGv in1,
TCGv in2, unsigned cf)
static DisasJumpType do_cmpclr(DisasContext *ctx, unsigned rt, TCGv in1,
TCGv in2, unsigned cf)
{
TCGv dest, sv;
DisasCond cond;
......@@ -1003,11 +991,11 @@ static ExitStatus do_cmpclr(DisasContext *ctx, unsigned rt, TCGv in1,
/* Install the new nullification. */
cond_free(&ctx->null_cond);
ctx->null_cond = cond;
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus do_log(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
unsigned cf, void (*fn)(TCGv, TCGv, TCGv))
static DisasJumpType do_log(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
unsigned cf, void (*fn)(TCGv, TCGv, TCGv))
{
TCGv dest = dest_gpr(ctx, rt);
......@@ -1020,12 +1008,12 @@ static ExitStatus do_log(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
if (cf) {
ctx->null_cond = do_log_cond(cf, dest);
}
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus do_unit(DisasContext *ctx, unsigned rt, TCGv in1,
TCGv in2, unsigned cf, bool is_tc,
void (*fn)(TCGv, TCGv, TCGv))
static DisasJumpType do_unit(DisasContext *ctx, unsigned rt, TCGv in1,
TCGv in2, unsigned cf, bool is_tc,
void (*fn)(TCGv, TCGv, TCGv))
{
TCGv dest;
DisasCond cond;
......@@ -1053,7 +1041,7 @@ static ExitStatus do_unit(DisasContext *ctx, unsigned rt, TCGv in1,
cond_free(&ctx->null_cond);
ctx->null_cond = cond;
}
return NO_EXIT;
return DISAS_NEXT;
}
/* Emit a memory load. The modify parameter should be
......@@ -1185,9 +1173,9 @@ static void do_store_64(DisasContext *ctx, TCGv_i64 src, unsigned rb,
#define do_store_tl do_store_32
#endif
static ExitStatus do_load(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_long disp,
int modify, TCGMemOp mop)
static DisasJumpType do_load(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_long disp,
int modify, TCGMemOp mop)
{
TCGv dest;
......@@ -1203,12 +1191,12 @@ static ExitStatus do_load(DisasContext *ctx, unsigned rt, unsigned rb,
do_load_tl(ctx, dest, rb, rx, scale, disp, modify, mop);
save_gpr(ctx, rt, dest);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_long disp,
int modify)
static DisasJumpType do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_long disp,
int modify)
{
TCGv_i32 tmp;
......@@ -1223,12 +1211,12 @@ static ExitStatus do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
gen_helper_loaded_fr0(cpu_env);
}
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_long disp,
int modify)
static DisasJumpType do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_long disp,
int modify)
{
TCGv_i64 tmp;
......@@ -1243,20 +1231,20 @@ static ExitStatus do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
gen_helper_loaded_fr0(cpu_env);
}
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_store(DisasContext *ctx, unsigned rt, unsigned rb,
target_long disp, int modify, TCGMemOp mop)
static DisasJumpType do_store(DisasContext *ctx, unsigned rt, unsigned rb,
target_long disp, int modify, TCGMemOp mop)
{
nullify_over(ctx);
do_store_tl(ctx, load_gpr(ctx, rt), rb, 0, 0, disp, modify, mop);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_long disp,
int modify)
static DisasJumpType do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_long disp,
int modify)
{
TCGv_i32 tmp;
......@@ -1266,12 +1254,12 @@ static ExitStatus do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
do_store_32(ctx, tmp, rb, rx, scale, disp, modify, MO_TEUL);
tcg_temp_free_i32(tmp);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_long disp,
int modify)
static DisasJumpType do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
unsigned rx, int scale, target_long disp,
int modify)
{
TCGv_i64 tmp;
......@@ -1281,11 +1269,11 @@ static ExitStatus do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
do_store_64(ctx, tmp, rb, rx, scale, disp, modify, MO_TEQ);
tcg_temp_free_i64(tmp);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
static DisasJumpType do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
{
TCGv_i32 tmp;
......@@ -1296,11 +1284,11 @@ static ExitStatus do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
save_frw_i32(rt, tmp);
tcg_temp_free_i32(tmp);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
static DisasJumpType do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
{
TCGv_i32 dst;
TCGv_i64 src;
......@@ -1314,11 +1302,11 @@ static ExitStatus 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, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
static DisasJumpType do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
{
TCGv_i64 tmp;
......@@ -1329,11 +1317,11 @@ static ExitStatus do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
save_frd(rt, tmp);
tcg_temp_free_i64(tmp);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
static DisasJumpType do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
{
TCGv_i32 src;
TCGv_i64 dst;
......@@ -1347,13 +1335,13 @@ static ExitStatus 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, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_fop_weww(DisasContext *ctx, unsigned rt,
unsigned ra, unsigned rb,
void (*func)(TCGv_i32, TCGv_env,
TCGv_i32, TCGv_i32))
static DisasJumpType 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;
......@@ -1366,13 +1354,13 @@ static ExitStatus 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, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus do_fop_dedd(DisasContext *ctx, unsigned rt,
unsigned ra, unsigned rb,
void (*func)(TCGv_i64, TCGv_env,
TCGv_i64, TCGv_i64))
static DisasJumpType 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;
......@@ -1385,13 +1373,13 @@ static ExitStatus 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, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
/* Emit an unconditional branch to a direct target, which may or may not
have already had nullification handled. */
static ExitStatus do_dbranch(DisasContext *ctx, target_ulong dest,
unsigned link, bool is_n)
static DisasJumpType do_dbranch(DisasContext *ctx, target_ulong dest,
unsigned link, bool is_n)
{
if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
if (link != 0) {
......@@ -1401,7 +1389,7 @@ static ExitStatus do_dbranch(DisasContext *ctx, target_ulong dest,
if (is_n) {
ctx->null_cond.c = TCG_COND_ALWAYS;
}
return NO_EXIT;
return DISAS_NEXT;
} else {
nullify_over(ctx);
......@@ -1417,18 +1405,18 @@ static ExitStatus do_dbranch(DisasContext *ctx, target_ulong dest,
gen_goto_tb(ctx, 0, ctx->iaoq_b, dest);
}
nullify_end(ctx, NO_EXIT);
nullify_end(ctx, DISAS_NEXT);
nullify_set(ctx, 0);
gen_goto_tb(ctx, 1, ctx->iaoq_b, ctx->iaoq_n);
return EXIT_GOTO_TB;
return DISAS_NORETURN;
}
}
/* Emit a conditional branch to a direct target. If the branch itself
is nullified, we should have already used nullify_over. */
static ExitStatus do_cbranch(DisasContext *ctx, target_long disp, bool is_n,
DisasCond *cond)
static DisasJumpType do_cbranch(DisasContext *ctx, target_long disp, bool is_n,
DisasCond *cond)
{
target_ulong dest = iaoq_dest(ctx, disp);
TCGLabel *taken = NULL;
......@@ -1480,16 +1468,16 @@ static ExitStatus do_cbranch(DisasContext *ctx, target_long disp, bool is_n,
if (ctx->null_lab) {
gen_set_label(ctx->null_lab);
ctx->null_lab = NULL;
return EXIT_IAQ_N_STALE;
return DISAS_IAQ_N_STALE;
} else {
return EXIT_GOTO_TB;
return DISAS_NORETURN;
}
}
/* Emit an unconditional branch to an indirect target. This handles
nullification of the branch itself. */
static ExitStatus do_ibranch(DisasContext *ctx, TCGv dest,
unsigned link, bool is_n)
static DisasJumpType do_ibranch(DisasContext *ctx, TCGv dest,
unsigned link, bool is_n)
{
TCGv a0, a1, next, tmp;
TCGCond c;
......@@ -1528,7 +1516,7 @@ static ExitStatus do_ibranch(DisasContext *ctx, TCGv dest,
tcg_gen_movi_tl(cpu_gr[link], ctx->iaoq_n);
}
tcg_gen_lookup_and_goto_ptr(cpu_iaoq_f);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
} else {
cond_prep(&ctx->null_cond);
c = ctx->null_cond.c;
......@@ -1560,7 +1548,7 @@ static ExitStatus do_ibranch(DisasContext *ctx, TCGv dest,
}
}
return NO_EXIT;
return DISAS_NEXT;
}
/* On Linux, page zero is normally marked execute only + gateway.
......@@ -1570,7 +1558,7 @@ static ExitStatus do_ibranch(DisasContext *ctx, TCGv dest,
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 ExitStatus do_page_zero(DisasContext *ctx)
static DisasJumpType 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
......@@ -1598,55 +1586,55 @@ static ExitStatus do_page_zero(DisasContext *ctx)
switch (ctx->iaoq_f) {
case 0x00: /* Null pointer call */
gen_excp_1(EXCP_SIGSEGV);
return EXIT_NORETURN;
return DISAS_NORETURN;
case 0xb0: /* LWS */
gen_excp_1(EXCP_SYSCALL_LWS);
return EXIT_NORETURN;
return DISAS_NORETURN;
case 0xe0: /* SET_THREAD_POINTER */
tcg_gen_mov_tl(cpu_cr27, cpu_gr[26]);
tcg_gen_mov_tl(cpu_iaoq_f, cpu_gr[31]);
tcg_gen_addi_tl(cpu_iaoq_b, cpu_iaoq_f, 4);
return EXIT_IAQ_N_UPDATED;
return DISAS_IAQ_N_UPDATED;
case 0x100: /* SYSCALL */
gen_excp_1(EXCP_SYSCALL);
return EXIT_NORETURN;
return DISAS_NORETURN;
default:
do_sigill:
gen_excp_1(EXCP_SIGILL);
return EXIT_NORETURN;
return DISAS_NORETURN;
}
}
static ExitStatus trans_nop(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_nop(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_break(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_break(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
nullify_over(ctx);
return nullify_end(ctx, gen_excp(ctx, EXCP_DEBUG));
}
static ExitStatus trans_sync(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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 NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_mfia(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_mfia(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
TCGv tmp = dest_gpr(ctx, rt);
......@@ -1654,11 +1642,11 @@ static ExitStatus trans_mfia(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, tmp);
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_mfsp(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_mfsp(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
TCGv tmp = dest_gpr(ctx, rt);
......@@ -1668,11 +1656,11 @@ static ExitStatus trans_mfsp(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, tmp);
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_mfctl(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_mfctl(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned ctl = extract32(insn, 21, 5);
......@@ -1708,11 +1696,11 @@ static ExitStatus trans_mfctl(DisasContext *ctx, uint32_t insn,
}
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_mtctl(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_mtctl(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rin = extract32(insn, 16, 5);
unsigned ctl = extract32(insn, 21, 5);
......@@ -1729,11 +1717,11 @@ static ExitStatus trans_mtctl(DisasContext *ctx, uint32_t insn,
}
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_mtsarcm(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_mtsarcm(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rin = extract32(insn, 16, 5);
TCGv tmp = tcg_temp_new();
......@@ -1744,11 +1732,11 @@ static ExitStatus trans_mtsarcm(DisasContext *ctx, uint32_t insn,
tcg_temp_free(tmp);
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_ldsid(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_ldsid(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
TCGv dest = dest_gpr(ctx, rt);
......@@ -1758,7 +1746,7 @@ static ExitStatus trans_ldsid(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, dest);
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static const DisasInsn table_system[] = {
......@@ -1774,8 +1762,8 @@ static const DisasInsn table_system[] = {
{ 0x000010a0u, 0xfc1f3fe0u, trans_ldsid },
};
static ExitStatus trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rx = extract32(insn, 16, 5);
......@@ -1788,11 +1776,11 @@ static ExitStatus trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rb, dest);
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_probe(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_probe(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned rb = extract32(insn, 21, 5);
......@@ -1809,7 +1797,7 @@ static ExitStatus trans_probe(DisasContext *ctx, uint32_t insn,
gen_helper_probe_r(dest, load_gpr(ctx, rb));
}
save_gpr(ctx, rt, dest);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static const DisasInsn table_mem_mgmt[] = {
......@@ -1830,8 +1818,8 @@ static const DisasInsn table_mem_mgmt[] = {
{ 0x04003180u, 0xfc003fa0u, trans_probe }, /* probei */
};
static ExitStatus trans_add(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_add(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
......@@ -1844,7 +1832,7 @@ static ExitStatus trans_add(DisasContext *ctx, uint32_t insn,
bool is_l = false;
bool is_tc = false;
bool is_tsv = false;
ExitStatus ret;
DisasJumpType ret;
switch (ext) {
case 0x6: /* ADD, SHLADD */
......@@ -1874,8 +1862,8 @@ static ExitStatus trans_add(DisasContext *ctx, uint32_t insn,
return nullify_end(ctx, ret);
}
static ExitStatus trans_sub(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_sub(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
......@@ -1886,7 +1874,7 @@ static ExitStatus trans_sub(DisasContext *ctx, uint32_t insn,
bool is_b = false;
bool is_tc = false;
bool is_tsv = false;
ExitStatus ret;
DisasJumpType ret;
switch (ext) {
case 0x10: /* SUB */
......@@ -1919,15 +1907,15 @@ static ExitStatus trans_sub(DisasContext *ctx, uint32_t insn,
return nullify_end(ctx, ret);
}
static ExitStatus trans_log(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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 tcg_r1, tcg_r2;
ExitStatus ret;
DisasJumpType ret;
if (cf) {
nullify_over(ctx);
......@@ -1939,8 +1927,8 @@ static ExitStatus trans_log(DisasContext *ctx, uint32_t insn,
}
/* OR r,0,t -> COPY (according to gas) */
static ExitStatus trans_copy(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_copy(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned r1 = extract32(insn, 16, 5);
unsigned rt = extract32(insn, 0, 5);
......@@ -1953,18 +1941,18 @@ static ExitStatus trans_copy(DisasContext *ctx, uint32_t insn,
save_gpr(ctx, rt, cpu_gr[r1]);
}
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_cmpclr(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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 tcg_r1, tcg_r2;
ExitStatus ret;
DisasJumpType ret;
if (cf) {
nullify_over(ctx);
......@@ -1975,15 +1963,15 @@ static ExitStatus trans_cmpclr(DisasContext *ctx, uint32_t insn,
return nullify_end(ctx, ret);
}
static ExitStatus trans_uxor(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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 tcg_r1, tcg_r2;
ExitStatus ret;
DisasJumpType ret;
if (cf) {
nullify_over(ctx);
......@@ -1994,8 +1982,8 @@ static ExitStatus trans_uxor(DisasContext *ctx, uint32_t insn,
return nullify_end(ctx, ret);
}
static ExitStatus trans_uaddcm(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_uaddcm(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
......@@ -2003,7 +1991,7 @@ static ExitStatus trans_uaddcm(DisasContext *ctx, uint32_t insn,
unsigned is_tc = extract32(insn, 6, 1);
unsigned rt = extract32(insn, 0, 5);
TCGv tcg_r1, tcg_r2, tmp;
ExitStatus ret;
DisasJumpType ret;
if (cf) {
nullify_over(ctx);
......@@ -2016,15 +2004,15 @@ static ExitStatus trans_uaddcm(DisasContext *ctx, uint32_t insn,
return nullify_end(ctx, ret);
}
static ExitStatus trans_dcor(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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 tmp;
ExitStatus ret;
DisasJumpType ret;
nullify_over(ctx);
......@@ -2041,8 +2029,8 @@ static ExitStatus trans_dcor(DisasContext *ctx, uint32_t insn,
return nullify_end(ctx, ret);
}
static ExitStatus trans_ds(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_ds(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned r2 = extract32(insn, 21, 5);
unsigned r1 = extract32(insn, 16, 5);
......@@ -2105,7 +2093,7 @@ static ExitStatus trans_ds(DisasContext *ctx, uint32_t insn,
tcg_temp_free(add2);
tcg_temp_free(dest);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static const DisasInsn table_arith_log[] = {
......@@ -2126,7 +2114,7 @@ static const DisasInsn table_arith_log[] = {
{ 0x08000200u, 0xfc000320u, trans_add }, /* shladd */
};
static ExitStatus trans_addi(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_addi(DisasContext *ctx, uint32_t insn)
{
target_long im = low_sextract(insn, 0, 11);
unsigned e1 = extract32(insn, 11, 1);
......@@ -2135,7 +2123,7 @@ static ExitStatus trans_addi(DisasContext *ctx, uint32_t insn)
unsigned r2 = extract32(insn, 21, 5);
unsigned o1 = extract32(insn, 26, 1);
TCGv tcg_im, tcg_r2;
ExitStatus ret;
DisasJumpType ret;
if (cf) {
nullify_over(ctx);
......@@ -2148,7 +2136,7 @@ static ExitStatus trans_addi(DisasContext *ctx, uint32_t insn)
return nullify_end(ctx, ret);
}
static ExitStatus trans_subi(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_subi(DisasContext *ctx, uint32_t insn)
{
target_long im = low_sextract(insn, 0, 11);
unsigned e1 = extract32(insn, 11, 1);
......@@ -2156,7 +2144,7 @@ static ExitStatus trans_subi(DisasContext *ctx, uint32_t insn)
unsigned rt = extract32(insn, 16, 5);
unsigned r2 = extract32(insn, 21, 5);
TCGv tcg_im, tcg_r2;
ExitStatus ret;
DisasJumpType ret;
if (cf) {
nullify_over(ctx);
......@@ -2169,14 +2157,14 @@ static ExitStatus trans_subi(DisasContext *ctx, uint32_t insn)
return nullify_end(ctx, ret);
}
static ExitStatus trans_cmpiclr(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_cmpiclr(DisasContext *ctx, uint32_t insn)
{
target_long 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 tcg_im, tcg_r2;
ExitStatus ret;
DisasJumpType ret;
if (cf) {
nullify_over(ctx);
......@@ -2189,8 +2177,8 @@ static ExitStatus trans_cmpiclr(DisasContext *ctx, uint32_t insn)
return nullify_end(ctx, ret);
}
static ExitStatus trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
......@@ -2204,8 +2192,8 @@ static ExitStatus trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
return do_load(ctx, rt, rb, 0, 0, disp, modify, mop);
}
static ExitStatus trans_ld_idx_x(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_ld_idx_x(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
......@@ -2218,8 +2206,8 @@ static ExitStatus trans_ld_idx_x(DisasContext *ctx, uint32_t insn,
return do_load(ctx, rt, rb, rx, u ? sz : 0, 0, m, mop);
}
static ExitStatus trans_st_idx_i(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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);
......@@ -2233,8 +2221,8 @@ static ExitStatus trans_st_idx_i(DisasContext *ctx, uint32_t insn,
return do_store(ctx, rr, rb, disp, modify, mop);
}
static ExitStatus trans_ldcw(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_ldcw(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
......@@ -2285,11 +2273,11 @@ static ExitStatus trans_ldcw(DisasContext *ctx, uint32_t insn,
}
save_gpr(ctx, rt, dest);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_stby(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_stby(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
target_long disp = low_sextract(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
......@@ -2321,7 +2309,7 @@ static ExitStatus trans_stby(DisasContext *ctx, uint32_t insn,
}
tcg_temp_free(addr);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static const DisasInsn table_index_mem[] = {
......@@ -2332,7 +2320,7 @@ static const DisasInsn table_index_mem[] = {
{ 0x0c001300u, 0xfc0013c0, trans_stby },
};
static ExitStatus trans_ldil(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_ldil(DisasContext *ctx, uint32_t insn)
{
unsigned rt = extract32(insn, 21, 5);
target_long i = assemble_21(insn);
......@@ -2342,10 +2330,10 @@ static ExitStatus trans_ldil(DisasContext *ctx, uint32_t insn)
save_gpr(ctx, rt, tcg_rt);
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_addil(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_addil(DisasContext *ctx, uint32_t insn)
{
unsigned rt = extract32(insn, 21, 5);
target_long i = assemble_21(insn);
......@@ -2356,10 +2344,10 @@ static ExitStatus trans_addil(DisasContext *ctx, uint32_t insn)
save_gpr(ctx, 1, tcg_r1);
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_ldo(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_ldo(DisasContext *ctx, uint32_t insn)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rt = extract32(insn, 16, 5);
......@@ -2376,11 +2364,11 @@ static ExitStatus trans_ldo(DisasContext *ctx, uint32_t insn)
save_gpr(ctx, rt, tcg_rt);
cond_free(&ctx->null_cond);
return NO_EXIT;
return DISAS_NEXT;
}
static ExitStatus trans_load(DisasContext *ctx, uint32_t insn,
bool is_mod, TCGMemOp mop)
static DisasJumpType trans_load(DisasContext *ctx, uint32_t insn,
bool is_mod, TCGMemOp mop)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rt = extract32(insn, 16, 5);
......@@ -2389,7 +2377,7 @@ static ExitStatus trans_load(DisasContext *ctx, uint32_t insn,
return do_load(ctx, rt, rb, 0, 0, i, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
}
static ExitStatus trans_load_w(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_load_w(DisasContext *ctx, uint32_t insn)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rt = extract32(insn, 16, 5);
......@@ -2410,7 +2398,7 @@ static ExitStatus trans_load_w(DisasContext *ctx, uint32_t insn)
}
}
static ExitStatus trans_fload_mod(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_fload_mod(DisasContext *ctx, uint32_t insn)
{
target_long i = assemble_16a(insn);
unsigned t1 = extract32(insn, 1, 1);
......@@ -2422,8 +2410,8 @@ static ExitStatus trans_fload_mod(DisasContext *ctx, uint32_t insn)
return do_floadw(ctx, t1 * 32 + t0, rb, 0, 0, i, (a ? -1 : 1));
}
static ExitStatus trans_store(DisasContext *ctx, uint32_t insn,
bool is_mod, TCGMemOp mop)
static DisasJumpType trans_store(DisasContext *ctx, uint32_t insn,
bool is_mod, TCGMemOp mop)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rt = extract32(insn, 16, 5);
......@@ -2432,7 +2420,7 @@ static ExitStatus trans_store(DisasContext *ctx, uint32_t insn,
return do_store(ctx, rt, rb, i, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
}
static ExitStatus trans_store_w(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_store_w(DisasContext *ctx, uint32_t insn)
{
unsigned rb = extract32(insn, 21, 5);
unsigned rt = extract32(insn, 16, 5);
......@@ -2452,7 +2440,7 @@ static ExitStatus trans_store_w(DisasContext *ctx, uint32_t insn)
}
}
static ExitStatus trans_fstore_mod(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_fstore_mod(DisasContext *ctx, uint32_t insn)
{
target_long i = assemble_16a(insn);
unsigned t1 = extract32(insn, 1, 1);
......@@ -2464,7 +2452,7 @@ static ExitStatus trans_fstore_mod(DisasContext *ctx, uint32_t insn)
return do_fstorew(ctx, t1 * 32 + t0, rb, 0, 0, i, (a ? -1 : 1));
}
static ExitStatus trans_copr_w(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_copr_w(DisasContext *ctx, uint32_t insn)
{
unsigned t0 = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
......@@ -2499,7 +2487,7 @@ static ExitStatus trans_copr_w(DisasContext *ctx, uint32_t insn)
return gen_illegal(ctx);
}
static ExitStatus trans_copr_dw(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_copr_dw(DisasContext *ctx, uint32_t insn)
{
unsigned rt = extract32(insn, 0, 5);
unsigned m = extract32(insn, 5, 1);
......@@ -2533,8 +2521,8 @@ static ExitStatus trans_copr_dw(DisasContext *ctx, uint32_t insn)
}
}
static ExitStatus trans_cmpb(DisasContext *ctx, uint32_t insn,
bool is_true, bool is_imm, bool is_dw)
static DisasJumpType trans_cmpb(DisasContext *ctx, uint32_t insn,
bool is_true, bool is_imm, bool is_dw)
{
target_long disp = assemble_12(insn) * 4;
unsigned n = extract32(insn, 1, 1);
......@@ -2565,8 +2553,8 @@ static ExitStatus trans_cmpb(DisasContext *ctx, uint32_t insn,
return do_cbranch(ctx, disp, n, &cond);
}
static ExitStatus trans_addb(DisasContext *ctx, uint32_t insn,
bool is_true, bool is_imm)
static DisasJumpType trans_addb(DisasContext *ctx, uint32_t insn,
bool is_true, bool is_imm)
{
target_long disp = assemble_12(insn) * 4;
unsigned n = extract32(insn, 1, 1);
......@@ -2607,7 +2595,7 @@ static ExitStatus trans_addb(DisasContext *ctx, uint32_t insn,
return do_cbranch(ctx, disp, n, &cond);
}
static ExitStatus trans_bb(DisasContext *ctx, uint32_t insn)
static DisasJumpType trans_bb(DisasContext *ctx, uint32_t insn)
{
target_long disp = assemble_12(insn) * 4;
unsigned n = extract32(insn, 1, 1);
......@@ -2633,7 +2621,7 @@ static ExitStatus trans_bb(DisasContext *ctx, uint32_t insn)
return do_cbranch(ctx, disp, n, &cond);
}
static ExitStatus trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
static DisasJumpType trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
{
target_long disp = assemble_12(insn) * 4;
unsigned n = extract32(insn, 1, 1);
......@@ -2658,8 +2646,8 @@ static ExitStatus trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
return do_cbranch(ctx, disp, n, &cond);
}
static ExitStatus trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned c = extract32(insn, 13, 3);
......@@ -2700,11 +2688,11 @@ static ExitStatus trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned cpos = extract32(insn, 5, 5);
......@@ -2741,11 +2729,11 @@ static ExitStatus trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_extrw_sar(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_extrw_sar(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned clen = extract32(insn, 0, 5);
unsigned is_se = extract32(insn, 10, 1);
......@@ -2780,11 +2768,11 @@ static ExitStatus trans_extrw_sar(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_extrw_imm(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_extrw_imm(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned clen = extract32(insn, 0, 5);
unsigned pos = extract32(insn, 5, 5);
......@@ -2814,7 +2802,7 @@ static ExitStatus trans_extrw_imm(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static const DisasInsn table_sh_ex[] = {
......@@ -2824,8 +2812,8 @@ static const DisasInsn table_sh_ex[] = {
{ 0xd0001800u, 0xfc001800u, trans_extrw_imm },
};
static ExitStatus trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned clen = extract32(insn, 0, 5);
unsigned cpos = extract32(insn, 5, 5);
......@@ -2865,11 +2853,11 @@ static ExitStatus trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_depw_imm(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_depw_imm(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned clen = extract32(insn, 0, 5);
unsigned cpos = extract32(insn, 5, 5);
......@@ -2902,11 +2890,11 @@ static ExitStatus trans_depw_imm(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_depw_sar(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_depw_sar(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned clen = extract32(insn, 0, 5);
unsigned nz = extract32(insn, 10, 1);
......@@ -2954,7 +2942,7 @@ static ExitStatus trans_depw_sar(DisasContext *ctx, uint32_t insn,
if (c) {
ctx->null_cond = do_sed_cond(c, dest);
}
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static const DisasInsn table_depw[] = {
......@@ -2963,7 +2951,7 @@ static const DisasInsn table_depw[] = {
{ 0xd4001800u, 0xfc001800u, trans_depw_imm_c },
};
static ExitStatus trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
static DisasJumpType trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
{
unsigned n = extract32(insn, 1, 1);
unsigned b = extract32(insn, 21, 5);
......@@ -2988,8 +2976,8 @@ static ExitStatus trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
}
}
static ExitStatus trans_bl(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_bl(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
unsigned link = extract32(insn, 21, 5);
......@@ -2998,8 +2986,8 @@ static ExitStatus trans_bl(DisasContext *ctx, uint32_t insn,
return do_dbranch(ctx, iaoq_dest(ctx, disp), link, n);
}
static ExitStatus trans_bl_long(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_bl_long(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
target_long disp = assemble_22(insn);
......@@ -3007,8 +2995,8 @@ static ExitStatus trans_bl_long(DisasContext *ctx, uint32_t insn,
return do_dbranch(ctx, iaoq_dest(ctx, disp), 2, n);
}
static ExitStatus trans_blr(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_blr(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
unsigned rx = extract32(insn, 16, 5);
......@@ -3020,8 +3008,8 @@ static ExitStatus trans_blr(DisasContext *ctx, uint32_t insn,
return do_ibranch(ctx, tmp, link, n);
}
static ExitStatus trans_bv(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_bv(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
unsigned rx = extract32(insn, 16, 5);
......@@ -3038,8 +3026,8 @@ static ExitStatus trans_bv(DisasContext *ctx, uint32_t insn,
return do_ibranch(ctx, dest, 0, n);
}
static ExitStatus trans_bve(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_bve(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned n = extract32(insn, 1, 1);
unsigned rb = extract32(insn, 21, 5);
......@@ -3056,64 +3044,64 @@ static const DisasInsn table_branch[] = {
{ 0xe800d000u, 0xfc00dffcu, trans_bve },
};
static ExitStatus trans_fop_wew_0c(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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);
}
static ExitStatus trans_fop_wew_0e(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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);
}
static ExitStatus trans_fop_ded(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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);
}
static ExitStatus trans_fop_wed_0c(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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);
}
static ExitStatus trans_fop_wed_0e(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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);
}
static ExitStatus trans_fop_dew_0c(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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);
}
static ExitStatus trans_fop_dew_0e(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType 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);
}
static ExitStatus trans_fop_weww_0c(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_fop_weww_0c(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned rb = extract32(insn, 16, 5);
......@@ -3121,8 +3109,8 @@ static ExitStatus trans_fop_weww_0c(DisasContext *ctx, uint32_t insn,
return do_fop_weww(ctx, rt, ra, rb, di->f.weww);
}
static ExitStatus trans_fop_weww_0e(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_fop_weww_0e(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = assemble_rt64(insn);
unsigned rb = assemble_rb64(insn);
......@@ -3130,8 +3118,8 @@ static ExitStatus trans_fop_weww_0e(DisasContext *ctx, uint32_t insn,
return do_fop_weww(ctx, rt, ra, rb, di->f.weww);
}
static ExitStatus trans_fop_dedd(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_fop_dedd(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned rb = extract32(insn, 16, 5);
......@@ -3179,8 +3167,8 @@ static void gen_fnegabs_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
tcg_gen_ori_i64(dst, src, INT64_MIN);
}
static ExitStatus do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
unsigned y, unsigned c)
static DisasJumpType do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
unsigned y, unsigned c)
{
TCGv_i32 ta, tb, tc, ty;
......@@ -3198,11 +3186,11 @@ static ExitStatus do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
tcg_temp_free_i32(ty);
tcg_temp_free_i32(tc);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_fcmp_s_0c(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_fcmp_s_0c(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned c = extract32(insn, 0, 5);
unsigned y = extract32(insn, 13, 3);
......@@ -3211,8 +3199,8 @@ static ExitStatus trans_fcmp_s_0c(DisasContext *ctx, uint32_t insn,
return do_fcmp_s(ctx, ra, rb, y, c);
}
static ExitStatus trans_fcmp_s_0e(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_fcmp_s_0e(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned c = extract32(insn, 0, 5);
unsigned y = extract32(insn, 13, 3);
......@@ -3221,8 +3209,8 @@ static ExitStatus trans_fcmp_s_0e(DisasContext *ctx, uint32_t insn,
return do_fcmp_s(ctx, ra, rb, y, c);
}
static ExitStatus trans_fcmp_d(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_fcmp_d(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned c = extract32(insn, 0, 5);
unsigned y = extract32(insn, 13, 3);
......@@ -3245,11 +3233,11 @@ static ExitStatus trans_fcmp_d(DisasContext *ctx, uint32_t insn,
tcg_temp_free_i32(ty);
tcg_temp_free_i32(tc);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_ftest_t(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_ftest_t(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned y = extract32(insn, 13, 3);
unsigned cbit = (y ^ 1) - 1;
......@@ -3263,11 +3251,11 @@ static ExitStatus 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, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_ftest_q(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_ftest_q(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned c = extract32(insn, 0, 5);
int mask;
......@@ -3317,11 +3305,11 @@ static ExitStatus trans_ftest_q(DisasContext *ctx, uint32_t insn,
ctx->null_cond = cond_make_0(TCG_COND_EQ, t);
}
done:
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_xmpyu(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_xmpyu(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned rb = assemble_rb64(insn);
......@@ -3337,7 +3325,7 @@ static ExitStatus trans_xmpyu(DisasContext *ctx, uint32_t insn,
tcg_temp_free_i64(a);
tcg_temp_free_i64(b);
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
#define FOP_DED trans_fop_ded, .f.ded
......@@ -3512,7 +3500,8 @@ static inline int fmpyadd_s_reg(unsigned r)
return (r & 16) * 2 + 16 + (r & 15);
}
static ExitStatus trans_fmpyadd(DisasContext *ctx, uint32_t insn, bool is_sub)
static DisasJumpType trans_fmpyadd(DisasContext *ctx,
uint32_t insn, bool is_sub)
{
unsigned tm = extract32(insn, 0, 5);
unsigned f = extract32(insn, 5, 1);
......@@ -3540,11 +3529,11 @@ static ExitStatus trans_fmpyadd(DisasContext *ctx, uint32_t insn, bool is_sub)
is_sub ? gen_helper_fsub_d : gen_helper_fadd_d);
}
return nullify_end(ctx, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = assemble_rt64(insn);
unsigned neg = extract32(insn, 5, 1);
......@@ -3568,11 +3557,11 @@ static ExitStatus 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, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static ExitStatus trans_fmpyfadd_d(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
static DisasJumpType trans_fmpyfadd_d(DisasContext *ctx, uint32_t insn,
const DisasInsn *di)
{
unsigned rt = extract32(insn, 0, 5);
unsigned neg = extract32(insn, 5, 1);
......@@ -3596,7 +3585,7 @@ static ExitStatus 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, NO_EXIT);
return nullify_end(ctx, DISAS_NEXT);
}
static const DisasInsn table_fp_fused[] = {
......@@ -3604,8 +3593,8 @@ static const DisasInsn table_fp_fused[] = {
{ 0xb8000800u, 0xfc0019c0u, trans_fmpyfadd_d }
};
static ExitStatus translate_table_int(DisasContext *ctx, uint32_t insn,
const DisasInsn table[], size_t n)
static DisasJumpType translate_table_int(DisasContext *ctx, uint32_t insn,
const DisasInsn table[], size_t n)
{
size_t i;
for (i = 0; i < n; ++i) {
......@@ -3619,7 +3608,7 @@ static ExitStatus translate_table_int(DisasContext *ctx, uint32_t insn,
#define translate_table(ctx, insn, table) \
translate_table_int(ctx, insn, table, ARRAY_SIZE(table))
static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
{
uint32_t opc = extract32(insn, 26, 6);
......@@ -3740,188 +3729,201 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
return gen_illegal(ctx);
}
void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
static int hppa_tr_init_disas_context(DisasContextBase *dcbase,
CPUState *cs, int max_insns)
{
CPUHPPAState *env = cs->env_ptr;
DisasContext ctx;
ExitStatus ret;
int num_insns, max_insns, i;
DisasContext *ctx = container_of(dcbase, DisasContext, base);
TranslationBlock *tb = ctx->base.tb;
int i, bound;
ctx.tb = tb;
ctx.cs = cs;
ctx.iaoq_f = tb->pc;
ctx.iaoq_b = tb->cs_base;
ctx.singlestep_enabled = cs->singlestep_enabled;
ctx->cs = cs;
ctx->iaoq_f = tb->pc;
ctx->iaoq_b = tb->cs_base;
ctx->iaoq_n = -1;
TCGV_UNUSED(ctx->iaoq_n_var);
ctx.ntemps = 0;
for (i = 0; i < ARRAY_SIZE(ctx.temps); ++i) {
TCGV_UNUSED(ctx.temps[i]);
ctx->ntemps = 0;
for (i = 0; i < ARRAY_SIZE(ctx->temps); ++i) {
TCGV_UNUSED(ctx->temps[i]);
}
/* Compute the maximum number of insns to execute, as bounded by
(1) icount, (2) single-stepping, (3) branch delay slots, or
(4) the number of insns remaining on the current page. */
max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns == 0) {
max_insns = CF_COUNT_MASK;
}
if (ctx.singlestep_enabled || singlestep) {
max_insns = 1;
} else if (max_insns > TCG_MAX_INSNS) {
max_insns = TCG_MAX_INSNS;
}
bound = -(tb->pc | TARGET_PAGE_MASK) / 4;
return MIN(max_insns, bound);
}
num_insns = 0;
gen_tb_start(tb);
static void hppa_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
/* Seed the nullification status from PSW[N], as shown in TB->FLAGS. */
ctx.null_cond = cond_make_f();
ctx.psw_n_nonzero = false;
if (tb->flags & 1) {
ctx.null_cond.c = TCG_COND_ALWAYS;
ctx.psw_n_nonzero = true;
ctx->null_cond = cond_make_f();
ctx->psw_n_nonzero = false;
if (ctx->base.tb->flags & 1) {
ctx->null_cond.c = TCG_COND_ALWAYS;
ctx->psw_n_nonzero = true;
}
ctx.null_lab = NULL;
ctx->null_lab = NULL;
}
do {
tcg_gen_insn_start(ctx.iaoq_f, ctx.iaoq_b);
num_insns++;
static void hppa_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
if (unlikely(cpu_breakpoint_test(cs, ctx.iaoq_f, BP_ANY))) {
ret = gen_excp(&ctx, EXCP_DEBUG);
break;
}
if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
gen_io_start();
}
tcg_gen_insn_start(ctx->iaoq_f, ctx->iaoq_b);
}
static bool hppa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
const CPUBreakpoint *bp)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
if (ctx.iaoq_f < TARGET_PAGE_SIZE) {
ret = do_page_zero(&ctx);
assert(ret != NO_EXIT);
ctx->base.is_jmp = gen_excp(ctx, EXCP_DEBUG);
ctx->base.pc_next = ctx->iaoq_f + 4;
return true;
}
static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
CPUHPPAState *env = cs->env_ptr;
DisasJumpType ret;
int i, n;
/* Execute one insn. */
if (ctx->iaoq_f < TARGET_PAGE_SIZE) {
ret = do_page_zero(ctx);
assert(ret != DISAS_NEXT);
} else {
/* Always fetch the insn, even if nullified, so that we check
the page permissions for execute. */
uint32_t insn = cpu_ldl_code(env, ctx->iaoq_f);
/* Set up the IA queue for the next insn.
This will be overwritten by a branch. */
if (ctx->iaoq_b == -1) {
ctx->iaoq_n = -1;
ctx->iaoq_n_var = get_temp(ctx);
tcg_gen_addi_tl(ctx->iaoq_n_var, cpu_iaoq_b, 4);
} else {
/* Always fetch the insn, even if nullified, so that we check
the page permissions for execute. */
uint32_t insn = cpu_ldl_code(env, ctx.iaoq_f);
/* Set up the IA queue for the next insn.
This will be overwritten by a branch. */
if (ctx.iaoq_b == -1) {
ctx.iaoq_n = -1;
ctx.iaoq_n_var = get_temp(&ctx);
tcg_gen_addi_tl(ctx.iaoq_n_var, cpu_iaoq_b, 4);
} else {
ctx.iaoq_n = ctx.iaoq_b + 4;
TCGV_UNUSED(ctx.iaoq_n_var);
}
if (unlikely(ctx.null_cond.c == TCG_COND_ALWAYS)) {
ctx.null_cond.c = TCG_COND_NEVER;
ret = NO_EXIT;
} else {
ret = translate_one(&ctx, insn);
assert(ctx.null_lab == NULL);
}
ctx->iaoq_n = ctx->iaoq_b + 4;
TCGV_UNUSED(ctx->iaoq_n_var);
}
for (i = 0; i < ctx.ntemps; ++i) {
tcg_temp_free(ctx.temps[i]);
TCGV_UNUSED(ctx.temps[i]);
}
ctx.ntemps = 0;
/* If we see non-linear instructions, exhaust instruction count,
or run out of buffer space, stop generation. */
/* ??? The non-linear instruction restriction is purely due to
the debugging dump. Otherwise we *could* follow unconditional
branches within the same page. */
if (ret == NO_EXIT
&& (ctx.iaoq_b != ctx.iaoq_f + 4
|| num_insns >= max_insns
|| tcg_op_buf_full())) {
if (ctx.null_cond.c == TCG_COND_NEVER
|| 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 = EXIT_GOTO_TB;
} else {
ret = EXIT_IAQ_N_STALE;
}
if (unlikely(ctx->null_cond.c == TCG_COND_ALWAYS)) {
ctx->null_cond.c = TCG_COND_NEVER;
ret = DISAS_NEXT;
} else {
ret = translate_one(ctx, insn);
assert(ctx->null_lab == NULL);
}
}
ctx.iaoq_f = ctx.iaoq_b;
ctx.iaoq_b = ctx.iaoq_n;
if (ret == EXIT_NORETURN
|| ret == EXIT_GOTO_TB
|| ret == EXIT_IAQ_N_UPDATED) {
break;
}
if (ctx.iaoq_f == -1) {
tcg_gen_mov_tl(cpu_iaoq_f, cpu_iaoq_b);
copy_iaoq_entry(cpu_iaoq_b, ctx.iaoq_n, ctx.iaoq_n_var);
nullify_save(&ctx);
ret = EXIT_IAQ_N_UPDATED;
break;
}
if (ctx.iaoq_b == -1) {
tcg_gen_mov_tl(cpu_iaoq_b, ctx.iaoq_n_var);
}
} while (ret == NO_EXIT);
/* Free any temporaries allocated. */
for (i = 0, n = ctx->ntemps; i < n; ++i) {
tcg_temp_free(ctx->temps[i]);
TCGV_UNUSED(ctx->temps[i]);
}
ctx->ntemps = 0;
if (tb->cflags & CF_LAST_IO) {
gen_io_end();
/* Advance the insn queue. */
/* ??? The non-linear instruction restriction is purely due to
the debugging dump. Otherwise we *could* follow unconditional
branches within the same page. */
if (ret == DISAS_NEXT && ctx->iaoq_b != ctx->iaoq_f + 4) {
if (ctx->null_cond.c == TCG_COND_NEVER
|| 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;
} else {
ret = DISAS_IAQ_N_STALE;
}
}
ctx->iaoq_f = ctx->iaoq_b;
ctx->iaoq_b = ctx->iaoq_n;
ctx->base.is_jmp = ret;
if (ret == DISAS_NORETURN || ret == DISAS_IAQ_N_UPDATED) {
return;
}
if (ctx->iaoq_f == -1) {
tcg_gen_mov_tl(cpu_iaoq_f, cpu_iaoq_b);
copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
nullify_save(ctx);
ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
} else if (ctx->iaoq_b == -1) {
tcg_gen_mov_tl(cpu_iaoq_b, ctx->iaoq_n_var);
}
}
switch (ret) {
case EXIT_GOTO_TB:
case EXIT_NORETURN:
static void hppa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
switch (ctx->base.is_jmp) {
case DISAS_NORETURN:
break;
case EXIT_IAQ_N_STALE:
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);
case DISAS_TOO_MANY:
case DISAS_IAQ_N_STALE:
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);
/* FALLTHRU */
case EXIT_IAQ_N_UPDATED:
if (ctx.singlestep_enabled) {
case DISAS_IAQ_N_UPDATED:
if (ctx->base.singlestep_enabled) {
gen_excp_1(EXCP_DEBUG);
} else {
tcg_gen_lookup_and_goto_ptr(cpu_iaoq_f);
}
break;
default:
abort();
g_assert_not_reached();
}
gen_tb_end(tb, num_insns);
/* We don't actually use this during normal translation,
but we should interact with the generic main loop. */
ctx->base.pc_next = ctx->base.tb->pc + 4 * ctx->base.num_insns;
}
tb->size = num_insns * 4;
tb->icount = num_insns;
static void hppa_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
{
TranslationBlock *tb = dcbase->tb;
#ifdef DEBUG_DISAS
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
&& qemu_log_in_addr_range(tb->pc)) {
qemu_log_lock();
switch (tb->pc) {
case 0x00:
qemu_log("IN:\n0x00000000: (null)\n\n");
break;
case 0xb0:
qemu_log("IN:\n0x000000b0: light-weight-syscall\n\n");
break;
case 0xe0:
qemu_log("IN:\n0x000000e0: set-thread-pointer-syscall\n\n");
break;
case 0x100:
qemu_log("IN:\n0x00000100: syscall\n\n");
break;
default:
qemu_log("IN: %s\n", lookup_symbol(tb->pc));
log_target_disas(cs, tb->pc, tb->size, 1);
qemu_log("\n");
break;
}
qemu_log_unlock();
switch (tb->pc) {
case 0x00:
qemu_log("IN:\n0x00000000: (null)\n");
break;
case 0xb0:
qemu_log("IN:\n0x000000b0: light-weight-syscall\n");
break;
case 0xe0:
qemu_log("IN:\n0x000000e0: set-thread-pointer-syscall\n");
break;
case 0x100:
qemu_log("IN:\n0x00000100: syscall\n");
break;
default:
qemu_log("IN: %s\n", lookup_symbol(tb->pc));
log_target_disas(cs, tb->pc, tb->size, 1);
break;
}
#endif
}
static const TranslatorOps hppa_tr_ops = {
.init_disas_context = hppa_tr_init_disas_context,
.tb_start = hppa_tr_tb_start,
.insn_start = hppa_tr_insn_start,
.breakpoint_check = hppa_tr_breakpoint_check,
.translate_insn = hppa_tr_translate_insn,
.tb_stop = hppa_tr_tb_stop,
.disas_log = hppa_tr_disas_log,
};
void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
{
DisasContext ctx;
translator_loop(&hppa_tr_ops, &ctx.base, cs, tb);
}
void restore_state_to_opc(CPUHPPAState *env, TranslationBlock *tb,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册