#include "gen-op.h"
-static inline void gen_set_T0 (target_ulong val)
+static always_inline void gen_set_T0 (target_ulong val)
{
#if defined(TARGET_PPC64)
if (val >> 32)
gen_op_set_T0(val);
}
-static inline void gen_set_T1 (target_ulong val)
+static always_inline void gen_set_T1 (target_ulong val)
{
#if defined(TARGET_PPC64)
if (val >> 32)
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
}; \
-static inline void func(int n) \
+static always_inline void func (int n) \
{ \
NAME ## _table[n](); \
}
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
}; \
-static inline void func(int n) \
+static always_inline void func (int n) \
{ \
NAME ## _table[n](); \
}
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
}; \
-static inline void func(int n) \
+static always_inline void func (int n) \
{ \
NAME ## _table[n](); \
}
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 always_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;
+ int altivec_enabled;
#if defined(TARGET_PPCEMB)
int spe_enabled;
#endif
ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
int singlestep_enabled;
+ int dcache_line_size;
} DisasContext;
struct opc_handler_t {
#endif
};
-static inline void gen_set_Rc0 (DisasContext *ctx)
+static always_inline void gen_set_Rc0 (DisasContext *ctx)
{
#if defined(TARGET_PPC64)
if (ctx->sf_mode)
gen_op_set_Rc0();
}
-static inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
+static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
{
#if defined(TARGET_PPC64)
if (ctx->sf_mode)
#define GEN_EXCP_NO_AP(ctx) \
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
+#define GEN_EXCP_NO_VR(ctx) \
+GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
+
/* Stop translation */
-static inline void GEN_STOP (DisasContext *ctx)
+static always_inline void GEN_STOP (DisasContext *ctx)
{
gen_update_nip(ctx, ctx->nip);
ctx->exception = POWERPC_EXCP_STOP;
}
/* No need to update nip here, as execution flow will change */
-static inline void GEN_SYNC (DisasContext *ctx)
+static always_inline void GEN_SYNC (DisasContext *ctx)
{
ctx->exception = POWERPC_EXCP_SYNC;
}
/*****************************************************************************/
/*** Instruction decoding ***/
#define EXTRACT_HELPER(name, shift, nb) \
-static inline uint32_t name (uint32_t opcode) \
+static always_inline uint32_t name (uint32_t opcode) \
{ \
return (opcode >> (shift)) & ((1 << (nb)) - 1); \
}
#define EXTRACT_SHELPER(name, shift, nb) \
-static inline int32_t name (uint32_t opcode) \
+static always_inline int32_t name (uint32_t opcode) \
{ \
return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1)); \
}
EXTRACT_HELPER(crbB, 11, 5);
/* SPR / TBL */
EXTRACT_HELPER(_SPR, 11, 10);
-static inline uint32_t SPR (uint32_t opcode)
+static always_inline uint32_t SPR (uint32_t opcode)
{
uint32_t sprn = _SPR(opcode);
/* Displacement */
EXTRACT_SHELPER(d, 0, 16);
/* Immediate address */
-static inline target_ulong LI (uint32_t opcode)
+static always_inline target_ulong LI (uint32_t opcode)
{
return (opcode >> 0) & 0x03FFFFFC;
}
-static inline uint32_t BD (uint32_t opcode)
+static always_inline uint32_t BD (uint32_t opcode)
{
return (opcode >> 0) & 0xFFFC;
}
EXTRACT_HELPER(LK, 0, 1);
/* Create a mask between <start> and <end> bits */
-static inline target_ulong MASK (uint32_t start, uint32_t end)
+static always_inline target_ulong MASK (uint32_t start, uint32_t end)
{
target_ulong 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 */
+ /* PowerPC base instructions set */
PPC_INSNS_BASE = 0x0000000000000001ULL,
+ /* integer operations instructions */
#define PPC_INTEGER PPC_INSNS_BASE
+ /* flow control instructions */
#define PPC_FLOW PPC_INSNS_BASE
+ /* virtual memory instructions */
#define PPC_MEM PPC_INSNS_BASE
+ /* ld/st with reservation instructions */
#define PPC_RES PPC_INSNS_BASE
+ /* cache control instructions */
#define PPC_CACHE PPC_INSNS_BASE
+ /* spr/msr access instructions */
#define PPC_MISC PPC_INSNS_BASE
- /* Optional floating point instructions */
+ /* 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 */
+ /* external control instructions */
PPC_EXTERN = 0x0000000000000080ULL,
- /* segment register access instructions */
+ /* segment register access instructions */
PPC_SEGMENT = 0x0000000000000100ULL,
- /* Optional cache control instruction */
+ /* Optional cache control instruction */
PPC_CACHE_DCBA = 0x0000000000000200ULL,
- /* Optional memory control instructions */
+ /* Optional memory control instructions */
PPC_MEM_TLBIA = 0x0000000000000400ULL,
PPC_MEM_TLBIE = 0x0000000000000800ULL,
PPC_MEM_TLBSYNC = 0x0000000000001000ULL,
- /* eieio & sync */
+ /* eieio & sync */
PPC_MEM_SYNC = 0x0000000000002000ULL,
- /* PowerPC 6xx TLB management instructions */
+ /* PowerPC 6xx TLB management instructions */
PPC_6xx_TLB = 0x0000000000004000ULL,
- /* Altivec support */
+ /* Altivec support */
PPC_ALTIVEC = 0x0000000000008000ULL,
- /* Time base mftb instruction */
+ /* Time base mftb instruction */
PPC_MFTB = 0x0000000000010000ULL,
- /* Embedded PowerPC dedicated instructions */
+ /* Embedded PowerPC dedicated instructions */
PPC_EMB_COMMON = 0x0000000000020000ULL,
- /* PowerPC 40x exception model */
+ /* PowerPC 40x exception model */
PPC_40x_EXCP = 0x0000000000040000ULL,
- /* PowerPC 40x TLB management instructions */
+ /* PowerPC 40x TLB management instructions */
PPC_40x_TLB = 0x0000000000080000ULL,
- /* PowerPC 405 Mac instructions */
+ /* PowerPC 405 Mac instructions */
PPC_405_MAC = 0x0000000000100000ULL,
- /* PowerPC 440 specific instructions */
+ /* PowerPC 440 specific instructions */
PPC_440_SPEC = 0x0000000000200000ULL,
- /* Power-to-PowerPC bridge (601) */
+ /* Power-to-PowerPC bridge (601) */
PPC_POWER_BR = 0x0000000000400000ULL,
- /* PowerPC 602 specific */
+ /* PowerPC 602 specific */
PPC_602_SPEC = 0x0000000000800000ULL,
- /* Deprecated instructions */
- /* Original POWER instruction set */
+ /* Deprecated instructions */
+ /* Original POWER instruction set */
PPC_POWER = 0x0000000001000000ULL,
- /* POWER2 instruction set extension */
+ /* POWER2 instruction set extension */
PPC_POWER2 = 0x0000000002000000ULL,
- /* Power RTC support */
+ /* Power RTC support */
PPC_POWER_RTC = 0x0000000004000000ULL,
- /* 64 bits PowerPC instructions */
- /* 64 bits PowerPC instruction set */
+ /* 64 bits PowerPC instruction set */
PPC_64B = 0x0000000008000000ULL,
- /* 64 bits hypervisor extensions */
+ /* 64 bits hypervisor extensions */
PPC_64H = 0x0000000010000000ULL,
- /* 64 bits PowerPC "bridge" features */
- PPC_64_BRIDGE = 0x0000000020000000ULL,
- /* BookE (embedded) PowerPC specification */
+ /* segment register access instructions for PowerPC 64 "bridge" */
+ PPC_SEGMENT_64B = 0x0000000020000000ULL,
+ /* BookE (embedded) PowerPC specification */
PPC_BOOKE = 0x0000000040000000ULL,
- /* eieio */
+ /* eieio */
PPC_MEM_EIEIO = 0x0000000080000000ULL,
- /* e500 vector instructions */
+ /* e500 vector instructions */
PPC_E500_VECTOR = 0x0000000100000000ULL,
- /* PowerPC 4xx dedicated instructions */
+ /* PowerPC 4xx dedicated instructions */
PPC_4xx_COMMON = 0x0000000200000000ULL,
- /* PowerPC 2.03 specification extensions */
+ /* PowerPC 2.03 specification extensions */
PPC_203 = 0x0000000400000000ULL,
- /* PowerPC 2.03 SPE extension */
+ /* PowerPC 2.03 SPE extension */
PPC_SPE = 0x0000000800000000ULL,
- /* PowerPC 2.03 SPE floating-point extension */
+ /* PowerPC 2.03 SPE floating-point extension */
PPC_SPEFPU = 0x0000001000000000ULL,
- /* SLB management */
+ /* SLB management */
PPC_SLBI = 0x0000002000000000ULL,
- /* PowerPC 40x ibct instructions */
+ /* PowerPC 40x ibct instructions */
PPC_40x_ICBT = 0x0000004000000000ULL,
- /* PowerPC 74xx TLB management instructions */
+ /* PowerPC 74xx TLB management instructions */
PPC_74xx_TLB = 0x0000008000000000ULL,
- /* More BookE (embedded) instructions... */
+ /* More BookE (embedded) instructions... */
PPC_BOOKE_EXT = 0x0000010000000000ULL,
- /* rfmci is not implemented in all BookE PowerPC */
+ /* rfmci is not implemented in all BookE PowerPC */
PPC_RFMCI = 0x0000020000000000ULL,
- /* user-mode DCR access, implemented in PowerPC 460 */
+ /* user-mode DCR access, implemented in PowerPC 460 */
PPC_DCRUX = 0x0000040000000000ULL,
- /* New floating-point extensions (PowerPC 2.0x) */
+ /* New floating-point extensions (PowerPC 2.0x) */
PPC_FLOAT_EXT = 0x0000080000000000ULL,
- /* New wait instruction (PowerPC 2.0x) */
+ /* New wait instruction (PowerPC 2.0x) */
PPC_WAIT = 0x0000100000000000ULL,
- /* New 64 bits extensions (PowerPC 2.0x) */
+ /* New 64 bits extensions (PowerPC 2.0x) */
PPC_64BX = 0x0000200000000000ULL,
+ /* dcbz instruction with fixed cache line size */
+ PPC_CACHE_DCBZ = 0x0000400000000000ULL,
+ /* dcbz instruction with tunable cache line size */
+ PPC_CACHE_DCBZT = 0x0000800000000000ULL,
};
/*****************************************************************************/
#endif
/* add add. addo addo. */
-static inline void gen_op_addo (void)
+static always_inline void gen_op_addo (void)
{
gen_op_move_T2_T0();
gen_op_add();
}
#if defined(TARGET_PPC64)
#define gen_op_add_64 gen_op_add
-static inline void gen_op_addo_64 (void)
+static always_inline void gen_op_addo_64 (void)
{
gen_op_move_T2_T0();
gen_op_add();
#endif
GEN_INT_ARITH2_64 (add, 0x1F, 0x0A, 0x08, PPC_INTEGER);
/* addc addc. addco addco. */
-static inline void gen_op_addc (void)
+static always_inline void gen_op_addc (void)
{
gen_op_move_T2_T0();
gen_op_add();
gen_op_check_addc();
}
-static inline void gen_op_addco (void)
+static always_inline void gen_op_addco (void)
{
gen_op_move_T2_T0();
gen_op_add();
gen_op_check_addo();
}
#if defined(TARGET_PPC64)
-static inline void gen_op_addc_64 (void)
+static always_inline void gen_op_addc_64 (void)
{
gen_op_move_T2_T0();
gen_op_add();
gen_op_check_addc_64();
}
-static inline void gen_op_addco_64 (void)
+static always_inline void gen_op_addco_64 (void)
{
gen_op_move_T2_T0();
gen_op_add();
#endif
GEN_INT_ARITH2_64 (addc, 0x1F, 0x0A, 0x00, PPC_INTEGER);
/* adde adde. addeo addeo. */
-static inline void gen_op_addeo (void)
+static always_inline void gen_op_addeo (void)
{
gen_op_move_T2_T0();
gen_op_adde();
gen_op_check_addo();
}
#if defined(TARGET_PPC64)
-static inline void gen_op_addeo_64 (void)
+static always_inline void gen_op_addeo_64 (void)
{
gen_op_move_T2_T0();
gen_op_adde_64();
#endif
GEN_INT_ARITH2_64 (adde, 0x1F, 0x0A, 0x04, PPC_INTEGER);
/* addme addme. addmeo addmeo. */
-static inline void gen_op_addme (void)
+static always_inline void gen_op_addme (void)
{
gen_op_move_T1_T0();
gen_op_add_me();
}
#if defined(TARGET_PPC64)
-static inline void gen_op_addme_64 (void)
+static always_inline void gen_op_addme_64 (void)
{
gen_op_move_T1_T0();
gen_op_add_me_64();
#endif
GEN_INT_ARITH1_64 (addme, 0x1F, 0x0A, 0x07, PPC_INTEGER);
/* addze addze. addzeo addzeo. */
-static inline void gen_op_addze (void)
+static always_inline void gen_op_addze (void)
{
gen_op_move_T2_T0();
gen_op_add_ze();
gen_op_check_addc();
}
-static inline void gen_op_addzeo (void)
+static always_inline void gen_op_addzeo (void)
{
gen_op_move_T2_T0();
gen_op_add_ze();
gen_op_check_addo();
}
#if defined(TARGET_PPC64)
-static inline void gen_op_addze_64 (void)
+static always_inline void gen_op_addze_64 (void)
{
gen_op_move_T2_T0();
gen_op_add_ze();
gen_op_check_addc_64();
}
-static inline void gen_op_addzeo_64 (void)
+static always_inline void gen_op_addzeo_64 (void)
{
gen_op_move_T2_T0();
gen_op_add_ze();
/* neg neg. nego nego. */
GEN_INT_ARITH1_64 (neg, 0x1F, 0x08, 0x03, PPC_INTEGER);
/* subf subf. subfo subfo. */
-static inline void gen_op_subfo (void)
+static always_inline void gen_op_subfo (void)
{
gen_op_move_T2_T0();
gen_op_subf();
}
#if defined(TARGET_PPC64)
#define gen_op_subf_64 gen_op_subf
-static inline void gen_op_subfo_64 (void)
+static always_inline void gen_op_subfo_64 (void)
{
gen_op_move_T2_T0();
gen_op_subf();
#endif
GEN_INT_ARITH2_64 (subf, 0x1F, 0x08, 0x01, PPC_INTEGER);
/* subfc subfc. subfco subfco. */
-static inline void gen_op_subfc (void)
+static always_inline void gen_op_subfc (void)
{
gen_op_subf();
gen_op_check_subfc();
}
-static inline void gen_op_subfco (void)
+static always_inline void gen_op_subfco (void)
{
gen_op_move_T2_T0();
gen_op_subf();
gen_op_check_subfo();
}
#if defined(TARGET_PPC64)
-static inline void gen_op_subfc_64 (void)
+static always_inline void gen_op_subfc_64 (void)
{
gen_op_subf();
gen_op_check_subfc_64();
}
-static inline void gen_op_subfco_64 (void)
+static always_inline void gen_op_subfco_64 (void)
{
gen_op_move_T2_T0();
gen_op_subf();
#endif
GEN_INT_ARITH2_64 (subfc, 0x1F, 0x08, 0x00, PPC_INTEGER);
/* subfe subfe. subfeo subfeo. */
-static inline void gen_op_subfeo (void)
+static always_inline void gen_op_subfeo (void)
{
gen_op_move_T2_T0();
gen_op_subfe();
}
#if defined(TARGET_PPC64)
#define gen_op_subfe_64 gen_op_subfe
-static inline void gen_op_subfeo_64 (void)
+static always_inline void gen_op_subfeo_64 (void)
{
gen_op_move_T2_T0();
gen_op_subfe_64();
gen_##name(ctx, 1, 1); \
}
-static inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
+static always_inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
{
if (mask >> 32)
gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
gen_op_andi_T0(mask);
}
-static inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
+static always_inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
{
if (mask >> 32)
gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
gen_op_andi_T1(mask);
}
-static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me,
- uint32_t sh)
+static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
+ uint32_t me, uint32_t sh)
{
gen_op_load_gpr_T0(rS(ctx->opcode));
if (likely(sh == 0)) {
gen_set_Rc0(ctx);
}
/* rldicl - rldicl. */
-static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
+static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
{
uint32_t sh, mb;
}
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
/* rldicr - rldicr. */
-static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
+static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
{
uint32_t sh, me;
}
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
/* rldic - rldic. */
-static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
+static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
{
uint32_t sh, mb;
}
GEN_PPC64_R4(rldic, 0x1E, 0x04);
-static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me)
+static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
+ uint32_t me)
{
gen_op_load_gpr_T0(rS(ctx->opcode));
gen_op_load_gpr_T1(rB(ctx->opcode));
}
/* rldcl - rldcl. */
-static inline void gen_rldcl (DisasContext *ctx, int mbn)
+static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
{
uint32_t mb;
}
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
/* rldcr - rldcr. */
-static inline void gen_rldcr (DisasContext *ctx, int men)
+static always_inline void gen_rldcr (DisasContext *ctx, int men)
{
uint32_t me;
}
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
/* rldimi - rldimi. */
-static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
+static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
{
uint64_t mask;
uint32_t sh, mb;
/* srad & srad. */
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
/* sradi & sradi. */
-static inline void gen_sradi (DisasContext *ctx, int n)
+static always_inline void gen_sradi (DisasContext *ctx, int n)
{
uint64_t mask;
int sh, mb, me;
/*** Addressing modes ***/
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
-static inline void gen_addr_imm_index (DisasContext *ctx, target_long maskl)
+static always_inline void gen_addr_imm_index (DisasContext *ctx,
+ target_long maskl)
{
target_long simm = SIMM(ctx->opcode);
#endif
}
-static inline void gen_addr_reg_index (DisasContext *ctx)
+static always_inline void gen_addr_reg_index (DisasContext *ctx)
{
if (rA(ctx->opcode) == 0) {
gen_op_load_gpr_T0(rB(ctx->opcode));
#endif
}
-static inline void gen_addr_register (DisasContext *ctx)
+static always_inline void gen_addr_register (DisasContext *ctx)
{
if (rA(ctx->opcode) == 0) {
gen_op_reset_T0();
#define op_ldst(name) (*gen_op_##name[ctx->mem_idx])()
#if defined(CONFIG_USER_ONLY)
#if defined(TARGET_PPC64)
+/* User mode only - 64 bits */
#define OP_LD_TABLE(width) \
static GenOpFunc *gen_op_l##width[] = { \
&gen_op_l##width##_raw, \
#define gen_op_stb_le_64_raw gen_op_stb_64_raw
#define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
#else
+/* User mode only - 32 bits */
#define OP_LD_TABLE(width) \
static GenOpFunc *gen_op_l##width[] = { \
&gen_op_l##width##_raw, \
#define gen_op_lbz_le_raw gen_op_lbz_raw
#else
#if defined(TARGET_PPC64)
+#if defined(TARGET_PPC64H)
+/* Full system - 64 bits with hypervisor mode */
#define OP_LD_TABLE(width) \
static GenOpFunc *gen_op_l##width[] = { \
&gen_op_l##width##_user, \
&gen_op_l##width##_le_user, \
- &gen_op_l##width##_kernel, \
- &gen_op_l##width##_le_kernel, \
&gen_op_l##width##_64_user, \
&gen_op_l##width##_le_64_user, \
+ &gen_op_l##width##_kernel, \
+ &gen_op_l##width##_le_kernel, \
&gen_op_l##width##_64_kernel, \
&gen_op_l##width##_le_64_kernel, \
+ &gen_op_l##width##_hypv, \
+ &gen_op_l##width##_le_hypv, \
+ &gen_op_l##width##_64_hypv, \
+ &gen_op_l##width##_le_64_hypv, \
};
#define OP_ST_TABLE(width) \
static GenOpFunc *gen_op_st##width[] = { \
&gen_op_st##width##_user, \
&gen_op_st##width##_le_user, \
+ &gen_op_st##width##_64_user, \
+ &gen_op_st##width##_le_64_user, \
&gen_op_st##width##_kernel, \
&gen_op_st##width##_le_kernel, \
+ &gen_op_st##width##_64_kernel, \
+ &gen_op_st##width##_le_64_kernel, \
+ &gen_op_st##width##_hypv, \
+ &gen_op_st##width##_le_hypv, \
+ &gen_op_st##width##_64_hypv, \
+ &gen_op_st##width##_le_64_hypv, \
+};
+/* Byte access routine are endian safe */
+#define gen_op_stb_le_hypv gen_op_stb_64_hypv
+#define gen_op_lbz_le_hypv gen_op_lbz_64_hypv
+#define gen_op_stb_le_64_hypv gen_op_stb_64_hypv
+#define gen_op_lbz_le_64_hypv gen_op_lbz_64_hypv
+#else
+/* Full system - 64 bits */
+#define OP_LD_TABLE(width) \
+static GenOpFunc *gen_op_l##width[] = { \
+ &gen_op_l##width##_user, \
+ &gen_op_l##width##_le_user, \
+ &gen_op_l##width##_64_user, \
+ &gen_op_l##width##_le_64_user, \
+ &gen_op_l##width##_kernel, \
+ &gen_op_l##width##_le_kernel, \
+ &gen_op_l##width##_64_kernel, \
+ &gen_op_l##width##_le_64_kernel, \
+};
+#define OP_ST_TABLE(width) \
+static GenOpFunc *gen_op_st##width[] = { \
+ &gen_op_st##width##_user, \
+ &gen_op_st##width##_le_user, \
&gen_op_st##width##_64_user, \
&gen_op_st##width##_le_64_user, \
+ &gen_op_st##width##_kernel, \
+ &gen_op_st##width##_le_kernel, \
&gen_op_st##width##_64_kernel, \
&gen_op_st##width##_le_64_kernel, \
};
+#endif
/* Byte access routine are endian safe */
-#define gen_op_stb_le_64_user gen_op_stb_64_user
-#define gen_op_lbz_le_64_user gen_op_lbz_64_user
+#define gen_op_stb_le_64_user gen_op_stb_64_user
+#define gen_op_lbz_le_64_user gen_op_lbz_64_user
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
#else
+/* Full system - 32 bits */
#define OP_LD_TABLE(width) \
static GenOpFunc *gen_op_l##width[] = { \
&gen_op_l##width##_user, \
};
#endif
/* Byte access routine are endian safe */
-#define gen_op_stb_le_user gen_op_stb_user
-#define gen_op_lbz_le_user gen_op_lbz_user
+#define gen_op_stb_le_user gen_op_stb_user
+#define gen_op_lbz_le_user gen_op_lbz_user
#define gen_op_stb_le_kernel gen_op_stb_kernel
#define gen_op_lbz_le_kernel gen_op_lbz_kernel
#endif
/*** Integer load and store multiple ***/
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
-#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
+/* User-mode only */
static GenOpFunc1 *gen_op_lmw[] = {
&gen_op_lmw_raw,
&gen_op_lmw_le_raw,
+#if defined(TARGET_PPC64)
&gen_op_lmw_64_raw,
&gen_op_lmw_le_64_raw,
+#endif
};
static GenOpFunc1 *gen_op_stmw[] = {
+ &gen_op_stmw_raw,
+ &gen_op_stmw_le_raw,
+#if defined(TARGET_PPC64)
&gen_op_stmw_64_raw,
&gen_op_stmw_le_64_raw,
+#endif
};
#else
+#if defined(TARGET_PPC64)
+/* Full system - 64 bits mode */
static GenOpFunc1 *gen_op_lmw[] = {
&gen_op_lmw_user,
&gen_op_lmw_le_user,
- &gen_op_lmw_kernel,
- &gen_op_lmw_le_kernel,
&gen_op_lmw_64_user,
&gen_op_lmw_le_64_user,
+ &gen_op_lmw_kernel,
+ &gen_op_lmw_le_kernel,
&gen_op_lmw_64_kernel,
&gen_op_lmw_le_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_lmw_hypv,
+ &gen_op_lmw_le_hypv,
+ &gen_op_lmw_64_hypv,
+ &gen_op_lmw_le_64_hypv,
+#endif
};
static GenOpFunc1 *gen_op_stmw[] = {
&gen_op_stmw_user,
&gen_op_stmw_le_user,
- &gen_op_stmw_kernel,
- &gen_op_stmw_le_kernel,
&gen_op_stmw_64_user,
&gen_op_stmw_le_64_user,
+ &gen_op_stmw_kernel,
+ &gen_op_stmw_le_kernel,
&gen_op_stmw_64_kernel,
&gen_op_stmw_le_64_kernel,
-};
+#if defined(TARGET_PPC64H)
+ &gen_op_stmw_hypv,
+ &gen_op_stmw_le_hypv,
+ &gen_op_stmw_64_hypv,
+ &gen_op_stmw_le_64_hypv,
#endif
-#else
-#if defined(CONFIG_USER_ONLY)
-static GenOpFunc1 *gen_op_lmw[] = {
- &gen_op_lmw_raw,
- &gen_op_lmw_le_raw,
-};
-static GenOpFunc1 *gen_op_stmw[] = {
- &gen_op_stmw_raw,
- &gen_op_stmw_le_raw,
};
#else
+/* Full system - 32 bits mode */
static GenOpFunc1 *gen_op_lmw[] = {
&gen_op_lmw_user,
&gen_op_lmw_le_user,
/*** Integer load and store strings ***/
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
-#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
+/* User-mode only */
static GenOpFunc1 *gen_op_lswi[] = {
&gen_op_lswi_raw,
&gen_op_lswi_le_raw,
+#if defined(TARGET_PPC64)
&gen_op_lswi_64_raw,
&gen_op_lswi_le_64_raw,
+#endif
};
static GenOpFunc3 *gen_op_lswx[] = {
&gen_op_lswx_raw,
&gen_op_lswx_le_raw,
+#if defined(TARGET_PPC64)
&gen_op_lswx_64_raw,
&gen_op_lswx_le_64_raw,
+#endif
};
static GenOpFunc1 *gen_op_stsw[] = {
&gen_op_stsw_raw,
&gen_op_stsw_le_raw,
+#if defined(TARGET_PPC64)
&gen_op_stsw_64_raw,
&gen_op_stsw_le_64_raw,
+#endif
};
#else
+#if defined(TARGET_PPC64)
+/* Full system - 64 bits mode */
static GenOpFunc1 *gen_op_lswi[] = {
&gen_op_lswi_user,
&gen_op_lswi_le_user,
- &gen_op_lswi_kernel,
- &gen_op_lswi_le_kernel,
&gen_op_lswi_64_user,
&gen_op_lswi_le_64_user,
+ &gen_op_lswi_kernel,
+ &gen_op_lswi_le_kernel,
&gen_op_lswi_64_kernel,
&gen_op_lswi_le_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_lswi_hypv,
+ &gen_op_lswi_le_hypv,
+ &gen_op_lswi_64_hypv,
+ &gen_op_lswi_le_64_hypv,
+#endif
};
static GenOpFunc3 *gen_op_lswx[] = {
&gen_op_lswx_user,
&gen_op_lswx_le_user,
- &gen_op_lswx_kernel,
- &gen_op_lswx_le_kernel,
&gen_op_lswx_64_user,
&gen_op_lswx_le_64_user,
+ &gen_op_lswx_kernel,
+ &gen_op_lswx_le_kernel,
&gen_op_lswx_64_kernel,
&gen_op_lswx_le_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_lswx_hypv,
+ &gen_op_lswx_le_hypv,
+ &gen_op_lswx_64_hypv,
+ &gen_op_lswx_le_64_hypv,
+#endif
};
static GenOpFunc1 *gen_op_stsw[] = {
&gen_op_stsw_user,
&gen_op_stsw_le_user,
- &gen_op_stsw_kernel,
- &gen_op_stsw_le_kernel,
&gen_op_stsw_64_user,
&gen_op_stsw_le_64_user,
+ &gen_op_stsw_kernel,
+ &gen_op_stsw_le_kernel,
&gen_op_stsw_64_kernel,
&gen_op_stsw_le_64_kernel,
-};
+#if defined(TARGET_PPC64H)
+ &gen_op_stsw_hypv,
+ &gen_op_stsw_le_hypv,
+ &gen_op_stsw_64_hypv,
+ &gen_op_stsw_le_64_hypv,
#endif
-#else
-#if defined(CONFIG_USER_ONLY)
-static GenOpFunc1 *gen_op_lswi[] = {
- &gen_op_lswi_raw,
- &gen_op_lswi_le_raw,
-};
-static GenOpFunc3 *gen_op_lswx[] = {
- &gen_op_lswx_raw,
- &gen_op_lswx_le_raw,
-};
-static GenOpFunc1 *gen_op_stsw[] = {
- &gen_op_stsw_raw,
- &gen_op_stsw_le_raw,
};
#else
+/* Full system - 32 bits mode */
static GenOpFunc1 *gen_op_lswi[] = {
&gen_op_lswi_user,
&gen_op_lswi_le_user,
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
-#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
+/* User-mode only */
static GenOpFunc *gen_op_lwarx[] = {
&gen_op_lwarx_raw,
&gen_op_lwarx_le_raw,
+#if defined(TARGET_PPC64)
&gen_op_lwarx_64_raw,
&gen_op_lwarx_le_64_raw,
+#endif
};
static GenOpFunc *gen_op_stwcx[] = {
&gen_op_stwcx_raw,
&gen_op_stwcx_le_raw,
+#if defined(TARGET_PPC64)
&gen_op_stwcx_64_raw,
&gen_op_stwcx_le_64_raw,
+#endif
};
#else
+#if defined(TARGET_PPC64)
+/* Full system - 64 bits mode */
static GenOpFunc *gen_op_lwarx[] = {
&gen_op_lwarx_user,
&gen_op_lwarx_le_user,
- &gen_op_lwarx_kernel,
- &gen_op_lwarx_le_kernel,
&gen_op_lwarx_64_user,
&gen_op_lwarx_le_64_user,
+ &gen_op_lwarx_kernel,
+ &gen_op_lwarx_le_kernel,
&gen_op_lwarx_64_kernel,
&gen_op_lwarx_le_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_lwarx_hypv,
+ &gen_op_lwarx_le_hypv,
+ &gen_op_lwarx_64_hypv,
+ &gen_op_lwarx_le_64_hypv,
+#endif
};
static GenOpFunc *gen_op_stwcx[] = {
&gen_op_stwcx_user,
&gen_op_stwcx_le_user,
- &gen_op_stwcx_kernel,
- &gen_op_stwcx_le_kernel,
&gen_op_stwcx_64_user,
&gen_op_stwcx_le_64_user,
+ &gen_op_stwcx_kernel,
+ &gen_op_stwcx_le_kernel,
&gen_op_stwcx_64_kernel,
&gen_op_stwcx_le_64_kernel,
-};
+#if defined(TARGET_PPC64H)
+ &gen_op_stwcx_hypv,
+ &gen_op_stwcx_le_hypv,
+ &gen_op_stwcx_64_hypv,
+ &gen_op_stwcx_le_64_hypv,
#endif
-#else
-#if defined(CONFIG_USER_ONLY)
-static GenOpFunc *gen_op_lwarx[] = {
- &gen_op_lwarx_raw,
- &gen_op_lwarx_le_raw,
-};
-static GenOpFunc *gen_op_stwcx[] = {
- &gen_op_stwcx_raw,
- &gen_op_stwcx_le_raw,
};
#else
+/* Full system - 32 bits mode */
static GenOpFunc *gen_op_lwarx[] = {
&gen_op_lwarx_user,
&gen_op_lwarx_le_user,
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
#if defined(CONFIG_USER_ONLY)
+/* User-mode only */
static GenOpFunc *gen_op_ldarx[] = {
&gen_op_ldarx_raw,
&gen_op_ldarx_le_raw,
&gen_op_stdcx_le_64_raw,
};
#else
+/* Full system */
static GenOpFunc *gen_op_ldarx[] = {
&gen_op_ldarx_user,
&gen_op_ldarx_le_user,
- &gen_op_ldarx_kernel,
- &gen_op_ldarx_le_kernel,
&gen_op_ldarx_64_user,
&gen_op_ldarx_le_64_user,
+ &gen_op_ldarx_kernel,
+ &gen_op_ldarx_le_kernel,
&gen_op_ldarx_64_kernel,
&gen_op_ldarx_le_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_ldarx_hypv,
+ &gen_op_ldarx_le_hypv,
+ &gen_op_ldarx_64_hypv,
+ &gen_op_ldarx_le_64_hypv,
+#endif
};
static GenOpFunc *gen_op_stdcx[] = {
&gen_op_stdcx_user,
&gen_op_stdcx_le_user,
- &gen_op_stdcx_kernel,
- &gen_op_stdcx_le_kernel,
&gen_op_stdcx_64_user,
&gen_op_stdcx_le_64_user,
+ &gen_op_stdcx_kernel,
+ &gen_op_stdcx_le_kernel,
&gen_op_stdcx_64_kernel,
&gen_op_stdcx_le_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_stdcx_hypv,
+ &gen_op_stdcx_le_hypv,
+ &gen_op_stdcx_64_hypv,
+ &gen_op_stdcx_le_64_hypv,
+#endif
};
#endif
GEN_STXF(fiwx, 0x17, 0x1E, PPC_FLOAT_STFIWX);
/*** Branch ***/
-static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)
+static always_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)
+static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
{
#if defined(TARGET_PPC64)
if (ctx->sf_mode != 0 && (nip >> 32))
#define BCOND_LR 1
#define BCOND_CTR 2
-static inline void gen_bcond (DisasContext *ctx, int type)
+static always_inline void gen_bcond (DisasContext *ctx, int type)
{
target_ulong target = 0;
target_ulong li;
#endif
/* sc */
+#if defined(CONFIG_USER_ONLY)
+#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
+#else
+#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
+#endif
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
{
uint32_t lev;
lev = (ctx->opcode >> 5) & 0x7F;
-#if defined(CONFIG_USER_ONLY)
- GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL_USER, lev);
-#else
- GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL, lev);
-#endif
+ GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
}
/*** Trap ***/
#endif
/* mfspr */
-static inline void gen_op_mfspr (DisasContext *ctx)
+static always_inline void gen_op_mfspr (DisasContext *ctx)
{
void (*read_cb)(void *opaque, int sprn);
uint32_t sprn = SPR(ctx->opcode);
}
/* dcbz */
-#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
-#if defined(TARGET_PPC64)
+#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
#if defined(CONFIG_USER_ONLY)
-static GenOpFunc *gen_op_dcbz[] = {
- &gen_op_dcbz_raw,
- &gen_op_dcbz_raw,
- &gen_op_dcbz_64_raw,
- &gen_op_dcbz_64_raw,
+/* User-mode only */
+static GenOpFunc *gen_op_dcbz[4][4] = {
+ {
+ &gen_op_dcbz_l32_raw,
+ &gen_op_dcbz_l32_raw,
+#if defined(TARGET_PPC64)
+ &gen_op_dcbz_l32_64_raw,
+ &gen_op_dcbz_l32_64_raw,
+#endif
+ },
+ {
+ &gen_op_dcbz_l64_raw,
+ &gen_op_dcbz_l64_raw,
+#if defined(TARGET_PPC64)
+ &gen_op_dcbz_l64_64_raw,
+ &gen_op_dcbz_l64_64_raw,
+#endif
+ },
+ {
+ &gen_op_dcbz_l128_raw,
+ &gen_op_dcbz_l128_raw,
+#if defined(TARGET_PPC64)
+ &gen_op_dcbz_l128_64_raw,
+ &gen_op_dcbz_l128_64_raw,
+#endif
+ },
+ {
+ &gen_op_dcbz_raw,
+ &gen_op_dcbz_raw,
+#if defined(TARGET_PPC64)
+ &gen_op_dcbz_64_raw,
+ &gen_op_dcbz_64_raw,
+#endif
+ },
};
#else
-static GenOpFunc *gen_op_dcbz[] = {
- &gen_op_dcbz_user,
- &gen_op_dcbz_user,
- &gen_op_dcbz_kernel,
- &gen_op_dcbz_kernel,
- &gen_op_dcbz_64_user,
- &gen_op_dcbz_64_user,
- &gen_op_dcbz_64_kernel,
- &gen_op_dcbz_64_kernel,
-};
+#if defined(TARGET_PPC64)
+/* Full system - 64 bits mode */
+static GenOpFunc *gen_op_dcbz[4][12] = {
+ {
+ &gen_op_dcbz_l32_user,
+ &gen_op_dcbz_l32_user,
+ &gen_op_dcbz_l32_64_user,
+ &gen_op_dcbz_l32_64_user,
+ &gen_op_dcbz_l32_kernel,
+ &gen_op_dcbz_l32_kernel,
+ &gen_op_dcbz_l32_64_kernel,
+ &gen_op_dcbz_l32_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_dcbz_l32_hypv,
+ &gen_op_dcbz_l32_hypv,
+ &gen_op_dcbz_l32_64_hypv,
+ &gen_op_dcbz_l32_64_hypv,
+#endif
+ },
+ {
+ &gen_op_dcbz_l64_user,
+ &gen_op_dcbz_l64_user,
+ &gen_op_dcbz_l64_64_user,
+ &gen_op_dcbz_l64_64_user,
+ &gen_op_dcbz_l64_kernel,
+ &gen_op_dcbz_l64_kernel,
+ &gen_op_dcbz_l64_64_kernel,
+ &gen_op_dcbz_l64_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_dcbz_l64_hypv,
+ &gen_op_dcbz_l64_hypv,
+ &gen_op_dcbz_l64_64_hypv,
+ &gen_op_dcbz_l64_64_hypv,
+#endif
+ },
+ {
+ &gen_op_dcbz_l128_user,
+ &gen_op_dcbz_l128_user,
+ &gen_op_dcbz_l128_64_user,
+ &gen_op_dcbz_l128_64_user,
+ &gen_op_dcbz_l128_kernel,
+ &gen_op_dcbz_l128_kernel,
+ &gen_op_dcbz_l128_64_kernel,
+ &gen_op_dcbz_l128_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_dcbz_l128_hypv,
+ &gen_op_dcbz_l128_hypv,
+ &gen_op_dcbz_l128_64_hypv,
+ &gen_op_dcbz_l128_64_hypv,
+#endif
+ },
+ {
+ &gen_op_dcbz_user,
+ &gen_op_dcbz_user,
+ &gen_op_dcbz_64_user,
+ &gen_op_dcbz_64_user,
+ &gen_op_dcbz_kernel,
+ &gen_op_dcbz_kernel,
+ &gen_op_dcbz_64_kernel,
+ &gen_op_dcbz_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_dcbz_hypv,
+ &gen_op_dcbz_hypv,
+ &gen_op_dcbz_64_hypv,
+ &gen_op_dcbz_64_hypv,
#endif
-#else
-#if defined(CONFIG_USER_ONLY)
-static GenOpFunc *gen_op_dcbz[] = {
- &gen_op_dcbz_raw,
- &gen_op_dcbz_raw,
+ },
};
#else
-static GenOpFunc *gen_op_dcbz[] = {
- &gen_op_dcbz_user,
- &gen_op_dcbz_user,
- &gen_op_dcbz_kernel,
- &gen_op_dcbz_kernel,
+/* Full system - 32 bits mode */
+static GenOpFunc *gen_op_dcbz[4][4] = {
+ {
+ &gen_op_dcbz_l32_user,
+ &gen_op_dcbz_l32_user,
+ &gen_op_dcbz_l32_kernel,
+ &gen_op_dcbz_l32_kernel,
+ },
+ {
+ &gen_op_dcbz_l64_user,
+ &gen_op_dcbz_l64_user,
+ &gen_op_dcbz_l64_kernel,
+ &gen_op_dcbz_l64_kernel,
+ },
+ {
+ &gen_op_dcbz_l128_user,
+ &gen_op_dcbz_l128_user,
+ &gen_op_dcbz_l128_kernel,
+ &gen_op_dcbz_l128_kernel,
+ },
+ {
+ &gen_op_dcbz_user,
+ &gen_op_dcbz_user,
+ &gen_op_dcbz_kernel,
+ &gen_op_dcbz_kernel,
+ },
};
#endif
#endif
-GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
+static always_inline void handler_dcbz (DisasContext *ctx,
+ int dcache_line_size)
+{
+ int n;
+
+ switch (dcache_line_size) {
+ case 32:
+ n = 0;
+ break;
+ case 64:
+ n = 1;
+ break;
+ case 128:
+ n = 2;
+ break;
+ default:
+ n = 3;
+ break;
+ }
+ op_dcbz(n);
+}
+
+GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
{
gen_addr_reg_index(ctx);
- op_dcbz();
+ handler_dcbz(ctx, ctx->dcache_line_size);
+ gen_op_check_reservation();
+}
+
+GEN_HANDLER(dcbz_970, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
+{
+ gen_addr_reg_index(ctx);
+ if (ctx->opcode & 0x00200000)
+ handler_dcbz(ctx, ctx->dcache_line_size);
+ else
+ handler_dcbz(ctx, -1);
gen_op_check_reservation();
}
/* icbi */
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
-#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
+/* User-mode only */
static GenOpFunc *gen_op_icbi[] = {
&gen_op_icbi_raw,
&gen_op_icbi_raw,
+#if defined(TARGET_PPC64)
&gen_op_icbi_64_raw,
&gen_op_icbi_64_raw,
+#endif
};
#else
+/* Full system - 64 bits mode */
+#if defined(TARGET_PPC64)
static GenOpFunc *gen_op_icbi[] = {
&gen_op_icbi_user,
&gen_op_icbi_user,
- &gen_op_icbi_kernel,
- &gen_op_icbi_kernel,
&gen_op_icbi_64_user,
&gen_op_icbi_64_user,
+ &gen_op_icbi_kernel,
+ &gen_op_icbi_kernel,
&gen_op_icbi_64_kernel,
&gen_op_icbi_64_kernel,
-};
+#if defined(TARGET_PPC64H)
+ &gen_op_icbi_hypv,
+ &gen_op_icbi_hypv,
+ &gen_op_icbi_64_hypv,
+ &gen_op_icbi_64_hypv,
#endif
-#else
-#if defined(CONFIG_USER_ONLY)
-static GenOpFunc *gen_op_icbi[] = {
- &gen_op_icbi_raw,
- &gen_op_icbi_raw,
};
#else
+/* Full system - 32 bits mode */
static GenOpFunc *gen_op_icbi[] = {
&gen_op_icbi_user,
&gen_op_icbi_user,
#endif
}
+#if defined(TARGET_PPC64)
+/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
+/* mfsr */
+GEN_HANDLER(mfsr_64b, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_EXCP_PRIVREG(ctx);
+#else
+ if (unlikely(!ctx->supervisor)) {
+ GEN_EXCP_PRIVREG(ctx);
+ return;
+ }
+ gen_op_set_T1(SR(ctx->opcode));
+ gen_op_load_slb();
+ gen_op_store_T0_gpr(rD(ctx->opcode));
+#endif
+}
+
+/* mfsrin */
+GEN_HANDLER(mfsrin_64b, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT_64B)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_EXCP_PRIVREG(ctx);
+#else
+ if (unlikely(!ctx->supervisor)) {
+ GEN_EXCP_PRIVREG(ctx);
+ return;
+ }
+ gen_op_load_gpr_T1(rB(ctx->opcode));
+ gen_op_srli_T1(28);
+ gen_op_load_slb();
+ gen_op_store_T0_gpr(rD(ctx->opcode));
+#endif
+}
+
+/* mtsr */
+GEN_HANDLER(mtsr_64b, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_EXCP_PRIVREG(ctx);
+#else
+ if (unlikely(!ctx->supervisor)) {
+ GEN_EXCP_PRIVREG(ctx);
+ return;
+ }
+ gen_op_load_gpr_T0(rS(ctx->opcode));
+ gen_op_set_T1(SR(ctx->opcode));
+ gen_op_store_slb();
+#endif
+}
+
+/* mtsrin */
+GEN_HANDLER(mtsrin_64b, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT_64B)
+{
+#if defined(CONFIG_USER_ONLY)
+ GEN_EXCP_PRIVREG(ctx);
+#else
+ if (unlikely(!ctx->supervisor)) {
+ 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_slb();
+#endif
+}
+#endif /* defined(TARGET_PPC64) */
+
/*** Lookaside buffer management ***/
/* Optional & supervisor only: */
/* tlbia */
/* Optional: */
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
-#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
+/* User-mode only */
static GenOpFunc *gen_op_eciwx[] = {
&gen_op_eciwx_raw,
&gen_op_eciwx_le_raw,
+#if defined(TARGET_PPC64)
&gen_op_eciwx_64_raw,
&gen_op_eciwx_le_64_raw,
+#endif
};
static GenOpFunc *gen_op_ecowx[] = {
&gen_op_ecowx_raw,
&gen_op_ecowx_le_raw,
+#if defined(TARGET_PPC64)
&gen_op_ecowx_64_raw,
&gen_op_ecowx_le_64_raw,
+#endif
};
#else
+#if defined(TARGET_PPC64)
+/* Full system - 64 bits mode */
static GenOpFunc *gen_op_eciwx[] = {
&gen_op_eciwx_user,
&gen_op_eciwx_le_user,
- &gen_op_eciwx_kernel,
- &gen_op_eciwx_le_kernel,
&gen_op_eciwx_64_user,
&gen_op_eciwx_le_64_user,
+ &gen_op_eciwx_kernel,
+ &gen_op_eciwx_le_kernel,
&gen_op_eciwx_64_kernel,
&gen_op_eciwx_le_64_kernel,
+#if defined(TARGET_PPC64H)
+ &gen_op_eciwx_hypv,
+ &gen_op_eciwx_le_hypv,
+ &gen_op_eciwx_64_hypv,
+ &gen_op_eciwx_le_64_hypv,
+#endif
};
static GenOpFunc *gen_op_ecowx[] = {
&gen_op_ecowx_user,
&gen_op_ecowx_le_user,
- &gen_op_ecowx_kernel,
- &gen_op_ecowx_le_kernel,
&gen_op_ecowx_64_user,
&gen_op_ecowx_le_64_user,
+ &gen_op_ecowx_kernel,
+ &gen_op_ecowx_le_kernel,
&gen_op_ecowx_64_kernel,
&gen_op_ecowx_le_64_kernel,
-};
+#if defined(TARGET_PPC64H)
+ &gen_op_ecowx_hypv,
+ &gen_op_ecowx_le_hypv,
+ &gen_op_ecowx_64_hypv,
+ &gen_op_ecowx_le_64_hypv,
#endif
-#else
-#if defined(CONFIG_USER_ONLY)
-static GenOpFunc *gen_op_eciwx[] = {
- &gen_op_eciwx_raw,
- &gen_op_eciwx_le_raw,
-};
-static GenOpFunc *gen_op_ecowx[] = {
- &gen_op_ecowx_raw,
- &gen_op_ecowx_le_raw,
};
#else
+/* Full system - 32 bits mode */
static GenOpFunc *gen_op_eciwx[] = {
&gen_op_eciwx_user,
&gen_op_eciwx_le_user,
}
/* As lscbx load from memory byte after byte, it's always endian safe */
-#define op_POWER_lscbx(start, ra, rb) \
+#define op_POWER_lscbx(start, ra, rb) \
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
#if defined(CONFIG_USER_ONLY)
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
}
/* All 405 MAC instructions are translated here */
-static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
- int ra, int rb, int rt, int Rc)
+static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
+ int opc2, int opc3,
+ int ra, int rb, int rt, int Rc)
{
gen_op_load_gpr_T0(ra);
gen_op_load_gpr_T1(rb);
*/
}
+/*** Altivec vector extension ***/
+/* Altivec registers moves */
+GEN32(gen_op_load_avr_A0, gen_op_load_avr_A0_avr);
+GEN32(gen_op_load_avr_A1, gen_op_load_avr_A1_avr);
+GEN32(gen_op_load_avr_A2, gen_op_load_avr_A2_avr);
+
+GEN32(gen_op_store_A0_avr, gen_op_store_A0_avr_avr);
+GEN32(gen_op_store_A1_avr, gen_op_store_A1_avr_avr);
+#if 0 // unused
+GEN32(gen_op_store_A2_avr, gen_op_store_A2_avr_avr);
+#endif
+
+#define op_vr_ldst(name) (*gen_op_##name[ctx->mem_idx])()
+#if defined(CONFIG_USER_ONLY)
+#if defined(TARGET_PPC64)
+/* User-mode only - 64 bits mode */
+#define OP_VR_LD_TABLE(name) \
+static GenOpFunc *gen_op_vr_l##name[] = { \
+ &gen_op_vr_l##name##_raw, \
+ &gen_op_vr_l##name##_le_raw, \
+ &gen_op_vr_l##name##_64_raw, \
+ &gen_op_vr_l##name##_le_64_raw, \
+};
+#define OP_VR_ST_TABLE(name) \
+static GenOpFunc *gen_op_vr_st##name[] = { \
+ &gen_op_vr_st##name##_raw, \
+ &gen_op_vr_st##name##_le_raw, \
+ &gen_op_vr_st##name##_64_raw, \
+ &gen_op_vr_st##name##_le_64_raw, \
+};
+#else /* defined(TARGET_PPC64) */
+/* User-mode only - 32 bits mode */
+#define OP_VR_LD_TABLE(name) \
+static GenOpFunc *gen_op_vr_l##name[] = { \
+ &gen_op_vr_l##name##_raw, \
+ &gen_op_vr_l##name##_le_raw, \
+};
+#define OP_VR_ST_TABLE(name) \
+static GenOpFunc *gen_op_vr_st##name[] = { \
+ &gen_op_vr_st##name##_raw, \
+ &gen_op_vr_st##name##_le_raw, \
+};
+#endif /* defined(TARGET_PPC64) */
+#else /* defined(CONFIG_USER_ONLY) */
+#if defined(TARGET_PPC64H)
+/* Full system with hypervisor mode */
+#define OP_VR_LD_TABLE(name) \
+static GenOpFunc *gen_op_vr_l##name[] = { \
+ &gen_op_vr_l##name##_user, \
+ &gen_op_vr_l##name##_le_user, \
+ &gen_op_vr_l##name##_64_user, \
+ &gen_op_vr_l##name##_le_64_user, \
+ &gen_op_vr_l##name##_kernel, \
+ &gen_op_vr_l##name##_le_kernel, \
+ &gen_op_vr_l##name##_64_kernel, \
+ &gen_op_vr_l##name##_le_64_kernel, \
+ &gen_op_vr_l##name##_hypv, \
+ &gen_op_vr_l##name##_le_hypv, \
+ &gen_op_vr_l##name##_64_hypv, \
+ &gen_op_vr_l##name##_le_64_hypv, \
+};
+#define OP_VR_ST_TABLE(name) \
+static GenOpFunc *gen_op_vr_st##name[] = { \
+ &gen_op_vr_st##name##_user, \
+ &gen_op_vr_st##name##_le_user, \
+ &gen_op_vr_st##name##_64_user, \
+ &gen_op_vr_st##name##_le_64_user, \
+ &gen_op_vr_st##name##_kernel, \
+ &gen_op_vr_st##name##_le_kernel, \
+ &gen_op_vr_st##name##_64_kernel, \
+ &gen_op_vr_st##name##_le_64_kernel, \
+ &gen_op_vr_st##name##_hypv, \
+ &gen_op_vr_st##name##_le_hypv, \
+ &gen_op_vr_st##name##_64_hypv, \
+ &gen_op_vr_st##name##_le_64_hypv, \
+};
+#elif defined(TARGET_PPC64)
+/* Full system - 64 bits mode */
+#define OP_VR_LD_TABLE(name) \
+static GenOpFunc *gen_op_vr_l##name[] = { \
+ &gen_op_vr_l##name##_user, \
+ &gen_op_vr_l##name##_le_user, \
+ &gen_op_vr_l##name##_64_user, \
+ &gen_op_vr_l##name##_le_64_user, \
+ &gen_op_vr_l##name##_kernel, \
+ &gen_op_vr_l##name##_le_kernel, \
+ &gen_op_vr_l##name##_64_kernel, \
+ &gen_op_vr_l##name##_le_64_kernel, \
+};
+#define OP_VR_ST_TABLE(name) \
+static GenOpFunc *gen_op_vr_st##name[] = { \
+ &gen_op_vr_st##name##_user, \
+ &gen_op_vr_st##name##_le_user, \
+ &gen_op_vr_st##name##_64_user, \
+ &gen_op_vr_st##name##_le_64_user, \
+ &gen_op_vr_st##name##_kernel, \
+ &gen_op_vr_st##name##_le_kernel, \
+ &gen_op_vr_st##name##_64_kernel, \
+ &gen_op_vr_st##name##_le_64_kernel, \
+};
+#else /* defined(TARGET_PPC64) */
+/* Full system - 32 bits mode */
+#define OP_VR_LD_TABLE(name) \
+static GenOpFunc *gen_op_vr_l##name[] = { \
+ &gen_op_vr_l##name##_user, \
+ &gen_op_vr_l##name##_le_user, \
+ &gen_op_vr_l##name##_kernel, \
+ &gen_op_vr_l##name##_le_kernel, \
+};
+#define OP_VR_ST_TABLE(name) \
+static GenOpFunc *gen_op_vr_st##name[] = { \
+ &gen_op_vr_st##name##_user, \
+ &gen_op_vr_st##name##_le_user, \
+ &gen_op_vr_st##name##_kernel, \
+ &gen_op_vr_st##name##_le_kernel, \
+};
+#endif /* defined(TARGET_PPC64) */
+#endif /* defined(CONFIG_USER_ONLY) */
+
+#define GEN_VR_LDX(name, opc2, opc3) \
+GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \
+{ \
+ if (unlikely(!ctx->altivec_enabled)) { \
+ GEN_EXCP_NO_VR(ctx); \
+ return; \
+ } \
+ gen_addr_reg_index(ctx); \
+ op_vr_ldst(vr_l##name); \
+ gen_op_store_A0_avr(rD(ctx->opcode)); \
+}
+
+#define GEN_VR_STX(name, opc2, opc3) \
+GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \
+{ \
+ if (unlikely(!ctx->altivec_enabled)) { \
+ GEN_EXCP_NO_VR(ctx); \
+ return; \
+ } \
+ gen_addr_reg_index(ctx); \
+ gen_op_load_avr_A0(rS(ctx->opcode)); \
+ op_vr_ldst(vr_st##name); \
+}
+
+OP_VR_LD_TABLE(vx);
+GEN_VR_LDX(vx, 0x07, 0x03);
+/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
+#define gen_op_vr_lvxl gen_op_vr_lvx
+GEN_VR_LDX(vxl, 0x07, 0x0B);
+
+OP_VR_ST_TABLE(vx);
+GEN_VR_STX(vx, 0x07, 0x07);
+/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
+#define gen_op_vr_stvxl gen_op_vr_stvx
+GEN_VR_STX(vxl, 0x07, 0x0F);
+
#if defined(TARGET_PPCEMB)
/*** SPE extension ***/
}
/* Handler for undefined SPE opcodes */
-static inline void gen_speundef (DisasContext *ctx)
+static always_inline void gen_speundef (DisasContext *ctx)
{
GEN_EXCP_INVAL(ctx);
}
/* SPE load and stores */
-static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
+static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
{
target_long simm = rB(ctx->opcode);
#define op_spe_ldst(name) (*gen_op_##name[ctx->mem_idx])()
#if defined(CONFIG_USER_ONLY)
#if defined(TARGET_PPC64)
+/* User-mode only - 64 bits mode */
#define OP_SPE_LD_TABLE(name) \
static GenOpFunc *gen_op_spe_l##name[] = { \
&gen_op_spe_l##name##_raw, \
&gen_op_spe_st##name##_le_64_raw, \
};
#else /* defined(TARGET_PPC64) */
+/* User-mode only - 32 bits mode */
#define OP_SPE_LD_TABLE(name) \
static GenOpFunc *gen_op_spe_l##name[] = { \
&gen_op_spe_l##name##_raw, \
};
#endif /* defined(TARGET_PPC64) */
#else /* defined(CONFIG_USER_ONLY) */
-#if defined(TARGET_PPC64)
+#if defined(TARGET_PPC64H)
+/* Full system with hypervisor mode */
#define OP_SPE_LD_TABLE(name) \
static GenOpFunc *gen_op_spe_l##name[] = { \
&gen_op_spe_l##name##_user, \
&gen_op_spe_l##name##_le_user, \
- &gen_op_spe_l##name##_kernel, \
- &gen_op_spe_l##name##_le_kernel, \
&gen_op_spe_l##name##_64_user, \
&gen_op_spe_l##name##_le_64_user, \
+ &gen_op_spe_l##name##_kernel, \
+ &gen_op_spe_l##name##_le_kernel, \
&gen_op_spe_l##name##_64_kernel, \
&gen_op_spe_l##name##_le_64_kernel, \
+ &gen_op_spe_l##name##_hypv, \
+ &gen_op_spe_l##name##_le_hypv, \
+ &gen_op_spe_l##name##_64_hypv, \
+ &gen_op_spe_l##name##_le_64_hypv, \
};
#define OP_SPE_ST_TABLE(name) \
static GenOpFunc *gen_op_spe_st##name[] = { \
&gen_op_spe_st##name##_user, \
&gen_op_spe_st##name##_le_user, \
+ &gen_op_spe_st##name##_64_user, \
+ &gen_op_spe_st##name##_le_64_user, \
&gen_op_spe_st##name##_kernel, \
&gen_op_spe_st##name##_le_kernel, \
+ &gen_op_spe_st##name##_64_kernel, \
+ &gen_op_spe_st##name##_le_64_kernel, \
+ &gen_op_spe_st##name##_hypv, \
+ &gen_op_spe_st##name##_le_hypv, \
+ &gen_op_spe_st##name##_64_hypv, \
+ &gen_op_spe_st##name##_le_64_hypv, \
+};
+#elif defined(TARGET_PPC64)
+/* Full system - 64 bits mode */
+#define OP_SPE_LD_TABLE(name) \
+static GenOpFunc *gen_op_spe_l##name[] = { \
+ &gen_op_spe_l##name##_user, \
+ &gen_op_spe_l##name##_le_user, \
+ &gen_op_spe_l##name##_64_user, \
+ &gen_op_spe_l##name##_le_64_user, \
+ &gen_op_spe_l##name##_kernel, \
+ &gen_op_spe_l##name##_le_kernel, \
+ &gen_op_spe_l##name##_64_kernel, \
+ &gen_op_spe_l##name##_le_64_kernel, \
+};
+#define OP_SPE_ST_TABLE(name) \
+static GenOpFunc *gen_op_spe_st##name[] = { \
+ &gen_op_spe_st##name##_user, \
+ &gen_op_spe_st##name##_le_user, \
&gen_op_spe_st##name##_64_user, \
&gen_op_spe_st##name##_le_64_user, \
+ &gen_op_spe_st##name##_kernel, \
+ &gen_op_spe_st##name##_le_kernel, \
&gen_op_spe_st##name##_64_kernel, \
&gen_op_spe_st##name##_le_64_kernel, \
};
#else /* defined(TARGET_PPC64) */
+/* Full system - 32 bits mode */
#define OP_SPE_LD_TABLE(name) \
static GenOpFunc *gen_op_spe_l##name[] = { \
&gen_op_spe_l##name##_user, \
#endif /* defined(CONFIG_USER_ONLY) */
#define GEN_SPE_LD(name, sh) \
-static inline void gen_evl##name (DisasContext *ctx) \
+static always_inline void gen_evl##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
}
#define GEN_SPE_LDX(name) \
-static inline void gen_evl##name##x (DisasContext *ctx) \
+static always_inline void gen_evl##name##x (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
GEN_SPE_LDX(name)
#define GEN_SPE_ST(name, sh) \
-static inline void gen_evst##name (DisasContext *ctx) \
+static always_inline void gen_evst##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
}
#define GEN_SPE_STX(name) \
-static inline void gen_evst##name##x (DisasContext *ctx) \
+static always_inline void gen_evst##name##x (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
/* SPE arithmetic and logic */
#define GEN_SPEOP_ARITH2(name) \
-static inline void gen_##name (DisasContext *ctx) \
+static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
}
#define GEN_SPEOP_ARITH1(name) \
-static inline void gen_##name (DisasContext *ctx) \
+static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
}
#define GEN_SPEOP_COMP(name) \
-static inline void gen_##name (DisasContext *ctx) \
+static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
GEN_SPEOP_ARITH1(evrndw);
GEN_SPEOP_ARITH1(evcntlzw);
GEN_SPEOP_ARITH1(evcntlsw);
-static inline void gen_brinc (DisasContext *ctx)
+static always_inline void gen_brinc (DisasContext *ctx)
{
/* Note: brinc is usable even if SPE is disabled */
gen_op_load_gpr64_T0(rA(ctx->opcode));
}
#define GEN_SPEOP_ARITH_IMM2(name) \
-static inline void gen_##name##i (DisasContext *ctx) \
+static always_inline void gen_##name##i (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
}
#define GEN_SPEOP_LOGIC_IMM2(name) \
-static inline void gen_##name##i (DisasContext *ctx) \
+static always_inline void gen_##name##i (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
#define gen_evsrwiu gen_evsrwui
GEN_SPEOP_LOGIC_IMM2(evrlw);
-static inline void gen_evsplati (DisasContext *ctx)
+static always_inline void gen_evsplati (DisasContext *ctx)
{
int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
gen_op_store_T0_gpr64(rD(ctx->opcode));
}
-static inline void gen_evsplatfi (DisasContext *ctx)
+static always_inline void gen_evsplatfi (DisasContext *ctx)
{
uint32_t imm = rA(ctx->opcode) << 27;
GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, PPC_SPE); ////
GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, PPC_SPE); ////
-static inline void gen_evsel (DisasContext *ctx)
+static always_inline void gen_evsel (DisasContext *ctx)
{
if (unlikely(!ctx->spe_enabled)) {
GEN_EXCP_NO_AP(ctx);
#endif
#endif
#define _GEN_OP_SPE_STWWE(suffix) \
-static inline void gen_op_spe_stwwe_##suffix (void) \
+static always_inline void gen_op_spe_stwwe_##suffix (void) \
{ \
gen_op_srli32_T1_64(); \
gen_op_spe_stwwo_##suffix(); \
}
#define _GEN_OP_SPE_STWWE_LE(suffix) \
-static inline void gen_op_spe_stwwe_le_##suffix (void) \
+static always_inline void gen_op_spe_stwwe_le_##suffix (void) \
{ \
gen_op_srli32_T1_64(); \
gen_op_spe_stwwo_le_##suffix(); \
#define GEN_OP_SPE_STWWE(suffix) \
_GEN_OP_SPE_STWWE(suffix); \
_GEN_OP_SPE_STWWE_LE(suffix); \
-static inline void gen_op_spe_stwwe_64_##suffix (void) \
+static always_inline void gen_op_spe_stwwe_64_##suffix (void) \
{ \
gen_op_srli32_T1_64(); \
gen_op_spe_stwwo_64_##suffix(); \
} \
-static inline void gen_op_spe_stwwe_le_64_##suffix (void) \
+static always_inline void gen_op_spe_stwwe_le_64_##suffix (void) \
{ \
gen_op_srli32_T1_64(); \
gen_op_spe_stwwo_le_64_##suffix(); \
GEN_SPEOP_ST(wwo, 2);
#define GEN_SPE_LDSPLAT(name, op, suffix) \
-static inline void gen_op_spe_l##name##_##suffix (void) \
+static always_inline void gen_op_spe_l##name##_##suffix (void) \
{ \
gen_op_##op##_##suffix(); \
gen_op_splatw_T1_64(); \
}
#define GEN_OP_SPE_LHE(suffix) \
-static inline void gen_op_spe_lhe_##suffix (void) \
+static always_inline void gen_op_spe_lhe_##suffix (void) \
{ \
gen_op_spe_lh_##suffix(); \
gen_op_sli16_T1_64(); \
}
#define GEN_OP_SPE_LHX(suffix) \
-static inline void gen_op_spe_lhx_##suffix (void) \
+static always_inline void gen_op_spe_lhx_##suffix (void) \
{ \
gen_op_spe_lh_##suffix(); \
gen_op_extsh_T1_64(); \
/*** SPE floating-point extension ***/
#define GEN_SPEFPUOP_CONV(name) \
-static inline void gen_##name (DisasContext *ctx) \
+static always_inline void gen_##name (DisasContext *ctx) \
{ \
gen_op_load_gpr64_T0(rB(ctx->opcode)); \
gen_op_##name(); \
/*****************************************************************************/
/* Misc PowerPC helpers */
-static inline uint32_t load_xer (CPUState *env)
+static always_inline uint32_t load_xer (CPUState *env)
{
return (xer_so << XER_SO) |
(xer_ov << XER_OV) |
if ((i & (RFPL - 1)) == (RFPL - 1))
cpu_fprintf(f, "\n");
}
+#if !defined(CONFIG_USER_ONLY)
cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX " " FILL FILL FILL
"SDR1 " REGX "\n",
env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
+#endif
#undef RGPL
#undef RFPL
}
/*****************************************************************************/
-static inline int gen_intermediate_code_internal (CPUState *env,
- TranslationBlock *tb,
- int search_pc)
+static always_inline int gen_intermediate_code_internal (CPUState *env,
+ TranslationBlock *tb,
+ int search_pc)
{
DisasContext ctx, *ctxp = &ctx;
opc_handler_t **table, *handler;
target_ulong pc_start;
uint16_t *gen_opc_end;
+ int supervisor;
+ int single_step, branch_step;
int j, lj = -1;
pc_start = tb->pc;
ctx.exception = POWERPC_EXCP_NONE;
ctx.spr_cb = env->spr_cb;
#if defined(CONFIG_USER_ONLY)
- ctx.mem_idx = msr_le;
-#if defined(TARGET_PPC64)
- ctx.mem_idx |= msr_sf << 1;
-#endif
+ supervisor = 0;
#else
#if defined(TARGET_PPC64H)
if (msr_pr == 0 && msr_hv == 1)
- ctx.supervisor = 2;
+ supervisor = 2;
else
#endif
- ctx.supervisor = 1 - msr_pr;
- ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
-#if defined(TARGET_PPC64)
- ctx.mem_idx |= msr_sf << 2;
-#endif
+ supervisor = 1 - msr_pr;
+ ctx.supervisor = supervisor;
#endif
#if defined(TARGET_PPC64)
ctx.sf_mode = msr_sf;
+ ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | msr_le;
+#else
+ ctx.mem_idx = (supervisor << 1) | msr_le;
#endif
+ ctx.dcache_line_size = env->dcache_line_size;
ctx.fpu_enabled = msr_fp;
#if defined(TARGET_PPCEMB)
- ctx.spe_enabled = msr_spe;
+ if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
+ ctx.spe_enabled = msr_spe;
+ else
+ ctx.spe_enabled = 0;
#endif
- ctx.singlestep_enabled = env->singlestep_enabled;
+ if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
+ ctx.altivec_enabled = msr_vr;
+ else
+ ctx.altivec_enabled = 0;
+ if ((env->flags & POWERPC_FLAG_SE) && msr_se)
+ single_step = 1;
+ else
+ single_step = 0;
+ if ((env->flags & POWERPC_FLAG_BE) && msr_be)
+ branch_step = 1;
+ else
+ branch_step = 0;
+ ctx.singlestep_enabled = env->singlestep_enabled || single_step == 1;
#if defined (DO_SINGLE_STEP) && 0
/* Single step trace mode */
msr_se = 1;
handler->count++;
#endif
/* Check trace mode exceptions */
-#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
- * - first instruction of an exception handler
- */
- (msr_se && (ctx.nip < 0x100 ||
- ctx.nip > 0xF00 ||
- (ctx.nip & 0xFC) != 0x04) &&
-#if defined(CONFIG_USER_ONLY)
- ctx.exception != POWERPC_EXCP_SYSCALL_USER &&
-#else
- ctx.exception != POWERPC_EXCP_SYSCALL &&
-#endif
- ctx.exception != POWERPC_EXCP_TRAP))) {
+ if (unlikely(branch_step != 0 &&
+ ctx.exception == POWERPC_EXCP_BRANCH)) {
GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
- }
-#endif
- /* if we reach a page boundary or are single stepping, stop
- * generation
- */
- if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
- (env->singlestep_enabled))) {
+ } else if (unlikely(single_step != 0 &&
+ (ctx.nip <= 0x100 || ctx.nip > 0xF00 ||
+ (ctx.nip & 0xFC) != 0x04) &&
+ ctx.exception != POWERPC_SYSCALL &&
+ ctx.exception != POWERPC_EXCP_TRAP)) {
+ GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
+ } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
+ (env->singlestep_enabled))) {
+ /* if we reach a page boundary or are single stepping, stop
+ * generation
+ */
break;
}
#if defined (DO_SINGLE_STEP)