/*
* PowerPC emulation for qemu: main translation routines.
- *
+ *
* Copyright (c) 2003-2007 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
#include "exec-all.h"
#include "disas.h"
+/* Include definitions for instructions classes and implementations flags */
//#define DO_SINGLE_STEP
//#define PPC_DEBUG_DISAS
+//#define DEBUG_MEMORY_ACCESSES
//#define DO_PPC_STATISTICS
+/*****************************************************************************/
+/* Code translation helpers */
#if defined(USE_DIRECT_JUMP)
#define TBPARAM(x)
#else
GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
-static inline void gen_op_store_T0_fpscri(int n, uint8_t param)
+static inline void gen_op_store_T0_fpscri (int n, uint8_t param)
{
gen_op_set_T0(param);
gen_op_store_T0_fpscr(n);
int sf_mode;
#endif
int fpu_enabled;
-#if defined(TARGET_PPCSPE)
+#if defined(TARGET_PPCEMB)
int spe_enabled;
#endif
ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
uint64_t type;
/* handler */
void (*handler)(DisasContext *ctx);
-#if defined(DO_PPC_STATISTICS)
+#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
const unsigned char *oname;
+#endif
+#if defined(DO_PPC_STATISTICS)
uint64_t count;
#endif
};
gen_op_update_nip(nip);
}
-#define RET_EXCP(ctx, excp, error) \
+#define GEN_EXCP(ctx, excp, error) \
do { \
- if ((ctx)->exception == EXCP_NONE) { \
+ if ((ctx)->exception == POWERPC_EXCP_NONE) { \
gen_update_nip(ctx, (ctx)->nip); \
} \
gen_op_raise_exception_err((excp), (error)); \
ctx->exception = (excp); \
} while (0)
-#define RET_INVAL(ctx) \
-RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
+#define GEN_EXCP_INVAL(ctx) \
+GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
+
+#define GEN_EXCP_PRIVOPC(ctx) \
+GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
-#define RET_PRIVOPC(ctx) \
-RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
+#define GEN_EXCP_PRIVREG(ctx) \
+GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
-#define RET_PRIVREG(ctx) \
-RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
+#define GEN_EXCP_NO_FP(ctx) \
+GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
+
+#define GEN_EXCP_NO_AP(ctx) \
+GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
/* Stop translation */
-static inline void RET_STOP (DisasContext *ctx)
+static inline void GEN_STOP (DisasContext *ctx)
{
gen_update_nip(ctx, ctx->nip);
- ctx->exception = EXCP_MTMSR;
+ ctx->exception = POWERPC_EXCP_STOP;
}
/* No need to update nip here, as execution flow will change */
-static inline void RET_CHG_FLOW (DisasContext *ctx)
+static inline void GEN_SYNC (DisasContext *ctx)
{
- ctx->exception = EXCP_MTMSR;
+ ctx->exception = POWERPC_EXCP_SYNC;
}
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
const unsigned char *oname;
} opcode_t;
+/*****************************************************************************/
/*** Instruction decoding ***/
#define EXTRACT_HELPER(name, shift, nb) \
static inline uint32_t name (uint32_t opcode) \
return ret;
}
+/*****************************************************************************/
+/* PowerPC Instructions types definitions */
+enum {
+ PPC_NONE = 0x0000000000000000ULL,
+ /* integer operations instructions */
+ /* flow control instructions */
+ /* virtual memory instructions */
+ /* ld/st with reservation instructions */
+ /* cache control instructions */
+ /* spr/msr access instructions */
+ PPC_INSNS_BASE = 0x0000000000000001ULL,
+#define PPC_INTEGER PPC_INSNS_BASE
+#define PPC_FLOW PPC_INSNS_BASE
+#define PPC_MEM PPC_INSNS_BASE
+#define PPC_RES PPC_INSNS_BASE
+#define PPC_CACHE PPC_INSNS_BASE
+#define PPC_MISC PPC_INSNS_BASE
+ /* Optional floating point instructions */
+ PPC_FLOAT = 0x0000000000000002ULL,
+ PPC_FLOAT_FSQRT = 0x0000000000000004ULL,
+ PPC_FLOAT_FRES = 0x0000000000000008ULL,
+ PPC_FLOAT_FRSQRTE = 0x0000000000000010ULL,
+ PPC_FLOAT_FSEL = 0x0000000000000020ULL,
+ PPC_FLOAT_STFIWX = 0x0000000000000040ULL,
+ /* external control instructions */
+ PPC_EXTERN = 0x0000000000000080ULL,
+ /* segment register access instructions */
+ PPC_SEGMENT = 0x0000000000000100ULL,
+ /* Optional cache control instruction */
+ PPC_CACHE_DCBA = 0x0000000000000200ULL,
+ /* Optional memory control instructions */
+ PPC_MEM_TLBIA = 0x0000000000000400ULL,
+ PPC_MEM_TLBIE = 0x0000000000000800ULL,
+ PPC_MEM_TLBSYNC = 0x0000000000001000ULL,
+ /* eieio & sync */
+ PPC_MEM_SYNC = 0x0000000000002000ULL,
+ /* PowerPC 6xx TLB management instructions */
+ PPC_6xx_TLB = 0x0000000000004000ULL,
+ /* Altivec support */
+ PPC_ALTIVEC = 0x0000000000008000ULL,
+ /* Time base mftb instruction */
+ PPC_MFTB = 0x0000000000010000ULL,
+ /* Embedded PowerPC dedicated instructions */
+ PPC_EMB_COMMON = 0x0000000000020000ULL,
+ /* PowerPC 40x exception model */
+ PPC_40x_EXCP = 0x0000000000040000ULL,
+ /* PowerPC 40x TLB management instructions */
+ PPC_40x_TLB = 0x0000000000080000ULL,
+ /* PowerPC 405 Mac instructions */
+ PPC_405_MAC = 0x0000000000100000ULL,
+ /* PowerPC 440 specific instructions */
+ PPC_440_SPEC = 0x0000000000200000ULL,
+ /* Power-to-PowerPC bridge (601) */
+ PPC_POWER_BR = 0x0000000000400000ULL,
+ /* PowerPC 602 specific */
+ PPC_602_SPEC = 0x0000000000800000ULL,
+ /* Deprecated instructions */
+ /* Original POWER instruction set */
+ PPC_POWER = 0x0000000001000000ULL,
+ /* POWER2 instruction set extension */
+ PPC_POWER2 = 0x0000000002000000ULL,
+ /* Power RTC support */
+ PPC_POWER_RTC = 0x0000000004000000ULL,
+ /* 64 bits PowerPC instructions */
+ /* 64 bits PowerPC instruction set */
+ PPC_64B = 0x0000000008000000ULL,
+ /* 64 bits hypervisor extensions */
+ PPC_64H = 0x0000000010000000ULL,
+ /* 64 bits PowerPC "bridge" features */
+ PPC_64_BRIDGE = 0x0000000020000000ULL,
+ /* BookE (embedded) PowerPC specification */
+ PPC_BOOKE = 0x0000000040000000ULL,
+ /* eieio */
+ PPC_MEM_EIEIO = 0x0000000080000000ULL,
+ /* e500 vector instructions */
+ PPC_E500_VECTOR = 0x0000000100000000ULL,
+ /* PowerPC 4xx dedicated instructions */
+ PPC_4xx_COMMON = 0x0000000200000000ULL,
+ /* PowerPC 2.03 specification extensions */
+ PPC_203 = 0x0000000400000000ULL,
+ /* PowerPC 2.03 SPE extension */
+ PPC_SPE = 0x0000000800000000ULL,
+ /* PowerPC 2.03 SPE floating-point extension */
+ PPC_SPEFPU = 0x0000001000000000ULL,
+ /* SLB management */
+ PPC_SLBI = 0x0000002000000000ULL,
+ /* PowerPC 40x ibct instructions */
+ PPC_40x_ICBT = 0x0000004000000000ULL,
+ /* PowerPC 74xx TLB management instructions */
+ PPC_74xx_TLB = 0x0000008000000000ULL,
+ /* More BookE (embedded) instructions... */
+ PPC_BOOKE_EXT = 0x0000010000000000ULL,
+ /* rfmci is not implemented in all BookE PowerPC */
+ PPC_RFMCI = 0x0000020000000000ULL,
+ /* user-mode DCR access, implemented in PowerPC 460 */
+ PPC_DCRUX = 0x0000040000000000ULL,
+ /* New floating-point extensions (PowerPC 2.0x) */
+ PPC_FLOAT_EXT = 0x0000080000000000ULL,
+ /* New wait instruction (PowerPC 2.0x) */
+ PPC_WAIT = 0x0000100000000000ULL,
+};
+
+/*****************************************************************************/
+/* PowerPC instructions table */
#if HOST_LONG_BITS == 64
#define OPC_ALIGN 8
#else
/* Invalid instruction */
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
{
- RET_INVAL(ctx);
+ GEN_EXCP_INVAL(ctx);
}
static opc_handler_t invalid_handler = {
else
#endif
gen_op_check_addc();
+ } else {
+ gen_op_clear_xer_ca();
}
gen_op_store_T0_gpr(rD(ctx->opcode));
gen_set_Rc0(ctx);
#if defined(TARGET_PPC64)
/* mulhd mulhd. */
-GEN_INT_ARITHN (mulhd, 0x1F, 0x09, 0x02, PPC_INTEGER);
+GEN_INT_ARITHN (mulhd, 0x1F, 0x09, 0x02, PPC_64B);
/* mulhdu mulhdu. */
-GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_INTEGER);
+GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
/* mulld mulld. mulldo mulldo. */
-GEN_INT_ARITH2 (mulld, 0x1F, 0x09, 0x07, PPC_INTEGER);
+GEN_INT_ARITH2 (mulld, 0x1F, 0x09, 0x07, PPC_64B);
/* divd divd. divdo divdo. */
-GEN_INT_ARITH2 (divd, 0x1F, 0x09, 0x0F, PPC_INTEGER);
+GEN_INT_ARITH2 (divd, 0x1F, 0x09, 0x0F, PPC_64B);
/* divdu divdu. divduo divduo. */
-GEN_INT_ARITH2 (divdu, 0x1F, 0x09, 0x0E, PPC_INTEGER);
+GEN_INT_ARITH2 (divdu, 0x1F, 0x09, 0x0E, PPC_64B);
#endif
/*** Integer comparison ***/
{ \
gen_op_load_gpr_T0(rA(ctx->opcode)); \
gen_op_load_gpr_T1(rB(ctx->opcode)); \
- if (ctx->sf_mode) \
+ if (ctx->sf_mode && (ctx->opcode & 0x00200000)) \
gen_op_##name##_64(); \
else \
gen_op_##name(); \
{
gen_op_load_gpr_T0(rA(ctx->opcode));
#if defined(TARGET_PPC64)
- if (ctx->sf_mode)
+ if (ctx->sf_mode && (ctx->opcode & 0x00200000))
gen_op_cmpi_64(SIMM(ctx->opcode));
else
#endif
{
gen_op_load_gpr_T0(rA(ctx->opcode));
#if defined(TARGET_PPC64)
- if (ctx->sf_mode)
+ if (ctx->sf_mode && (ctx->opcode & 0x00200000))
gen_op_cmpli_64(UIMM(ctx->opcode));
else
#endif
} else if (unlikely(Rc(ctx->opcode) != 0)) {
gen_op_load_gpr_T0(rs);
gen_set_Rc0(ctx);
+#if defined(TARGET_PPC64)
+ } else {
+ switch (rs) {
+ case 1:
+ /* Set process priority to low */
+ gen_op_store_pri(2);
+ break;
+ case 6:
+ /* Set process priority to medium-low */
+ gen_op_store_pri(3);
+ break;
+ case 2:
+ /* Set process priority to normal */
+ gen_op_store_pri(4);
+ break;
+ default:
+ /* nop */
+ break;
+ }
+#endif
}
}
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
{
uint32_t mb, me, sh;
-
+
sh = SH(ctx->opcode);
mb = MB(ctx->opcode);
me = ME(ctx->opcode);
gen_##name(ctx, 1, 1); \
}
+static inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
+{
+ if (mask >> 32)
+ gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
+ else
+ gen_op_andi_T0(mask);
+}
+
+static inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
+{
+ if (mask >> 32)
+ gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
+ else
+ gen_op_andi_T1(mask);
+}
+
static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me,
uint32_t sh)
{
}
if (likely(mb == 0)) {
if (likely(me == 63)) {
- gen_op_rotli32_T0(sh);
+ gen_op_rotli64_T0(sh);
goto do_store;
} else if (likely(me == (63 - sh))) {
gen_op_sli_T0(sh);
}
} else if (likely(me == 63)) {
if (likely(sh == (64 - mb))) {
- gen_op_srli_T0(mb);
+ gen_op_srli_T0_64(mb);
goto do_store;
}
}
gen_op_rotli64_T0(sh);
do_mask:
- gen_op_andi_T0(MASK(mb, me));
+ gen_andi_T0_64(ctx, MASK(mb, me));
do_store:
gen_op_store_T0_gpr(rA(ctx->opcode));
if (unlikely(Rc(ctx->opcode) != 0))
{
uint32_t sh, mb;
- sh = SH(ctx->opcode) | (1 << shn);
- mb = (MB(ctx->opcode) << 1) | mbn;
+ sh = SH(ctx->opcode) | (shn << 5);
+ mb = MB(ctx->opcode) | (mbn << 5);
gen_rldinm(ctx, mb, 63, sh);
}
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
{
uint32_t sh, me;
- sh = SH(ctx->opcode) | (1 << shn);
- me = (MB(ctx->opcode) << 1) | men;
+ sh = SH(ctx->opcode) | (shn << 5);
+ me = MB(ctx->opcode) | (men << 5);
gen_rldinm(ctx, 0, me, sh);
}
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
{
uint32_t sh, mb;
- sh = SH(ctx->opcode) | (1 << shn);
- mb = (MB(ctx->opcode) << 1) | mbn;
+ sh = SH(ctx->opcode) | (shn << 5);
+ mb = MB(ctx->opcode) | (mbn << 5);
gen_rldinm(ctx, mb, 63 - sh, sh);
}
GEN_PPC64_R4(rldic, 0x1E, 0x04);
gen_op_load_gpr_T1(rB(ctx->opcode));
gen_op_rotl64_T0_T1();
if (unlikely(mb != 0 || me != 63)) {
- gen_op_andi_T0(MASK(mb, me));
+ gen_andi_T0_64(ctx, MASK(mb, me));
}
gen_op_store_T0_gpr(rA(ctx->opcode));
if (unlikely(Rc(ctx->opcode) != 0))
{
uint32_t mb;
- mb = (MB(ctx->opcode) << 1) | mbn;
+ mb = MB(ctx->opcode) | (mbn << 5);
gen_rldnm(ctx, mb, 63);
}
-GEN_PPC64_R2(rldcl, 0x1E, 0x08)
+GEN_PPC64_R2(rldcl, 0x1E, 0x08);
/* rldcr - rldcr. */
static inline void gen_rldcr (DisasContext *ctx, int men)
{
uint32_t me;
- me = (MB(ctx->opcode) << 1) | men;
+ me = MB(ctx->opcode) | (men << 5);
gen_rldnm(ctx, 0, me);
}
-GEN_PPC64_R2(rldcr, 0x1E, 0x09)
+GEN_PPC64_R2(rldcr, 0x1E, 0x09);
/* rldimi - rldimi. */
static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
{
uint64_t mask;
uint32_t sh, mb;
- sh = SH(ctx->opcode) | (1 << shn);
- mb = (MB(ctx->opcode) << 1) | mbn;
+ sh = SH(ctx->opcode) | (shn << 5);
+ mb = MB(ctx->opcode) | (mbn << 5);
if (likely(sh == 0)) {
if (likely(mb == 0)) {
gen_op_load_gpr_T0(rS(ctx->opcode));
}
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_load_gpr_T1(rA(ctx->opcode));
- gen_op_rotli64_T0(SH(ctx->opcode));
+ gen_op_rotli64_T0(sh);
do_mask:
mask = MASK(mb, 63 - sh);
- gen_op_andi_T0(mask);
- gen_op_andi_T1(~mask);
+ gen_andi_T0_64(ctx, mask);
+ gen_andi_T1_64(ctx, ~mask);
gen_op_or();
do_store:
gen_op_store_T0_gpr(rA(ctx->opcode));
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx);
}
-GEN_PPC64_R4(rldimi, 0x1E, 0x06)
+GEN_PPC64_R4(rldimi, 0x1E, 0x06);
#endif
/*** Integer shift ***/
#endif
/*** Floating-Point arithmetic ***/
-#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat) \
-GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \
+#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, type) \
+GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
gen_op_reset_scrfx(); \
gen_op_set_Rc1(); \
}
-#define GEN_FLOAT_ACB(name, op2) \
-_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0); \
-_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
+#define GEN_FLOAT_ACB(name, op2, type) \
+_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, type); \
+_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, type);
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat) \
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
gen_op_reset_scrfx(); \
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
gen_op_reset_scrfx(); \
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0); \
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
-#define GEN_FLOAT_B(name, op2, op3) \
-GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \
+#define GEN_FLOAT_B(name, op2, op3, type) \
+GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
gen_op_reset_scrfx(); \
gen_op_set_Rc1(); \
}
-#define GEN_FLOAT_BS(name, op1, op2) \
-GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \
+#define GEN_FLOAT_BS(name, op1, op2, type) \
+GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
gen_op_reset_scrfx(); \
/* fmul - fmuls */
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
-/* fres */ /* XXX: not in 601 */
-GEN_FLOAT_BS(res, 0x3B, 0x18);
+/* fre */
+GEN_FLOAT_BS(re, 0x3F, 0x18, PPC_FLOAT_EXT);
-/* frsqrte */ /* XXX: not in 601 */
-GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
+/* fres */
+GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
-/* fsel */ /* XXX: not in 601 */
-_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0);
+/* frsqrte */
+GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, PPC_FLOAT_FRSQRTE);
+
+/* fsel */
+_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, PPC_FLOAT_FSEL);
/* fsub - fsubs */
GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
/* Optional: */
/* fsqrt */
-GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
+GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
{
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
gen_op_reset_scrfx();
gen_op_set_Rc1();
}
-GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
+GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
{
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
gen_op_reset_scrfx();
/*** Floating-Point multiply-and-add ***/
/* fmadd - fmadds */
-GEN_FLOAT_ACB(madd, 0x1D);
+GEN_FLOAT_ACB(madd, 0x1D, PPC_FLOAT);
/* fmsub - fmsubs */
-GEN_FLOAT_ACB(msub, 0x1C);
+GEN_FLOAT_ACB(msub, 0x1C, PPC_FLOAT);
/* fnmadd - fnmadds */
-GEN_FLOAT_ACB(nmadd, 0x1F);
+GEN_FLOAT_ACB(nmadd, 0x1F, PPC_FLOAT);
/* fnmsub - fnmsubs */
-GEN_FLOAT_ACB(nmsub, 0x1E);
+GEN_FLOAT_ACB(nmsub, 0x1E, PPC_FLOAT);
/*** Floating-Point round & convert ***/
/* fctiw */
-GEN_FLOAT_B(ctiw, 0x0E, 0x00);
+GEN_FLOAT_B(ctiw, 0x0E, 0x00, PPC_FLOAT);
/* fctiwz */
-GEN_FLOAT_B(ctiwz, 0x0F, 0x00);
+GEN_FLOAT_B(ctiwz, 0x0F, 0x00, PPC_FLOAT);
/* frsp */
-GEN_FLOAT_B(rsp, 0x0C, 0x00);
+GEN_FLOAT_B(rsp, 0x0C, 0x00, PPC_FLOAT);
#if defined(TARGET_PPC64)
/* fcfid */
-GEN_FLOAT_B(cfid, 0x0E, 0x1A);
+GEN_FLOAT_B(cfid, 0x0E, 0x1A, PPC_64B);
/* fctid */
-GEN_FLOAT_B(ctid, 0x0E, 0x19);
+GEN_FLOAT_B(ctid, 0x0E, 0x19, PPC_64B);
/* fctidz */
-GEN_FLOAT_B(ctidz, 0x0F, 0x19);
+GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
#endif
+/* frin */
+GEN_FLOAT_B(rin, 0x08, 0x0C, PPC_FLOAT_EXT);
+/* friz */
+GEN_FLOAT_B(riz, 0x08, 0x0D, PPC_FLOAT_EXT);
+/* frip */
+GEN_FLOAT_B(rip, 0x08, 0x0E, PPC_FLOAT_EXT);
+/* frim */
+GEN_FLOAT_B(rim, 0x08, 0x0F, PPC_FLOAT_EXT);
+
/*** Floating-Point compare ***/
/* fcmpo */
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
{
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
gen_op_reset_scrfx();
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
{
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
gen_op_reset_scrfx();
/*** Floating-point move ***/
/* fabs */
-GEN_FLOAT_B(abs, 0x08, 0x08);
+GEN_FLOAT_B(abs, 0x08, 0x08, PPC_FLOAT);
/* fmr - fmr. */
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
{
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
gen_op_reset_scrfx();
}
/* fnabs */
-GEN_FLOAT_B(nabs, 0x08, 0x04);
+GEN_FLOAT_B(nabs, 0x08, 0x04, PPC_FLOAT);
/* fneg */
-GEN_FLOAT_B(neg, 0x08, 0x01);
+GEN_FLOAT_B(neg, 0x08, 0x01, PPC_FLOAT);
/*** Floating-Point status & ctrl register ***/
/* mcrfs */
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
{
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
gen_op_load_fpscr_T0(crfS(ctx->opcode));
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
{
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
gen_op_load_fpscr();
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
{
uint8_t crb;
-
+
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
crb = crbD(ctx->opcode) >> 2;
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
{
uint8_t crb;
-
+
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
crb = crbD(ctx->opcode) >> 2;
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
{
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
gen_op_load_fpr_FT0(rB(ctx->opcode));
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
{
if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
+ GEN_EXCP_NO_FP(ctx);
return;
}
gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
/*** Addressing modes ***/
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
-static inline void gen_addr_imm_index (DisasContext *ctx)
+static inline void gen_addr_imm_index (DisasContext *ctx, int maskl)
{
target_long simm = SIMM(ctx->opcode);
+ if (maskl)
+ simm &= ~0x03;
if (rA(ctx->opcode) == 0) {
gen_set_T0(simm);
} else {
if (likely(simm != 0))
gen_op_addi(simm);
}
+#ifdef DEBUG_MEMORY_ACCESSES
+ gen_op_print_mem_EA();
+#endif
}
static inline void gen_addr_reg_index (DisasContext *ctx)
gen_op_load_gpr_T1(rB(ctx->opcode));
gen_op_add();
}
+#ifdef DEBUG_MEMORY_ACCESSES
+ gen_op_print_mem_EA();
+#endif
}
static inline void gen_addr_register (DisasContext *ctx)
} else {
gen_op_load_gpr_T0(rA(ctx->opcode));
}
+#ifdef DEBUG_MEMORY_ACCESSES
+ gen_op_print_mem_EA();
+#endif
}
/*** Integer load ***/
#define GEN_LD(width, opc, type) \
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
- gen_addr_imm_index(ctx); \
+ gen_addr_imm_index(ctx, 0); \
op_ldst(l##width); \
gen_op_store_T1_gpr(rD(ctx->opcode)); \
}
{ \
if (unlikely(rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode))) { \
- RET_INVAL(ctx); \
+ GEN_EXCP_INVAL(ctx); \
return; \
} \
- gen_addr_imm_index(ctx); \
+ if (type == PPC_64B) \
+ gen_addr_imm_index(ctx, 1); \
+ else \
+ gen_addr_imm_index(ctx, 0); \
op_ldst(l##width); \
gen_op_store_T1_gpr(rD(ctx->opcode)); \
gen_op_store_T0_gpr(rA(ctx->opcode)); \
{ \
if (unlikely(rA(ctx->opcode) == 0 || \
rA(ctx->opcode) == rD(ctx->opcode))) { \
- RET_INVAL(ctx); \
+ GEN_EXCP_INVAL(ctx); \
return; \
} \
gen_addr_reg_index(ctx); \
if (Rc(ctx->opcode)) {
if (unlikely(rA(ctx->opcode) == 0 ||
rA(ctx->opcode) == rD(ctx->opcode))) {
- RET_INVAL(ctx);
+ GEN_EXCP_INVAL(ctx);
return;
}
}
- gen_addr_imm_index(ctx);
+ gen_addr_imm_index(ctx, 1);
if (ctx->opcode & 0x02) {
/* lwa (lwau is undefined) */
op_ldst(lwa);
#define GEN_ST(width, opc, type) \
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
- gen_addr_imm_index(ctx); \
+ gen_addr_imm_index(ctx, 0); \
gen_op_load_gpr_T1(rS(ctx->opcode)); \
op_ldst(st##width); \
}
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
if (unlikely(rA(ctx->opcode) == 0)) { \
- RET_INVAL(ctx); \
+ GEN_EXCP_INVAL(ctx); \
return; \
} \
- gen_addr_imm_index(ctx); \
+ if (type == PPC_64B) \
+ gen_addr_imm_index(ctx, 1); \
+ else \
+ gen_addr_imm_index(ctx, 0); \
gen_op_load_gpr_T1(rS(ctx->opcode)); \
op_ldst(st##width); \
gen_op_store_T0_gpr(rA(ctx->opcode)); \
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
{ \
if (unlikely(rA(ctx->opcode) == 0)) { \
- RET_INVAL(ctx); \
+ GEN_EXCP_INVAL(ctx); \
return; \
} \
gen_addr_reg_index(ctx); \
{
if (Rc(ctx->opcode)) {
if (unlikely(rA(ctx->opcode) == 0)) {
- RET_INVAL(ctx);
+ GEN_EXCP_INVAL(ctx);
return;
}
}
- gen_addr_imm_index(ctx);
+ gen_addr_imm_index(ctx, 1);
gen_op_load_gpr_T1(rS(ctx->opcode));
op_ldst(std);
if (Rc(ctx->opcode))
{
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_imm_index(ctx);
+ gen_addr_imm_index(ctx, 0);
op_ldstm(lmw, rD(ctx->opcode));
}
{
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_imm_index(ctx);
+ gen_addr_imm_index(ctx, 0);
op_ldstm(stmw, rS(ctx->opcode));
}
if (unlikely(((start + nr) > 32 &&
start <= ra && (start + nr - 32) > ra) ||
((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
- RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
+ GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
return;
}
/* NIP cannot be restored if the memory exception comes from an helper */
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
{
/* NIP cannot be restored if the memory exception comes from an helper */
- gen_update_nip(ctx, ctx->nip - 4);
+ gen_update_nip(ctx, ctx->nip - 4);
gen_addr_reg_index(ctx);
gen_op_load_xer_bc();
op_ldsts(stsw, rS(ctx->opcode));
/*** Memory synchronisation ***/
/* eieio */
-GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
+GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
{
}
/* isync */
-GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
+GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
{
+ GEN_STOP(ctx);
}
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
#endif
/* ldarx */
-GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_RES)
+GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
{
gen_addr_reg_index(ctx);
op_ldarx();
}
/* stdcx. */
-GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_RES)
+GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
{
gen_addr_reg_index(ctx);
gen_op_load_gpr_T1(rS(ctx->opcode));
#endif /* defined(TARGET_PPC64) */
/* sync */
-GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC)
+GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03BFF801, PPC_MEM_SYNC)
+{
+}
+
+/* wait */
+GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
{
+ /* Stop translation, as the CPU is supposed to sleep from now */
+ /* XXX: TODO: handle this idle CPU case */
+ GEN_STOP(ctx);
}
/*** Floating-point load ***/
-#define GEN_LDF(width, opc) \
-GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
+#define GEN_LDF(width, opc, type) \
+GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
- gen_addr_imm_index(ctx); \
+ gen_addr_imm_index(ctx, 0); \
op_ldst(l##width); \
gen_op_store_FT0_fpr(rD(ctx->opcode)); \
}
-#define GEN_LDUF(width, opc) \
-GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
+#define GEN_LDUF(width, opc, type) \
+GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
if (unlikely(rA(ctx->opcode) == 0)) { \
- RET_INVAL(ctx); \
+ GEN_EXCP_INVAL(ctx); \
return; \
} \
- gen_addr_imm_index(ctx); \
+ gen_addr_imm_index(ctx, 0); \
op_ldst(l##width); \
gen_op_store_FT0_fpr(rD(ctx->opcode)); \
gen_op_store_T0_gpr(rA(ctx->opcode)); \
}
-#define GEN_LDUXF(width, opc) \
-GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
+#define GEN_LDUXF(width, opc, type) \
+GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
if (unlikely(rA(ctx->opcode) == 0)) { \
- RET_INVAL(ctx); \
+ GEN_EXCP_INVAL(ctx); \
return; \
} \
gen_addr_reg_index(ctx); \
gen_op_store_T0_gpr(rA(ctx->opcode)); \
}
-#define GEN_LDXF(width, opc2, opc3) \
-GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
+#define GEN_LDXF(width, opc2, opc3, type) \
+GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
gen_addr_reg_index(ctx); \
gen_op_store_FT0_fpr(rD(ctx->opcode)); \
}
-#define GEN_LDFS(width, op) \
+#define GEN_LDFS(width, op, type) \
OP_LD_TABLE(width); \
-GEN_LDF(width, op | 0x20); \
-GEN_LDUF(width, op | 0x21); \
-GEN_LDUXF(width, op | 0x01); \
-GEN_LDXF(width, 0x17, op | 0x00)
+GEN_LDF(width, op | 0x20, type); \
+GEN_LDUF(width, op | 0x21, type); \
+GEN_LDUXF(width, op | 0x01, type); \
+GEN_LDXF(width, 0x17, op | 0x00, type)
/* lfd lfdu lfdux lfdx */
-GEN_LDFS(fd, 0x12);
+GEN_LDFS(fd, 0x12, PPC_FLOAT);
/* lfs lfsu lfsux lfsx */
-GEN_LDFS(fs, 0x10);
+GEN_LDFS(fs, 0x10, PPC_FLOAT);
/*** Floating-point store ***/
-#define GEN_STF(width, opc) \
-GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
+#define GEN_STF(width, opc, type) \
+GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
- gen_addr_imm_index(ctx); \
+ gen_addr_imm_index(ctx, 0); \
gen_op_load_fpr_FT0(rS(ctx->opcode)); \
op_ldst(st##width); \
}
-#define GEN_STUF(width, opc) \
-GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
+#define GEN_STUF(width, opc, type) \
+GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
if (unlikely(rA(ctx->opcode) == 0)) { \
- RET_INVAL(ctx); \
+ GEN_EXCP_INVAL(ctx); \
return; \
} \
- gen_addr_imm_index(ctx); \
+ gen_addr_imm_index(ctx, 0); \
gen_op_load_fpr_FT0(rS(ctx->opcode)); \
op_ldst(st##width); \
gen_op_store_T0_gpr(rA(ctx->opcode)); \
}
-#define GEN_STUXF(width, opc) \
-GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
+#define GEN_STUXF(width, opc, type) \
+GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
if (unlikely(rA(ctx->opcode) == 0)) { \
- RET_INVAL(ctx); \
+ GEN_EXCP_INVAL(ctx); \
return; \
} \
gen_addr_reg_index(ctx); \
gen_op_store_T0_gpr(rA(ctx->opcode)); \
}
-#define GEN_STXF(width, opc2, opc3) \
-GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
+#define GEN_STXF(width, opc2, opc3, type) \
+GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
{ \
if (unlikely(!ctx->fpu_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_FP, 0); \
+ GEN_EXCP_NO_FP(ctx); \
return; \
} \
gen_addr_reg_index(ctx); \
op_ldst(st##width); \
}
-#define GEN_STFS(width, op) \
+#define GEN_STFS(width, op, type) \
OP_ST_TABLE(width); \
-GEN_STF(width, op | 0x20); \
-GEN_STUF(width, op | 0x21); \
-GEN_STUXF(width, op | 0x01); \
-GEN_STXF(width, 0x17, op | 0x00)
+GEN_STF(width, op | 0x20, type); \
+GEN_STUF(width, op | 0x21, type); \
+GEN_STUXF(width, op | 0x01, type); \
+GEN_STXF(width, 0x17, op | 0x00, type)
/* stfd stfdu stfdux stfdx */
-GEN_STFS(fd, 0x16);
+GEN_STFS(fd, 0x16, PPC_FLOAT);
/* stfs stfsu stfsux stfsx */
-GEN_STFS(fs, 0x14);
+GEN_STFS(fs, 0x14, PPC_FLOAT);
/* Optional: */
/* stfiwx */
-GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- RET_EXCP(ctx, EXCP_NO_FP, 0);
- return;
- }
- gen_addr_reg_index(ctx);
- /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
- RET_INVAL(ctx);
-}
+OP_ST_TABLE(fiwx);
+GEN_STXF(fiwx, 0x17, 0x1E, PPC_FLOAT_STFIWX);
/*** Branch ***/
-
-static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
+static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)
{
TranslationBlock *tb;
tb = ctx->tb;
}
}
+static inline void gen_setlr (DisasContext *ctx, target_ulong nip)
+{
+#if defined(TARGET_PPC64)
+ if (ctx->sf_mode != 0 && (nip >> 32))
+ gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
+ else
+#endif
+ gen_op_setlr(ctx->nip);
+}
+
/* b ba bl bla */
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
{
target = ctx->nip + li - 4;
else
target = li;
- if (LK(ctx->opcode)) {
#if defined(TARGET_PPC64)
- if (ctx->sf_mode)
- gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
- else
+ if (!ctx->sf_mode)
+ target = (uint32_t)target;
#endif
- gen_op_setlr(ctx->nip);
- }
+ if (LK(ctx->opcode))
+ gen_setlr(ctx, ctx->nip);
gen_goto_tb(ctx, 0, target);
- ctx->exception = EXCP_BRANCH;
+ ctx->exception = POWERPC_EXCP_BRANCH;
}
#define BCOND_IM 0
#define BCOND_LR 1
#define BCOND_CTR 2
-static inline void gen_bcond(DisasContext *ctx, int type)
+static inline void gen_bcond (DisasContext *ctx, int type)
{
target_ulong target = 0;
target_ulong li;
} else {
target = li;
}
+#if defined(TARGET_PPC64)
+ if (!ctx->sf_mode)
+ target = (uint32_t)target;
+#endif
break;
case BCOND_CTR:
gen_op_movl_T1_ctr();
gen_op_movl_T1_lr();
break;
}
- if (LK(ctx->opcode)) {
-#if defined(TARGET_PPC64)
- if (ctx->sf_mode)
- gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
- else
-#endif
- gen_op_setlr(ctx->nip);
- }
+ if (LK(ctx->opcode))
+ gen_setlr(ctx, ctx->nip);
if (bo & 0x10) {
/* No CR condition */
switch (bo & 0x6) {
else
#endif
gen_op_test_ctr_false(mask);
- break;
+ break;
case 2:
#if defined(TARGET_PPC64)
if (ctx->sf_mode)
#endif
gen_op_btest_T1(ctx->nip);
gen_op_reset_T0();
+ no_test:
+ if (ctx->singlestep_enabled)
+ gen_op_debug();
+ gen_op_exit_tb();
}
- no_test:
- if (ctx->singlestep_enabled)
- gen_op_debug();
- gen_op_exit_tb();
- ctx->exception = EXCP_BRANCH;
+ ctx->exception = POWERPC_EXCP_BRANCH;
}
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
-{
+{
gen_bcond(ctx, BCOND_IM);
}
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
-{
+{
gen_bcond(ctx, BCOND_CTR);
}
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
-{
+{
gen_bcond(ctx, BCOND_LR);
}
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
/* Restore CPU state */
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_rfi();
- RET_CHG_FLOW(ctx);
+ GEN_SYNC(ctx);
#endif
}
#if defined(TARGET_PPC64)
-GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_FLOW)
+GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
/* Restore CPU state */
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_rfid();
- RET_CHG_FLOW(ctx);
+ GEN_SYNC(ctx);
#endif
}
#endif
/* sc */
-GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
+GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
{
+ uint32_t lev;
+
+ lev = (ctx->opcode >> 5) & 0x7F;
#if defined(CONFIG_USER_ONLY)
- RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
+ GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL_USER, lev);
#else
- RET_EXCP(ctx, EXCP_SYSCALL, 0);
+ GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL, lev);
#endif
}
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
{
uint32_t crm, crn;
-
+
if (likely(ctx->opcode & 0x00100000)) {
crm = CRM(ctx->opcode);
if (likely((crm ^ (crm - 1)) == 0)) {
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_op_load_msr();
gen_op_store_T0_gpr(rD(ctx->opcode));
} else {
/* Privilege exception */
- if (loglevel) {
- fprintf(logfile, "Trying to read priviledged spr %d %03x\n",
+ if (loglevel != 0) {
+ fprintf(logfile, "Trying to read privileged spr %d %03x\n",
sprn, sprn);
}
- printf("Trying to read priviledged spr %d %03x\n", sprn, sprn);
- RET_PRIVREG(ctx);
+ printf("Trying to read privileged spr %d %03x\n", sprn, sprn);
+ GEN_EXCP_PRIVREG(ctx);
}
} else {
/* Not defined */
- if (loglevel) {
+ if (loglevel != 0) {
fprintf(logfile, "Trying to read invalid spr %d %03x\n",
sprn, sprn);
}
printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
- RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
+ GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
}
}
}
/* mftb */
-GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB)
+GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
{
gen_op_mfspr(ctx);
}
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
{
uint32_t crm, crn;
-
+
gen_op_load_gpr_T0(rS(ctx->opcode));
crm = CRM(ctx->opcode);
if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
/* mtmsr */
#if defined(TARGET_PPC64)
-GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_MISC)
+GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_update_nip(ctx, ctx->nip);
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_store_msr();
/* Must stop the translation as machine state (may have) changed */
- RET_CHG_FLOW(ctx);
+ /* Note that mtmsr is not always defined as context-synchronizing */
+ GEN_STOP(ctx);
#endif
}
#endif
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_update_nip(ctx, ctx->nip);
#endif
gen_op_store_msr();
/* Must stop the translation as machine state (may have) changed */
- RET_CHG_FLOW(ctx);
+ /* Note that mtmsrd is not always defined as context-synchronizing */
+ GEN_STOP(ctx);
#endif
}
(*write_cb)(ctx, sprn);
} else {
/* Privilege exception */
- if (loglevel) {
- fprintf(logfile, "Trying to write priviledged spr %d %03x\n",
+ if (loglevel != 0) {
+ fprintf(logfile, "Trying to write privileged spr %d %03x\n",
sprn, sprn);
}
- printf("Trying to write priviledged spr %d %03x\n", sprn, sprn);
- RET_PRIVREG(ctx);
+ printf("Trying to write privileged spr %d %03x\n", sprn, sprn);
+ GEN_EXCP_PRIVREG(ctx);
}
} else {
/* Not defined */
- if (loglevel) {
+ if (loglevel != 0) {
fprintf(logfile, "Trying to write invalid spr %d %03x\n",
sprn, sprn);
}
printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
- RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
+ GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
}
}
* We just have to flush tb while invalidating instruction cache lines...
*/
/* dcbf */
-GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
+GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
{
gen_addr_reg_index(ctx);
op_ldst(lbz);
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_addr_reg_index(ctx);
}
/* dcbt */
-GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
+GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
{
+ /* interpreted as no-op */
/* XXX: specification say this is treated as a load by the MMU
* but does not generate any exception
*/
}
/* dcbtst */
-GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
+GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
{
+ /* interpreted as no-op */
/* XXX: specification say this is treated as a load by the MMU
* but does not generate any exception
*/
};
#endif
#endif
+
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
{
- /* NIP cannot be restored if the memory exception comes from an helper */
- gen_update_nip(ctx, ctx->nip - 4);
gen_addr_reg_index(ctx);
op_icbi();
- RET_STOP(ctx);
}
/* Optional: */
/* dcba */
-GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT)
+GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
{
+ /* interpreted as no-op */
+ /* XXX: specification say this is treated as a store by the MMU
+ * but does not generate any exception
+ */
}
/*** Segment register manipulation ***/
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_op_set_T1(SR(ctx->opcode));
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_op_load_gpr_T1(rB(ctx->opcode));
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_set_T1(SR(ctx->opcode));
gen_op_store_sr();
- RET_STOP(ctx);
#endif
}
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_load_gpr_T1(rB(ctx->opcode));
gen_op_srli_T1(28);
gen_op_store_sr();
- RET_STOP(ctx);
#endif
}
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- if (loglevel)
+ if (loglevel != 0)
fprintf(logfile, "%s: ! supervisor\n", __func__);
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_tlbia();
- RET_STOP(ctx);
#endif
}
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_load_gpr_T0(rB(ctx->opcode));
else
#endif
gen_op_tlbie();
- RET_STOP(ctx);
#endif
}
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
/* This has no effect: it should ensure that all previous
* tlbie have completed
*/
- RET_STOP(ctx);
+ GEN_STOP(ctx);
#endif
}
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- if (loglevel)
+ if (loglevel != 0)
fprintf(logfile, "%s: ! supervisor\n", __func__);
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_slbia();
- RET_STOP(ctx);
#endif
}
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_load_gpr_T0(rB(ctx->opcode));
gen_op_slbie();
- RET_STOP(ctx);
#endif
}
#endif
}
/* clcs */
-GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR) /* 601 ? */
+GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
{
gen_op_load_gpr_T0(rA(ctx->opcode));
gen_op_POWER_clcs();
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
{
/* XXX: TODO */
- RET_INVAL(ctx);
+ GEN_EXCP_INVAL(ctx);
}
/* esa */
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
{
/* XXX: TODO */
- RET_INVAL(ctx);
+ GEN_EXCP_INVAL(ctx);
}
/* mfrom */
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_load_gpr_T0(rA(ctx->opcode));
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_load_gpr_T0(rB(ctx->opcode));
gen_op_6xx_tlbld();
- RET_STOP(ctx);
#endif
}
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_load_gpr_T0(rB(ctx->opcode));
gen_op_6xx_tlbli();
- RET_STOP(ctx);
#endif
}
/* cli */
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
{
- /* Cache line invalidate: priviledged and treated as no-op */
+ /* Cache line invalidate: privileged and treated as no-op */
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
#endif
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
int ra = rA(ctx->opcode);
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_addr_reg_index(ctx);
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_POWER_rfsvc();
- RET_CHG_FLOW(ctx);
+ GEN_SYNC(ctx);
#endif
}
{
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_imm_index(ctx);
+ gen_addr_imm_index(ctx, 0);
op_POWER2_lfq();
gen_op_store_FT0_fpr(rD(ctx->opcode));
gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_imm_index(ctx);
+ gen_addr_imm_index(ctx, 0);
op_POWER2_lfq();
gen_op_store_FT0_fpr(rD(ctx->opcode));
gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
{
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_imm_index(ctx);
+ gen_addr_imm_index(ctx, 0);
gen_op_load_fpr_FT0(rS(ctx->opcode));
gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
op_POWER2_stfq();
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_imm_index(ctx);
+ gen_addr_imm_index(ctx, 0);
gen_op_load_fpr_FT0(rS(ctx->opcode));
gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
op_POWER2_stfq();
}
/* BookE specific instructions */
-GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE)
+/* XXX: not implemented on 440 ? */
+GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE_EXT)
{
/* XXX: TODO */
- RET_INVAL(ctx);
+ GEN_EXCP_INVAL(ctx);
}
-GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE)
+/* XXX: not implemented on 440 ? */
+GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_addr_reg_index(ctx);
else
#endif
gen_op_tlbie();
- RET_STOP(ctx);
#endif
}
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
uint32_t dcrn = SPR(ctx->opcode);
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_op_set_T0(dcrn);
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
uint32_t dcrn = SPR(ctx->opcode);
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_op_set_T0(dcrn);
}
/* mfdcrx */
-GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000001, PPC_BOOKE)
+/* XXX: not implemented on 440 ? */
+GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_BOOKE_EXT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_op_load_gpr_T0(rA(ctx->opcode));
gen_op_load_dcr();
gen_op_store_T0_gpr(rD(ctx->opcode));
+ /* Note: Rc update flag set leads to undefined state of Rc0 */
#endif
}
/* mtdcrx */
-GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000001, PPC_BOOKE)
+/* XXX: not implemented on 440 ? */
+GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_BOOKE_EXT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVREG(ctx);
+ GEN_EXCP_PRIVREG(ctx);
return;
}
gen_op_load_gpr_T0(rA(ctx->opcode));
gen_op_load_gpr_T1(rS(ctx->opcode));
gen_op_store_dcr();
+ /* Note: Rc update flag set leads to undefined state of Rc0 */
#endif
}
+/* mfdcrux (PPC 460) : user-mode access to DCR */
+GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
+{
+ gen_op_load_gpr_T0(rA(ctx->opcode));
+ gen_op_load_dcr();
+ gen_op_store_T0_gpr(rD(ctx->opcode));
+ /* Note: Rc update flag set leads to undefined state of Rc0 */
+}
+
+/* mtdcrux (PPC 460) : user-mode access to DCR */
+GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
+{
+ gen_op_load_gpr_T0(rA(ctx->opcode));
+ gen_op_load_gpr_T1(rS(ctx->opcode));
+ gen_op_store_dcr();
+ /* Note: Rc update flag set leads to undefined state of Rc0 */
+}
+
/* dccci */
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
/* interpreted as no-op */
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_addr_reg_index(ctx);
}
/* icbt */
-GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_SPEC)
+GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
{
/* interpreted as no-op */
/* XXX: specification say this is treated as a load by the MMU
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
/* interpreted as no-op */
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
/* interpreted as no-op */
GEN_HANDLER(rfci_40x, 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
/* Restore CPU state */
gen_op_40x_rfci();
- RET_CHG_FLOW(ctx);
+ GEN_SYNC(ctx);
#endif
}
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
/* Restore CPU state */
gen_op_rfci();
- RET_CHG_FLOW(ctx);
+ GEN_SYNC(ctx);
#endif
}
/* BookE specific */
-GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE)
+/* XXX: not implemented on 440 ? */
+GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
/* Restore CPU state */
gen_op_rfdi();
- RET_CHG_FLOW(ctx);
+ GEN_SYNC(ctx);
#endif
}
-GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_BOOKE)
+/* XXX: not implemented on 440 ? */
+GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
/* Restore CPU state */
gen_op_rfmci();
- RET_CHG_FLOW(ctx);
+ GEN_SYNC(ctx);
#endif
}
+
/* TLB management - PowerPC 405 implementation */
/* tlbre */
-GEN_HANDLER(tlbre, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_SPEC)
+GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
switch (rB(ctx->opcode)) {
gen_op_store_T0_gpr(rD(ctx->opcode));
break;
default:
- RET_INVAL(ctx);
+ GEN_EXCP_INVAL(ctx);
break;
}
#endif
}
/* tlbsx - tlbsx. */
-GEN_HANDLER(tlbsx, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_SPEC)
+GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_addr_reg_index(ctx);
}
/* tlbwe */
-GEN_HANDLER(tlbwe, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC)
+GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
switch (rB(ctx->opcode)) {
gen_op_4xx_tlbwe_lo();
break;
default:
- RET_INVAL(ctx);
+ GEN_EXCP_INVAL(ctx);
+ break;
+ }
+#endif
+}
+
+/* TLB management - PowerPC 440 implementation */
+/* tlbre */
+GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_EXCP_PRIVOPC(ctx);
+#else
+ if (unlikely(!ctx->supervisor)) {
+ GEN_EXCP_PRIVOPC(ctx);
+ return;
+ }
+ switch (rB(ctx->opcode)) {
+ case 0:
+ case 1:
+ case 2:
+ gen_op_load_gpr_T0(rA(ctx->opcode));
+ gen_op_440_tlbre(rB(ctx->opcode));
+ gen_op_store_T0_gpr(rD(ctx->opcode));
+ break;
+ default:
+ GEN_EXCP_INVAL(ctx);
+ break;
+ }
+#endif
+}
+
+/* tlbsx - tlbsx. */
+GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_EXCP_PRIVOPC(ctx);
+#else
+ if (unlikely(!ctx->supervisor)) {
+ GEN_EXCP_PRIVOPC(ctx);
+ return;
+ }
+ gen_addr_reg_index(ctx);
+ if (Rc(ctx->opcode))
+ gen_op_440_tlbsx_();
+ else
+ gen_op_440_tlbsx();
+ gen_op_store_T0_gpr(rD(ctx->opcode));
+#endif
+}
+
+/* tlbwe */
+GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_EXCP_PRIVOPC(ctx);
+#else
+ if (unlikely(!ctx->supervisor)) {
+ GEN_EXCP_PRIVOPC(ctx);
+ return;
+ }
+ switch (rB(ctx->opcode)) {
+ case 0:
+ case 1:
+ case 2:
+ gen_op_load_gpr_T0(rA(ctx->opcode));
+ gen_op_load_gpr_T1(rS(ctx->opcode));
+ gen_op_440_tlbwe(rB(ctx->opcode));
+ break;
+ default:
+ GEN_EXCP_INVAL(ctx);
break;
}
#endif
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_load_gpr_T0(rD(ctx->opcode));
gen_op_wrte();
- RET_EXCP(ctx, EXCP_MTMSR, 0);
+ /* Stop translation to have a chance to raise an exception
+ * if we just set msr_ee to 1
+ */
+ GEN_STOP(ctx);
#endif
}
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
{
#if defined(CONFIG_USER_ONLY)
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
#else
if (unlikely(!ctx->supervisor)) {
- RET_PRIVOPC(ctx);
+ GEN_EXCP_PRIVOPC(ctx);
return;
}
gen_op_set_T0(ctx->opcode & 0x00010000);
gen_op_wrte();
- RET_EXCP(ctx, EXCP_MTMSR, 0);
+ /* Stop translation to have a chance to raise an exception
+ * if we just set msr_ee to 1
+ */
+ GEN_STOP(ctx);
#endif
}
-/* PPC 440 specific instructions */
+/* PowerPC 440 specific instructions */
/* dlmzb */
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
{
}
/* msync replaces sync on 440 */
-GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE)
+GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
{
/* interpreted as no-op */
}
*/
}
-#if defined(TARGET_PPCSPE)
+#if defined(TARGET_PPCEMB)
/*** SPE extension ***/
/* Register moves */
/* Handler for undefined SPE opcodes */
static inline void gen_speundef (DisasContext *ctx)
{
- RET_INVAL(ctx);
+ GEN_EXCP_INVAL(ctx);
}
/* SPE load and stores */
static inline void gen_evl##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_SPE, 0); \
+ GEN_EXCP_NO_AP(ctx); \
return; \
} \
gen_addr_spe_imm_index(ctx, sh); \
static inline void gen_evl##name##x (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_SPE, 0); \
+ GEN_EXCP_NO_AP(ctx); \
return; \
} \
gen_addr_reg_index(ctx); \
static inline void gen_evst##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_SPE, 0); \
+ GEN_EXCP_NO_AP(ctx); \
return; \
} \
gen_addr_spe_imm_index(ctx, sh); \
static inline void gen_evst##name##x (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_SPE, 0); \
+ GEN_EXCP_NO_AP(ctx); \
return; \
} \
gen_addr_reg_index(ctx); \
static inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_SPE, 0); \
+ GEN_EXCP_NO_AP(ctx); \
return; \
} \
gen_op_load_gpr64_T0(rA(ctx->opcode)); \
static inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_SPE, 0); \
+ GEN_EXCP_NO_AP(ctx); \
return; \
} \
gen_op_load_gpr64_T0(rA(ctx->opcode)); \
static inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_SPE, 0); \
+ GEN_EXCP_NO_AP(ctx); \
return; \
} \
gen_op_load_gpr64_T0(rA(ctx->opcode)); \
static inline void gen_##name##i (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_SPE, 0); \
+ GEN_EXCP_NO_AP(ctx); \
return; \
} \
gen_op_load_gpr64_T0(rB(ctx->opcode)); \
static inline void gen_##name##i (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
- RET_EXCP(ctx, EXCP_NO_SPE, 0); \
+ GEN_EXCP_NO_AP(ctx); \
return; \
} \
gen_op_load_gpr64_T0(rA(ctx->opcode)); \
static inline void gen_evsel (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
- RET_EXCP(ctx, EXCP_NO_SPE, 0);
+ GEN_EXCP_NO_AP(ctx);
return;
}
gen_op_load_crf_T0(ctx->opcode & 0x7);
(xer_cmp << XER_CMP);
}
-void cpu_dump_state(CPUState *env, FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
- int flags)
+void cpu_dump_state (CPUState *env, FILE *f,
+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+ int flags)
{
#if defined(TARGET_PPC64) || 1
#define FILL ""
for (i = 0; i < 32; i++) {
if ((i & (RGPL - 1)) == 0)
cpu_fprintf(f, "GPR%02d", i);
- cpu_fprintf(f, " " REGX, env->gpr[i]);
+ cpu_fprintf(f, " " REGX, (target_ulong)env->gpr[i]);
if ((i & (RGPL - 1)) == (RGPL - 1))
cpu_fprintf(f, "\n");
}
nb_gen_labels = 0;
ctx.nip = pc_start;
ctx.tb = tb;
- ctx.exception = EXCP_NONE;
+ ctx.exception = POWERPC_EXCP_NONE;
ctx.spr_cb = env->spr_cb;
#if defined(CONFIG_USER_ONLY)
ctx.mem_idx = msr_le;
ctx.sf_mode = msr_sf;
#endif
ctx.fpu_enabled = msr_fp;
-#if defined(TARGET_PPCSPE)
+#if defined(TARGET_PPCEMB)
ctx.spe_enabled = msr_spe;
#endif
ctx.singlestep_enabled = env->singlestep_enabled;
msr_se = 1;
#endif
/* Set env in case of segfault during code fetch */
- while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
+ while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
if (unlikely(env->nb_breakpoints > 0)) {
for (j = 0; j < env->nb_breakpoints; j++) {
if (env->breakpoints[j] == ctx.nip) {
- gen_update_nip(&ctx, ctx.nip);
+ gen_update_nip(&ctx, ctx.nip);
gen_op_debug();
break;
}
}
/* Is opcode *REALLY* valid ? */
if (unlikely(handler->handler == &gen_invalid)) {
- if (loglevel > 0) {
+ if (loglevel != 0) {
fprintf(logfile, "invalid/unsupported opcode: "
"%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
opc1(ctx.opcode), opc2(ctx.opcode),
}
} else {
if (unlikely((ctx.opcode & handler->inval) != 0)) {
- if (loglevel > 0) {
+ if (loglevel != 0) {
fprintf(logfile, "invalid bits: %08x for opcode: "
- "%02x -%02x - %02x (%08x) 0x" ADDRX "\n",
+ "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
ctx.opcode & handler->inval, opc1(ctx.opcode),
opc2(ctx.opcode), opc3(ctx.opcode),
ctx.opcode, ctx.nip - 4);
} else {
printf("invalid bits: %08x for opcode: "
- "%02x -%02x - %02x (%08x) 0x" ADDRX "\n",
+ "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
ctx.opcode & handler->inval, opc1(ctx.opcode),
opc2(ctx.opcode), opc3(ctx.opcode),
ctx.opcode, ctx.nip - 4);
}
- RET_INVAL(ctxp);
+ GEN_EXCP_INVAL(ctxp);
break;
}
}
handler->count++;
#endif
/* Check trace mode exceptions */
- if (unlikely((msr_be && ctx.exception == EXCP_BRANCH) ||
+#if 0 // XXX: buggy on embedded PowerPC
+ if (unlikely((msr_be && ctx.exception == POWERPC_EXCP_BRANCH) ||
/* Check in single step trace mode
* we need to stop except if:
* - rfi, trap or syscall
(msr_se && (ctx.nip < 0x100 ||
ctx.nip > 0xF00 ||
(ctx.nip & 0xFC) != 0x04) &&
- ctx.exception != EXCP_SYSCALL &&
- ctx.exception != EXCP_SYSCALL_USER &&
- ctx.exception != EXCP_TRAP))) {
- RET_EXCP(ctxp, EXCP_TRACE, 0);
+#if defined(CONFIG_USER_ONLY)
+ ctx.exception != POWERPC_EXCP_SYSCALL_USER &&
+#else
+ ctx.exception != POWERPC_EXCP_SYSCALL &&
+#endif
+ ctx.exception != POWERPC_EXCP_TRAP))) {
+ GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
}
+#endif
/* if we reach a page boundary or are single stepping, stop
* generation
*/
break;
#endif
}
- if (ctx.exception == EXCP_NONE) {
+ if (ctx.exception == POWERPC_EXCP_NONE) {
gen_goto_tb(&ctx, 0, ctx.nip);
- } else if (ctx.exception != EXCP_BRANCH) {
+ } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
gen_op_reset_T0();
/* Generate the return instruction */
gen_op_exit_tb();
lj++;
while (lj <= j)
gen_opc_instr_start[lj++] = 0;
- tb->size = 0;
} else {
tb->size = ctx.nip - pc_start;
}
}
if (loglevel & CPU_LOG_TB_IN_ASM) {
int flags;
- flags = msr_le;
+ flags = env->bfd_mach;
+ flags |= msr_le << 16;
fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
fprintf(logfile, "\n");