uint32_t opcode;
uint32_t exception;
/* Routine used to access memory */
- bool pr, hv;
+ bool pr, hv, dr, le_mode;
bool lazy_tlb_flush;
int mem_idx;
int access_type;
/* Translation flags */
- int le_mode;
TCGMemOp default_tcg_memop_mask;
#if defined(TARGET_PPC64)
- int sf_mode;
- int has_cfar;
-#endif
- int fpu_enabled;
- int altivec_enabled;
- int vsx_enabled;
- int spe_enabled;
- int tm_enabled;
+ bool sf_mode;
+ bool has_cfar;
+#endif
+ bool fpu_enabled;
+ bool altivec_enabled;
+ bool vsx_enabled;
+ bool spe_enabled;
+ bool tm_enabled;
ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
int singlestep_enabled;
uint64_t insns_flags;
tcg_gen_movi_tl(cpu_nip, ctx->nip);
}
-static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
+static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
{
TCGv_i32 t0, t1;
if (ctx->exception == POWERPC_EXCP_NONE) {
ctx->exception = (excp);
}
-static inline void gen_exception(DisasContext *ctx, uint32_t excp)
+static void gen_exception(DisasContext *ctx, uint32_t excp)
{
TCGv_i32 t0;
if (ctx->exception == POWERPC_EXCP_NONE) {
ctx->exception = (excp);
}
-static inline void gen_debug_exception(DisasContext *ctx)
+static void gen_debug_exception(DisasContext *ctx)
{
TCGv_i32 t0;
static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
{
- gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
+ /* Will be converted to program check if needed */
+ gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error);
+}
+
+static inline void gen_priv_exception(DisasContext *ctx, uint32_t error)
+{
+ gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error);
+}
+
+static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error)
+{
+ /* Will be converted to program check if needed */
+ gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error);
}
/* Stop translation */
const char *oname;
} opcode_t;
+/* Helpers for priv. check */
+#define GEN_PRIV \
+ do { \
+ gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \
+ } while (0)
+
+#if defined(CONFIG_USER_ONLY)
+#define CHK_HV GEN_PRIV
+#define CHK_SV GEN_PRIV
+#define CHK_HVRM GEN_PRIV
+#else
+#define CHK_HV \
+ do { \
+ if (unlikely(ctx->pr || !ctx->hv)) { \
+ GEN_PRIV; \
+ } \
+ } while (0)
+#define CHK_SV \
+ do { \
+ if (unlikely(ctx->pr)) { \
+ GEN_PRIV; \
+ } \
+ } while (0)
+#define CHK_HVRM \
+ do { \
+ if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) { \
+ GEN_PRIV; \
+ } \
+ } while (0)
+#endif
+
+#define CHK_NONE
+
+
/*****************************************************************************/
/*** Instruction decoding ***/
#define EXTRACT_HELPER(name, shift, nb) \
return (((opcode >> (shift1)) & ((1 << (nb1)) - 1)) << nb2) | \
((opcode >> (shift2)) & ((1 << (nb2)) - 1)); \
}
+
+#define EXTRACT_HELPER_DXFORM(name, \
+ d0_bits, shift_op_d0, shift_d0, \
+ d1_bits, shift_op_d1, shift_d1, \
+ d2_bits, shift_op_d2, shift_d2) \
+static inline int16_t name(uint32_t opcode) \
+{ \
+ return \
+ (((opcode >> (shift_op_d0)) & ((1 << (d0_bits)) - 1)) << (shift_d0)) | \
+ (((opcode >> (shift_op_d1)) & ((1 << (d1_bits)) - 1)) << (shift_d1)) | \
+ (((opcode >> (shift_op_d2)) & ((1 << (d2_bits)) - 1)) << (shift_d2)); \
+}
+
+
/* Opcode part 1 */
EXTRACT_HELPER(opc1, 26, 6);
/* Opcode part 2 */
EXTRACT_HELPER(FPFLM, 17, 8);
EXTRACT_HELPER(FPW, 16, 1);
+/* addpcis */
+EXTRACT_HELPER_DXFORM(DX, 10, 6, 6, 5, 16, 1, 1, 0, 0)
+
/*** Jump target decoding ***/
/* Immediate address */
static inline target_ulong LI(uint32_t opcode)
}
}
+/* cmprb - range comparison: isupper, isaplha, islower*/
+static void gen_cmprb(DisasContext *ctx)
+{
+ TCGv_i32 src1 = tcg_temp_new_i32();
+ TCGv_i32 src2 = tcg_temp_new_i32();
+ TCGv_i32 src2lo = tcg_temp_new_i32();
+ TCGv_i32 src2hi = tcg_temp_new_i32();
+ TCGv_i32 crf = cpu_crf[crfD(ctx->opcode)];
+
+ tcg_gen_trunc_tl_i32(src1, cpu_gpr[rA(ctx->opcode)]);
+ tcg_gen_trunc_tl_i32(src2, cpu_gpr[rB(ctx->opcode)]);
+
+ tcg_gen_andi_i32(src1, src1, 0xFF);
+ tcg_gen_ext8u_i32(src2lo, src2);
+ tcg_gen_shri_i32(src2, src2, 8);
+ tcg_gen_ext8u_i32(src2hi, src2);
+
+ tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1);
+ tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi);
+ tcg_gen_and_i32(crf, src2lo, src2hi);
+
+ if (ctx->opcode & 0x00200000) {
+ tcg_gen_shri_i32(src2, src2, 8);
+ tcg_gen_ext8u_i32(src2lo, src2);
+ tcg_gen_shri_i32(src2, src2, 8);
+ tcg_gen_ext8u_i32(src2hi, src2);
+ tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1);
+ tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi);
+ tcg_gen_and_i32(src2lo, src2lo, src2hi);
+ tcg_gen_or_i32(crf, crf, src2lo);
+ }
+ tcg_gen_shli_i32(crf, crf, CRF_GT);
+ tcg_temp_free_i32(src1);
+ tcg_temp_free_i32(src2);
+ tcg_temp_free_i32(src2lo);
+ tcg_temp_free_i32(src2hi);
+}
+
/* isel (PowerPC 2.03 specification) */
static void gen_isel(DisasContext *ctx)
{
}
}
+/* addpcis */
+static void gen_addpcis(DisasContext *ctx)
+{
+ target_long d = DX(ctx->opcode);
+
+ tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], ctx->nip + (d << 16));
+}
+
static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
TCGv arg2, int sign, int compute_ov)
{
GEN_DIVE(divdeo, divde, 1);
#endif
+static inline void gen_op_arith_modw(DisasContext *ctx, TCGv ret, TCGv arg1,
+ TCGv arg2, int sign)
+{
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_new_i32();
+
+ tcg_gen_trunc_tl_i32(t0, arg1);
+ tcg_gen_trunc_tl_i32(t1, arg2);
+ if (sign) {
+ TCGv_i32 t2 = tcg_temp_new_i32();
+ TCGv_i32 t3 = tcg_temp_new_i32();
+ tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN);
+ tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1);
+ tcg_gen_and_i32(t2, t2, t3);
+ tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0);
+ tcg_gen_or_i32(t2, t2, t3);
+ tcg_gen_movi_i32(t3, 0);
+ tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
+ tcg_gen_rem_i32(t3, t0, t1);
+ tcg_gen_ext_i32_tl(ret, t3);
+ tcg_temp_free_i32(t2);
+ tcg_temp_free_i32(t3);
+ } else {
+ TCGv_i32 t2 = tcg_const_i32(1);
+ TCGv_i32 t3 = tcg_const_i32(0);
+ tcg_gen_movcond_i32(TCG_COND_EQ, t1, t1, t3, t2, t1);
+ tcg_gen_remu_i32(t3, t0, t1);
+ tcg_gen_extu_i32_tl(ret, t3);
+ tcg_temp_free_i32(t2);
+ tcg_temp_free_i32(t3);
+ }
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
+}
+
+#define GEN_INT_ARITH_MODW(name, opc3, sign) \
+static void glue(gen_, name)(DisasContext *ctx) \
+{ \
+ gen_op_arith_modw(ctx, cpu_gpr[rD(ctx->opcode)], \
+ cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
+ sign); \
+}
+
+GEN_INT_ARITH_MODW(moduw, 0x08, 0);
+GEN_INT_ARITH_MODW(modsw, 0x18, 1);
+
/* mulhw mulhw. */
static void gen_mulhw(DisasContext *ctx)
{
/* nor & nor. */
GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
-#if defined(TARGET_PPC64)
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
static void gen_pause(DisasContext *ctx)
{
TCGv_i32 t0 = tcg_const_i32(0);
} else if (unlikely(Rc(ctx->opcode) != 0)) {
gen_set_Rc0(ctx, cpu_gpr[rs]);
#if defined(TARGET_PPC64)
- } else {
+ } else if (rs != 0) { /* 0 is nop */
int prio = 0;
switch (rs) {
break;
#endif
default:
- /* nop */
break;
}
if (prio) {
tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
gen_store_spr(SPR_PPR, t0);
tcg_temp_free(t0);
- /* Pause us out of TCG otherwise spin loops with smt_low
- * eat too much CPU and the kernel hangs
- */
- gen_pause(ctx);
}
+#if !defined(CONFIG_USER_ONLY)
+ /* Pause out of TCG otherwise spin loops with smt_low eat too much
+ * CPU and the kernel hangs. This applies to all encodings other
+ * than no-op, e.g., miso(rs=26), yield(27), mdoio(29), mdoom(30),
+ * and all currently undefined.
+ */
+ gen_pause(ctx);
+#endif
#endif
}
}
#endif
mask = MASK(mb, me);
- if (sh == 0) {
- tcg_gen_andi_tl(t_ra, t_rs, mask);
- } else if (mask <= 0xffffffffu) {
+ if (mask <= 0xffffffffu) {
TCGv_i32 t0 = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(t0, t_rs);
tcg_gen_rotli_i32(t0, t0, sh);
tcg_temp_free(EA); \
}
-#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2) \
+#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \
static void glue(gen_, name##x)(DisasContext *ctx) \
{ \
TCGv EA; \
+ chk; \
gen_set_access_type(ctx, ACCESS_INT); \
EA = tcg_temp_new(); \
gen_addr_reg_index(ctx, EA); \
gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
tcg_temp_free(EA); \
}
+
#define GEN_LDX(name, ldop, opc2, opc3, type) \
- GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE)
+ GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE)
+
+#define GEN_LDX_HVRM(name, ldop, opc2, opc3, type) \
+ GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
#define GEN_LDS(name, ldop, op, type) \
GEN_LD(name, ldop, op | 0x20, type); \
/* ldx */
GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
+/* CI load/store variants */
+GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
+GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
+GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
+GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
+
static void gen_ld(DisasContext *ctx)
{
TCGv EA;
bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
if (!legal_in_user_mode && ctx->pr) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
tcg_temp_free(EA); \
}
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2) \
+#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \
static void glue(gen_, name##x)(DisasContext *ctx) \
{ \
TCGv EA; \
+ chk; \
gen_set_access_type(ctx, ACCESS_INT); \
EA = tcg_temp_new(); \
gen_addr_reg_index(ctx, EA); \
tcg_temp_free(EA); \
}
#define GEN_STX(name, stop, opc2, opc3, type) \
- GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE)
+ GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE)
+
+#define GEN_STX_HVRM(name, stop, opc2, opc3, type) \
+ GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
#define GEN_STS(name, stop, op, type) \
GEN_ST(name, stop, op | 0x20, type); \
#if defined(TARGET_PPC64)
GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
+GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
+GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
+GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
+GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
static void gen_std(DisasContext *ctx)
{
}
if (!legal_in_user_mode && ctx->pr) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
}
-GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
+GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
#endif /* TARGET_PPC64 */
/* sthbrx */
TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
}
-GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
+GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE);
#endif /* TARGET_PPC64 */
/*** Integer load and store multiple ***/
gen_exception_err(ctx, EXCP_HLT, 1);
}
+#if defined(TARGET_PPC64)
+static void gen_doze(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_PRIV;
+#else
+ TCGv_i32 t;
+
+ CHK_HV;
+ t = tcg_const_i32(PPC_PM_DOZE);
+ gen_helper_pminsn(cpu_env, t);
+ tcg_temp_free_i32(t);
+ gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+
+static void gen_nap(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_PRIV;
+#else
+ TCGv_i32 t;
+
+ CHK_HV;
+ t = tcg_const_i32(PPC_PM_NAP);
+ gen_helper_pminsn(cpu_env, t);
+ tcg_temp_free_i32(t);
+ gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+
+static void gen_sleep(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_PRIV;
+#else
+ TCGv_i32 t;
+
+ CHK_HV;
+ t = tcg_const_i32(PPC_PM_SLEEP);
+ gen_helper_pminsn(cpu_env, t);
+ tcg_temp_free_i32(t);
+ gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+
+static void gen_rvwinkle(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_PRIV;
+#else
+ TCGv_i32 t;
+
+ CHK_HV;
+ t = tcg_const_i32(PPC_PM_RVWINKLE);
+ gen_helper_pminsn(cpu_env, t);
+ tcg_temp_free_i32(t);
+ gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+#endif /* #if defined(TARGET_PPC64) */
+
/*** Floating-point load ***/
#define GEN_LDF(name, ldop, opc, type) \
static void glue(gen_, name)(DisasContext *ctx) \
static void gen_rfi(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
+ /* FIXME: This instruction doesn't exist anymore on 64-bit server
+ * processors compliant with arch 2.x, we should remove it there,
+ * but we need to fix OpenBIOS not to use it on 970 first
+ */
/* Restore CPU state */
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
gen_update_cfar(ctx, ctx->nip);
gen_helper_rfi(cpu_env);
gen_sync_exception(ctx);
static void gen_rfid(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
/* Restore CPU state */
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
gen_update_cfar(ctx, ctx->nip);
gen_helper_rfid(cpu_env);
gen_sync_exception(ctx);
static void gen_hrfid(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
/* Restore CPU state */
- if (unlikely(ctx->pr || !ctx->hv)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_HV;
gen_helper_hrfid(cpu_env);
gen_sync_exception(ctx);
#endif
/* mfmsr */
static void gen_mfmsr(DisasContext *ctx)
{
-#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+ CHK_SV;
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
-#endif
}
static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
}
}
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
} else {
+ /* ISA 2.07 defines these as no-ops */
+ if ((ctx->insns_flags2 & PPC2_ISA207S) &&
+ (sprn >= 808 && sprn <= 811)) {
+ /* This is a nop */
+ return;
+ }
/* Not defined */
fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
qemu_log("Trying to read invalid spr %d (0x%03x) at "
TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
}
- /* Only generate an exception in user space, otherwise this is a nop */
- if (ctx->pr) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+
+ /* The behaviour depends on MSR:PR and SPR# bit 0x10,
+ * it can generate a priv, a hv emu or a no-op
+ */
+ if (sprn & 0x10) {
+ if (ctx->pr) {
+ gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+ }
+ } else {
+ if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
+ gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+ }
}
}
}
#if defined(TARGET_PPC64)
static void gen_mtmsrd(DisasContext *ctx)
{
-#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+ CHK_SV;
+
+#if !defined(CONFIG_USER_ONLY)
if (ctx->opcode & 0x00010000) {
/* Special form that does not need any synchronisation */
TCGv t0 = tcg_temp_new();
/* Note that mtmsr is not always defined as context-synchronizing */
gen_stop_exception(ctx);
}
-#endif
+#endif /* !defined(CONFIG_USER_ONLY) */
}
-#endif
+#endif /* defined(TARGET_PPC64) */
static void gen_mtmsr(DisasContext *ctx)
{
-#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
- if (ctx->opcode & 0x00010000) {
+ CHK_SV;
+
+#if !defined(CONFIG_USER_ONLY)
+ if (ctx->opcode & 0x00010000) {
/* Special form that does not need any synchronisation */
TCGv t0 = tcg_temp_new();
tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
qemu_log("Trying to write privileged spr %d (0x%03x) at "
TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
}
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
} else {
+ /* ISA 2.07 defines these as no-ops */
+ if ((ctx->insns_flags2 & PPC2_ISA207S) &&
+ (sprn >= 808 && sprn <= 811)) {
+ /* This is a nop */
+ return;
+ }
+
/* Not defined */
if (qemu_log_separate()) {
qemu_log("Trying to write invalid spr %d (0x%03x) at "
fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- /* Only generate an exception in user space, otherwise this is a nop */
- if (ctx->pr) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+
+ /* The behaviour depends on MSR:PR and SPR# bit 0x10,
+ * it can generate a priv, a hv emu or a no-op
+ */
+ if (sprn & 0x10) {
+ if (ctx->pr) {
+ gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+ }
+ } else {
+ if (ctx->pr || sprn == 0) {
+ gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+ }
}
}
}
static void gen_dcbi(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
TCGv EA, val;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+
+ CHK_SV;
EA = tcg_temp_new();
gen_set_access_type(ctx, ACCESS_CACHE);
gen_addr_reg_index(ctx, EA);
gen_qemu_st8(ctx, val, EA);
tcg_temp_free(val);
tcg_temp_free(EA);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* dcdst */
static void gen_mfsr(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+
+ CHK_SV;
t0 = tcg_const_tl(SR(ctx->opcode));
gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* mfsrin */
static void gen_mfsrin(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+
+ CHK_SV;
t0 = tcg_temp_new();
tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
tcg_gen_andi_tl(t0, t0, 0xF);
gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* mtsr */
static void gen_mtsr(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+
+ CHK_SV;
t0 = tcg_const_tl(SR(ctx->opcode));
gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* mtsrin */
static void gen_mtsrin(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+ CHK_SV;
+
t0 = tcg_temp_new();
tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
tcg_gen_andi_tl(t0, t0, 0xF);
gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
#if defined(TARGET_PPC64)
static void gen_mfsr_64b(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+
+ CHK_SV;
t0 = tcg_const_tl(SR(ctx->opcode));
gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* mfsrin */
static void gen_mfsrin_64b(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+
+ CHK_SV;
t0 = tcg_temp_new();
tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
tcg_gen_andi_tl(t0, t0, 0xF);
gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* mtsr */
static void gen_mtsr_64b(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+
+ CHK_SV;
t0 = tcg_const_tl(SR(ctx->opcode));
gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* mtsrin */
static void gen_mtsrin_64b(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+
+ CHK_SV;
t0 = tcg_temp_new();
tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
tcg_gen_andi_tl(t0, t0, 0xF);
gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* slbmte */
static void gen_slbmte(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+ CHK_SV;
+
gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
cpu_gpr[rS(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
static void gen_slbmfee(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+ CHK_SV;
+
gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
static void gen_slbmfev(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+ CHK_SV;
+
gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
static void gen_slbfee_(DisasContext *ctx)
static void gen_tlbia(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr || !ctx->hv)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_HV;
+
gen_helper_tlbia(cpu_env);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbiel */
static void gen_tlbiel(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
+
gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbie */
static void gen_tlbie(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr || !ctx->hv)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_HV;
+
if (NARROW_MODE(ctx)) {
TCGv t0 = tcg_temp_new();
tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
} else {
gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
}
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbsync */
static void gen_tlbsync(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr || !ctx->hv)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_HV;
+
/* tlbsync is a nop for server, ptesync handles delayed tlb flush,
* embedded however needs to deal with tlbsync. We don't try to be
* fancy and swallow the overhead of checking for both.
*/
gen_check_tlb_flush(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
#if defined(TARGET_PPC64)
static void gen_slbia(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
+
gen_helper_slbia(cpu_env);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* slbie */
static void gen_slbie(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
+
gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
-#endif
+#endif /* defined(TARGET_PPC64) */
/*** External control ***/
/* Optional: */
static void gen_mfrom(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* 602 - 603 - G2 TLB management */
static void gen_tlbld_6xx(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbli */
static void gen_tlbli_6xx(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* 74xx TLB management */
static void gen_tlbld_74xx(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbli */
static void gen_tlbli_74xx(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* POWER instructions not in PowerPC 601 */
/* cli */
static void gen_cli(DisasContext *ctx)
{
- /* Cache line invalidate: privileged and treated as no-op */
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
-#endif
+ /* Cache line invalidate: privileged and treated as no-op */
+ CHK_SV;
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* dclst */
static void gen_mfsri(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
int ra = rA(ctx->opcode);
int rd = rD(ctx->opcode);
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+
+ CHK_SV;
t0 = tcg_temp_new();
gen_addr_reg_index(ctx, t0);
tcg_gen_shri_tl(t0, t0, 28);
tcg_temp_free(t0);
if (ra != 0 && ra != rd)
tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
static void gen_rac(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+
+ CHK_SV;
t0 = tcg_temp_new();
gen_addr_reg_index(ctx, t0);
gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
static void gen_rfsvc(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
+
gen_helper_rfsvc(cpu_env);
gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* svc is not implemented for now */
static void gen_tlbiva(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+
+ CHK_SV;
t0 = tcg_temp_new();
gen_addr_reg_index(ctx, t0);
gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* All 405 MAC instructions are translated here */
static void gen_mfdcr(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
TCGv dcrn;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+
+ CHK_SV;
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
dcrn = tcg_const_tl(SPR(ctx->opcode));
gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
tcg_temp_free(dcrn);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* mtdcr */
static void gen_mtdcr(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
TCGv dcrn;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+
+ CHK_SV;
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
dcrn = tcg_const_tl(SPR(ctx->opcode));
gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
tcg_temp_free(dcrn);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* mfdcrx */
static void gen_mfdcrx(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+ CHK_SV;
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
cpu_gpr[rA(ctx->opcode)]);
/* Note: Rc update flag set leads to undefined state of Rc0 */
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* mtdcrx */
static void gen_mtdcrx(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
+ CHK_SV;
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
cpu_gpr[rS(ctx->opcode)]);
/* Note: Rc update flag set leads to undefined state of Rc0 */
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* mfdcrux (PPC 460) : user-mode access to DCR */
/* dccci */
static void gen_dccci(DisasContext *ctx)
{
-#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
/* interpreted as no-op */
-#endif
}
/* dcread */
static void gen_dcread(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
TCGv EA, val;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+
+ CHK_SV;
gen_set_access_type(ctx, ACCESS_CACHE);
EA = tcg_temp_new();
gen_addr_reg_index(ctx, EA);
tcg_temp_free(val);
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
tcg_temp_free(EA);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* icbt */
/* iccci */
static void gen_iccci(DisasContext *ctx)
{
-#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
/* interpreted as no-op */
-#endif
}
/* icread */
static void gen_icread(DisasContext *ctx)
{
-#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
/* interpreted as no-op */
-#endif
}
/* rfci (supervisor only) */
static void gen_rfci_40x(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
/* Restore CPU state */
gen_helper_40x_rfci(cpu_env);
gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
static void gen_rfci(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
/* Restore CPU state */
gen_helper_rfci(cpu_env);
gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* BookE specific */
static void gen_rfdi(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
/* Restore CPU state */
gen_helper_rfdi(cpu_env);
gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* XXX: not implemented on 440 ? */
static void gen_rfmci(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
/* Restore CPU state */
gen_helper_rfmci(cpu_env);
gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* TLB management - PowerPC 405 implementation */
static void gen_tlbre_40x(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
switch (rB(ctx->opcode)) {
case 0:
gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
break;
}
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbsx - tlbsx. */
static void gen_tlbsx_40x(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+
+ CHK_SV;
t0 = tcg_temp_new();
gen_addr_reg_index(ctx, t0);
gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
gen_set_label(l1);
}
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbwe */
static void gen_tlbwe_40x(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
+
switch (rB(ctx->opcode)) {
case 0:
gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
break;
}
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* TLB management - PowerPC 440 implementation */
static void gen_tlbre_440(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
+
switch (rB(ctx->opcode)) {
case 0:
case 1:
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
break;
}
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbsx - tlbsx. */
static void gen_tlbsx_440(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+
+ CHK_SV;
t0 = tcg_temp_new();
gen_addr_reg_index(ctx, t0);
gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
gen_set_label(l1);
}
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbwe */
static void gen_tlbwe_440(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
switch (rB(ctx->opcode)) {
case 0:
case 1:
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
break;
}
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* TLB management - PowerPC BookE 2.06 implementation */
/* tlbre */
static void gen_tlbre_booke206(DisasContext *ctx)
{
-#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ #if defined(CONFIG_USER_ONLY)
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
-
+ CHK_SV;
gen_helper_booke206_tlbre(cpu_env);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbsx - tlbsx. */
static void gen_tlbsx_booke206(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
if (rA(ctx->opcode)) {
t0 = tcg_temp_new();
tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
gen_helper_booke206_tlbsx(cpu_env, t0);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* tlbwe */
static void gen_tlbwe_booke206(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
gen_update_nip(ctx, ctx->nip - 4);
gen_helper_booke206_tlbwe(cpu_env);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
static void gen_tlbivax_booke206(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
t0 = tcg_temp_new();
gen_addr_reg_index(ctx, t0);
-
gen_helper_booke206_tlbivax(cpu_env, t0);
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
static void gen_tlbilx_booke206(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
t0 = tcg_temp_new();
gen_addr_reg_index(ctx, t0);
}
tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
static void gen_wrtee(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
TCGv t0;
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+
+ CHK_SV;
t0 = tcg_temp_new();
tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
* if we just set msr_ee to 1
*/
gen_stop_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* wrteei */
static void gen_wrteei(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
+ CHK_SV;
if (ctx->opcode & 0x00008000) {
tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
/* Stop translation to have a chance to raise an exception */
} else {
tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
}
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/* PowerPC 440 specific instructions */
static void gen_msgclr(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
-
+ CHK_SV;
gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
static void gen_msgsnd(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ GEN_PRIV;
#else
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
-
+ CHK_SV;
gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
}
/*** Altivec vector extension ***/
#define GEN_TM_PRIV_NOOP(name) \
static inline void gen_##name(DisasContext *ctx) \
{ \
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); \
+ gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); \
}
#else
#define GEN_TM_PRIV_NOOP(name) \
static inline void gen_##name(DisasContext *ctx) \
{ \
- if (unlikely(ctx->pr)) { \
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); \
- return; \
- } \
+ CHK_SV; \
if (unlikely(!ctx->tm_enabled)) { \
gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \
return; \
GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
+GEN_HANDLER_E(cmprb, 0x1F, 0x00, 0x06, 0x00400001, PPC_NONE, PPC2_ISA300),
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
+GEN_HANDLER_E(addpcis, 0x13, 0x2, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300),
GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
#if defined(TARGET_PPC64)
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
+GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
+GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
+GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
+GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
#endif
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
GEN_HANDLER_E(divweo, 0x1F, 0x0B, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
GEN_HANDLER_E(divweu, 0x1F, 0x0B, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
GEN_HANDLER_E(divweuo, 0x1F, 0x0B, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
+GEN_HANDLER_E(modsw, 0x1F, 0x0B, 0x18, 0x00000001, PPC_NONE, PPC2_ISA300),
+GEN_HANDLER_E(moduw, 0x1F, 0x0B, 0x08, 0x00000001, PPC_NONE, PPC2_ISA300),
#if defined(TARGET_PPC64)
#undef GEN_INT_ARITH_DIVD
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
#define GEN_LDUX(name, ldop, opc2, opc3, type) \
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2) \
+#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \
GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
#define GEN_LDS(name, ldop, op, type) \
GEN_LD(name, ldop, op | 0x20, type) \
GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
-GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX)
+GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE)
+
+/* HV/P7 and later only */
+GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
+GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST)
+GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
+GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
#endif
GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
#define GEN_STUX(name, stop, opc2, opc3, type) \
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2) \
+#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \
GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
#define GEN_STS(name, stop, op, type) \
GEN_ST(name, stop, op | 0x20, type) \
#if defined(TARGET_PPC64)
GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
-GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX)
+GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE)
+GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
+GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
+GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
+GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
#endif
GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
+#if defined(TARGET_PPC64)
+ if (env->excp_model == POWERPC_EXCP_POWER7 ||
+ env->excp_model == POWERPC_EXCP_POWER8) {
+ cpu_fprintf(f, "HSRR0 " TARGET_FMT_lx " HSRR1 " TARGET_FMT_lx "\n",
+ env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
+ }
+#endif
if (env->excp_model == POWERPC_EXCP_BOOKE) {
cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
" MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
ctx.spr_cb = env->spr_cb;
ctx.pr = msr_pr;
ctx.mem_idx = env->dmmu_idx;
+ ctx.dr = msr_dr;
#if !defined(CONFIG_USER_ONLY)
ctx.hv = msr_hv || !env->has_hv_mode;
#endif
ctx.insns_flags = env->insns_flags;
ctx.insns_flags2 = env->insns_flags2;
ctx.access_type = -1;
- ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
+ ctx.le_mode = !!(env->hflags & (1 << MSR_LE));
ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;
#if defined(TARGET_PPC64)
ctx.sf_mode = msr_is_64bit(env, env->msr);
(env->mmu_model & POWERPC_MMU_64B))
ctx.lazy_tlb_flush = true;
- ctx.fpu_enabled = msr_fp;
+ ctx.fpu_enabled = !!msr_fp;
if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
- ctx.spe_enabled = msr_spe;
+ ctx.spe_enabled = !!msr_spe;
else
- ctx.spe_enabled = 0;
+ ctx.spe_enabled = false;
if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
- ctx.altivec_enabled = msr_vr;
+ ctx.altivec_enabled = !!msr_vr;
else
- ctx.altivec_enabled = 0;
+ ctx.altivec_enabled = false;
if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
- ctx.vsx_enabled = msr_vsx;
+ ctx.vsx_enabled = !!msr_vsx;
} else {
- ctx.vsx_enabled = 0;
+ ctx.vsx_enabled = false;
}
#if defined(TARGET_PPC64)
if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
- ctx.tm_enabled = msr_tm;
+ ctx.tm_enabled = !!msr_tm;
} else {
- ctx.tm_enabled = 0;
+ ctx.tm_enabled = false;
}
#endif
if ((env->flags & POWERPC_FLAG_SE) && msr_se)