aboutsummaryrefslogtreecommitdiff
path: root/target/ppc/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/ppc/translate.c')
-rw-r--r--target/ppc/translate.c244
1 files changed, 86 insertions, 158 deletions
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 121218087f..b48abaedfb 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -422,157 +422,6 @@ typedef struct opcode_t {
#define CHK_NONE
-
-/*****************************************************************************/
-/*** Instruction decoding ***/
-#define EXTRACT_HELPER(name, shift, nb) \
-static 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) \
-{ \
- return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1)); \
-}
-
-#define EXTRACT_HELPER_SPLIT(name, shift1, nb1, shift2, nb2) \
-static inline uint32_t name(uint32_t opcode) \
-{ \
- 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(opc2, 1, 5);
-/* Opcode part 3 */
-EXTRACT_HELPER(opc3, 6, 5);
-/* Opcode part 4 */
-EXTRACT_HELPER(opc4, 16, 5);
-/* Update Cr0 flags */
-EXTRACT_HELPER(Rc, 0, 1);
-/* Update Cr6 flags (Altivec) */
-EXTRACT_HELPER(Rc21, 10, 1);
-/* Destination */
-EXTRACT_HELPER(rD, 21, 5);
-/* Source */
-EXTRACT_HELPER(rS, 21, 5);
-/* First operand */
-EXTRACT_HELPER(rA, 16, 5);
-/* Second operand */
-EXTRACT_HELPER(rB, 11, 5);
-/* Third operand */
-EXTRACT_HELPER(rC, 6, 5);
-/*** Get CRn ***/
-EXTRACT_HELPER(crfD, 23, 3);
-EXTRACT_HELPER(crfS, 18, 3);
-EXTRACT_HELPER(crbD, 21, 5);
-EXTRACT_HELPER(crbA, 16, 5);
-EXTRACT_HELPER(crbB, 11, 5);
-/* SPR / TBL */
-EXTRACT_HELPER(_SPR, 11, 10);
-static inline uint32_t SPR(uint32_t opcode)
-{
- uint32_t sprn = _SPR(opcode);
-
- return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
-}
-/*** Get constants ***/
-/* 16 bits signed immediate value */
-EXTRACT_SHELPER(SIMM, 0, 16);
-/* 16 bits unsigned immediate value */
-EXTRACT_HELPER(UIMM, 0, 16);
-/* 5 bits signed immediate value */
-EXTRACT_HELPER(SIMM5, 16, 5);
-/* 5 bits signed immediate value */
-EXTRACT_HELPER(UIMM5, 16, 5);
-/* 4 bits unsigned immediate value */
-EXTRACT_HELPER(UIMM4, 16, 4);
-/* Bit count */
-EXTRACT_HELPER(NB, 11, 5);
-/* Shift count */
-EXTRACT_HELPER(SH, 11, 5);
-/* Vector shift count */
-EXTRACT_HELPER(VSH, 6, 4);
-/* Mask start */
-EXTRACT_HELPER(MB, 6, 5);
-/* Mask end */
-EXTRACT_HELPER(ME, 1, 5);
-/* Trap operand */
-EXTRACT_HELPER(TO, 21, 5);
-
-EXTRACT_HELPER(CRM, 12, 8);
-
-#ifndef CONFIG_USER_ONLY
-EXTRACT_HELPER(SR, 16, 4);
-#endif
-
-/* mtfsf/mtfsfi */
-EXTRACT_HELPER(FPBF, 23, 3);
-EXTRACT_HELPER(FPIMM, 12, 4);
-EXTRACT_HELPER(FPL, 25, 1);
-EXTRACT_HELPER(FPFLM, 17, 8);
-EXTRACT_HELPER(FPW, 16, 1);
-
-/* addpcis */
-EXTRACT_HELPER_DXFORM(DX, 10, 6, 6, 5, 16, 1, 1, 0, 0)
-#if defined(TARGET_PPC64)
-/* darn */
-EXTRACT_HELPER(L, 16, 2);
-#endif
-
-/*** Jump target decoding ***/
-/* Immediate address */
-static inline target_ulong LI(uint32_t opcode)
-{
- return (opcode >> 0) & 0x03FFFFFC;
-}
-
-static inline uint32_t BD(uint32_t opcode)
-{
- return (opcode >> 0) & 0xFFFC;
-}
-
-EXTRACT_HELPER(BO, 21, 5);
-EXTRACT_HELPER(BI, 16, 5);
-/* Absolute/relative address */
-EXTRACT_HELPER(AA, 1, 1);
-/* Link */
-EXTRACT_HELPER(LK, 0, 1);
-
-/* DFP Z22-form */
-EXTRACT_HELPER(DCM, 10, 6)
-
-/* DFP Z23-form */
-EXTRACT_HELPER(RMC, 9, 2)
-
-EXTRACT_HELPER_SPLIT(xT, 0, 1, 21, 5);
-EXTRACT_HELPER_SPLIT(xS, 0, 1, 21, 5);
-EXTRACT_HELPER_SPLIT(xA, 2, 1, 16, 5);
-EXTRACT_HELPER_SPLIT(xB, 1, 1, 11, 5);
-EXTRACT_HELPER_SPLIT(xC, 3, 1, 6, 5);
-EXTRACT_HELPER(DM, 8, 2);
-EXTRACT_HELPER(UIM, 16, 2);
-EXTRACT_HELPER(SHW, 8, 2);
-EXTRACT_HELPER(SP, 19, 2);
-EXTRACT_HELPER(IMM8, 11, 8);
-
/*****************************************************************************/
/* PowerPC instructions table */
@@ -763,17 +612,17 @@ static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
tcg_gen_setcond_tl((s ? TCG_COND_LT: TCG_COND_LTU), t0, arg0, arg1);
tcg_gen_trunc_tl_i32(t1, t0);
- tcg_gen_shli_i32(t1, t1, CRF_LT);
+ tcg_gen_shli_i32(t1, t1, CRF_LT_BIT);
tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
tcg_gen_setcond_tl((s ? TCG_COND_GT: TCG_COND_GTU), t0, arg0, arg1);
tcg_gen_trunc_tl_i32(t1, t0);
- tcg_gen_shli_i32(t1, t1, CRF_GT);
+ tcg_gen_shli_i32(t1, t1, CRF_GT_BIT);
tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
tcg_gen_setcond_tl(TCG_COND_EQ, t0, arg0, arg1);
tcg_gen_trunc_tl_i32(t1, t0);
- tcg_gen_shli_i32(t1, t1, CRF_EQ);
+ tcg_gen_shli_i32(t1, t1, CRF_EQ_BIT);
tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
tcg_temp_free(t0);
@@ -899,7 +748,7 @@ static void gen_cmprb(DisasContext *ctx)
tcg_gen_and_i32(src2lo, src2lo, src2hi);
tcg_gen_or_i32(crf, crf, src2lo);
}
- tcg_gen_shli_i32(crf, crf, CRF_GT);
+ tcg_gen_shli_i32(crf, crf, CRF_GT_BIT);
tcg_temp_free_i32(src1);
tcg_temp_free_i32(src2);
tcg_temp_free_i32(src2lo);
@@ -3148,7 +2997,7 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
l1 = gen_new_label();
tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
- tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
+ tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ);
tcg_gen_qemu_st_tl(cpu_gpr[reg], EA, ctx->mem_idx, memop);
gen_set_label(l1);
tcg_gen_movi_tl(cpu_reserve, -1);
@@ -3242,7 +3091,7 @@ static void gen_stqcx_(DisasContext *ctx)
tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
l1 = gen_new_label();
tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
- tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
+ tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ);
if (unlikely(ctx->le_mode)) {
gpr1 = cpu_gpr[reg + 1];
@@ -3323,6 +3172,11 @@ static void gen_nap(DisasContext *ctx)
#endif /* defined(CONFIG_USER_ONLY) */
}
+static void gen_stop(DisasContext *ctx)
+{
+ gen_nap(ctx);
+}
+
static void gen_sleep(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
@@ -4423,7 +4277,7 @@ static void gen_slbfee_(DisasContext *ctx)
l2 = gen_new_label();
tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rS(ctx->opcode)], -1, l1);
- tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
+ tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ);
tcg_gen_br(l2);
gen_set_label(l1);
tcg_gen_movi_tl(cpu_gpr[rS(ctx->opcode)], 0);
@@ -6166,6 +6020,10 @@ GEN_TM_NOOP(tabortwci);
GEN_TM_NOOP(tabortdc);
GEN_TM_NOOP(tabortdci);
GEN_TM_NOOP(tsr);
+static inline void gen_cp_abort(DisasContext *ctx)
+{
+ // Do Nothing
+}
static void gen_tcheck(DisasContext *ctx)
{
@@ -6223,6 +6081,67 @@ GEN_TM_PRIV_NOOP(trechkpt);
#include "translate/spe-impl.inc.c"
+/* Handles lfdp, lxsd, lxssp */
+static void gen_dform39(DisasContext *ctx)
+{
+ switch (ctx->opcode & 0x3) {
+ case 0: /* lfdp */
+ if (ctx->insns_flags2 & PPC2_ISA205) {
+ return gen_lfdp(ctx);
+ }
+ break;
+ case 2: /* lxsd */
+ if (ctx->insns_flags2 & PPC2_ISA300) {
+ return gen_lxsd(ctx);
+ }
+ break;
+ case 3: /* lxssp */
+ if (ctx->insns_flags2 & PPC2_ISA300) {
+ return gen_lxssp(ctx);
+ }
+ break;
+ }
+ return gen_invalid(ctx);
+}
+
+/* handles stfdp, lxv, stxsd, stxssp lxvx */
+static void gen_dform3D(DisasContext *ctx)
+{
+ if ((ctx->opcode & 3) == 1) { /* DQ-FORM */
+ switch (ctx->opcode & 0x7) {
+ case 1: /* lxv */
+ if (ctx->insns_flags2 & PPC2_ISA300) {
+ return gen_lxv(ctx);
+ }
+ break;
+ case 5: /* stxv */
+ if (ctx->insns_flags2 & PPC2_ISA300) {
+ return gen_stxv(ctx);
+ }
+ break;
+ }
+ } else { /* DS-FORM */
+ switch (ctx->opcode & 0x3) {
+ case 0: /* stfdp */
+ if (ctx->insns_flags2 & PPC2_ISA205) {
+ return gen_stfdp(ctx);
+ }
+ break;
+ case 2: /* stxsd */
+ if (ctx->insns_flags2 & PPC2_ISA300) {
+ return gen_stxsd(ctx);
+ }
+ break;
+ case 3: /* stxssp */
+ if (ctx->insns_flags2 & PPC2_ISA300) {
+ return gen_stxssp(ctx);
+ }
+ break;
+ }
+ }
+ return gen_invalid(ctx);
+}
+
static opcode_t opcodes[] = {
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
@@ -6255,6 +6174,7 @@ GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
GEN_HANDLER_E(cnttzw, 0x1F, 0x1A, 0x10, 0x00000000, PPC_NONE, PPC2_ISA300),
+GEN_HANDLER_E(cp_abort, 0x1F, 0x06, 0x1A, 0x03FFF801, PPC_NONE, PPC2_ISA300),
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
@@ -6295,6 +6215,10 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
#endif
+/* handles lfdp, lxsd, lxssp */
+GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
+/* handles stfdp, lxv, stxsd, stxssp, stxv */
+GEN_HANDLER_E(dform3D, 0x3D, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
@@ -6326,6 +6250,7 @@ GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, 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(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300),
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),
@@ -6910,6 +6835,9 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
}
#endif
+ if (env->spr_cb[SPR_LPCR].name)
+ cpu_fprintf(f, " LPCR " TARGET_FMT_lx "\n", env->spr[SPR_LPCR]);
+
switch (env->mmu_model) {
case POWERPC_MMU_32B:
case POWERPC_MMU_601: