diff options
Diffstat (limited to 'target-ppc/translate.c')
-rw-r--r-- | target-ppc/translate.c | 1283 |
1 files changed, 612 insertions, 671 deletions
diff --git a/target-ppc/translate.c b/target-ppc/translate.c index f08901470b..48017219a4 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -46,17 +46,13 @@ /* global register indexes */ static TCGv_ptr cpu_env; static char cpu_reg_names[10*3 + 22*4 /* GPR */ -#if !defined(TARGET_PPC64) + 10*4 + 22*5 /* SPE GPRh */ -#endif + 10*4 + 22*5 /* FPR */ + 2*(10*6 + 22*7) /* AVRh, AVRl */ + 10*5 + 22*6 /* VSR */ + 8*5 /* CRF */]; static TCGv cpu_gpr[32]; -#if !defined(TARGET_PPC64) static TCGv cpu_gprh[32]; -#endif static TCGv_i64 cpu_fpr[32]; static TCGv_i64 cpu_avrh[32], cpu_avrl[32]; static TCGv_i64 cpu_vsr[32]; @@ -104,13 +100,11 @@ void ppc_translate_init(void) offsetof(CPUPPCState, gpr[i]), p); p += (i < 10) ? 3 : 4; cpu_reg_names_size -= (i < 10) ? 3 : 4; -#if !defined(TARGET_PPC64) snprintf(p, cpu_reg_names_size, "r%dH", i); - cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUPPCState, gprh[i]), p); + cpu_gprh[i] = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUPPCState, gprh[i]), p); p += (i < 10) ? 4 : 5; cpu_reg_names_size -= (i < 10) ? 4 : 5; -#endif snprintf(p, cpu_reg_names_size, "fp%d", i); cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0, @@ -196,6 +190,7 @@ typedef struct DisasContext { int access_type; /* Translation flags */ int le_mode; + TCGMemOp default_tcg_memop_mask; #if defined(TARGET_PPC64) int sf_mode; int has_cfar; @@ -210,6 +205,16 @@ typedef struct DisasContext { uint64_t insns_flags2; } DisasContext; +/* Return true iff byteswap is needed in a scalar memop */ +static inline bool need_byteswap(const DisasContext *ctx) +{ +#if defined(TARGET_WORDS_BIGENDIAN) + return ctx->le_mode; +#else + return !ctx->le_mode; +#endif +} + /* True when active word size < size of target_long. */ #ifdef TARGET_PPC64 # define NARROW_MODE(C) (!(C)->sf_mode) @@ -279,6 +284,13 @@ static inline void gen_update_nip(DisasContext *ctx, target_ulong nip) tcg_gen_movi_tl(cpu_nip, nip); } +void gen_update_current_nip(void *opaque) +{ + DisasContext *ctx = opaque; + + tcg_gen_movi_tl(cpu_nip, ctx->nip); +} + static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error) { TCGv_i32 t0, t1; @@ -467,6 +479,12 @@ 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) + /* Create a mask between <start> and <end> bits */ static inline target_ulong MASK(uint32_t start, uint32_t end) { @@ -503,6 +521,7 @@ 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); /*****************************************************************************/ /* PowerPC instructions table */ @@ -1217,6 +1236,7 @@ static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1, } tcg_gen_xor_tl(t1, arg2, inv1); /* add without carry */ tcg_gen_add_tl(t0, t0, inv1); + tcg_temp_free(inv1); tcg_gen_xor_tl(cpu_ca, t0, t1); /* bits changes w/ carry */ tcg_temp_free(t1); tcg_gen_shri_tl(cpu_ca, cpu_ca, 32); /* extract bit 32 */ @@ -2652,29 +2672,20 @@ static inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2) static inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2) { - tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx); - if (unlikely(ctx->le_mode)) { - tcg_gen_bswap16_tl(arg1, arg1); - } + TCGMemOp op = MO_UW | ctx->default_tcg_memop_mask; + tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op); } static inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2) { - if (unlikely(ctx->le_mode)) { - tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx); - tcg_gen_bswap16_tl(arg1, arg1); - tcg_gen_ext16s_tl(arg1, arg1); - } else { - tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx); - } + TCGMemOp op = MO_SW | ctx->default_tcg_memop_mask; + tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op); } static inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2) { - tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx); - if (unlikely(ctx->le_mode)) { - tcg_gen_bswap32_tl(arg1, arg1); - } + TCGMemOp op = MO_UL | ctx->default_tcg_memop_mask; + tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op); } static void gen_qemu_ld32u_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr) @@ -2687,12 +2698,8 @@ static void gen_qemu_ld32u_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr) static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2) { - if (unlikely(ctx->le_mode)) { - tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx); - tcg_gen_bswap32_tl(arg1, arg1); - tcg_gen_ext32s_tl(arg1, arg1); - } else - tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx); + TCGMemOp op = MO_SL | ctx->default_tcg_memop_mask; + tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op); } static void gen_qemu_ld32s_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr) @@ -2705,10 +2712,8 @@ static void gen_qemu_ld32s_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr) static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2) { - tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx); - if (unlikely(ctx->le_mode)) { - tcg_gen_bswap64_i64(arg1, arg1); - } + TCGMemOp op = MO_Q | ctx->default_tcg_memop_mask; + tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op); } static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2) @@ -2718,28 +2723,14 @@ static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2) static inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2) { - if (unlikely(ctx->le_mode)) { - TCGv t0 = tcg_temp_new(); - tcg_gen_ext16u_tl(t0, arg1); - tcg_gen_bswap16_tl(t0, t0); - tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx); - tcg_temp_free(t0); - } else { - tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx); - } + TCGMemOp op = MO_UW | ctx->default_tcg_memop_mask; + tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op); } static inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2) { - if (unlikely(ctx->le_mode)) { - TCGv t0 = tcg_temp_new(); - tcg_gen_ext32u_tl(t0, arg1); - tcg_gen_bswap32_tl(t0, t0); - tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx); - tcg_temp_free(t0); - } else { - tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx); - } + TCGMemOp op = MO_UL | ctx->default_tcg_memop_mask; + tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op); } static void gen_qemu_st32_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr) @@ -2752,13 +2743,8 @@ static void gen_qemu_st32_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr) static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2) { - if (unlikely(ctx->le_mode)) { - TCGv_i64 t0 = tcg_temp_new_i64(); - tcg_gen_bswap64_i64(t0, arg1); - tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx); - tcg_temp_free_i64(t0); - } else - tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx); + TCGMemOp op = MO_Q | ctx->default_tcg_memop_mask; + tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op); } #define GEN_LD(name, ldop, opc, type) \ @@ -2902,6 +2888,8 @@ static void gen_lq(DisasContext *ctx) EA = tcg_temp_new(); gen_addr_imm_index(ctx, EA, 0x0F); + /* We only need to swap high and low halves. gen_qemu_ld64 does necessary + 64-bit byteswap already. */ if (unlikely(ctx->le_mode)) { gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA); gen_addr_add(ctx, EA, EA, 8); @@ -3020,6 +3008,8 @@ static void gen_std(DisasContext *ctx) EA = tcg_temp_new(); gen_addr_imm_index(ctx, EA, 0x03); + /* We only need to swap high and low halves. gen_qemu_st64 does + necessary 64-bit byteswap already. */ if (unlikely(ctx->le_mode)) { gen_qemu_st64(ctx, cpu_gpr[rs+1], EA); gen_addr_add(ctx, EA, EA, 8); @@ -3049,23 +3039,20 @@ static void gen_std(DisasContext *ctx) } #endif /*** Integer load and store with byte reverse ***/ + /* lhbrx */ static inline void gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2) { - tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx); - if (likely(!ctx->le_mode)) { - tcg_gen_bswap16_tl(arg1, arg1); - } + TCGMemOp op = MO_UW | (ctx->default_tcg_memop_mask ^ MO_BSWAP); + tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op); } GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER); /* lwbrx */ static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2) { - tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx); - if (likely(!ctx->le_mode)) { - tcg_gen_bswap32_tl(arg1, arg1); - } + TCGMemOp op = MO_UL | (ctx->default_tcg_memop_mask ^ MO_BSWAP); + tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op); } GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER); @@ -3073,10 +3060,8 @@ GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER); /* ldbrx */ static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2) { - tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx); - if (likely(!ctx->le_mode)) { - tcg_gen_bswap64_tl(arg1, arg1); - } + 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); #endif /* TARGET_PPC64 */ @@ -3084,30 +3069,16 @@ GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX); /* sthbrx */ static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2) { - if (likely(!ctx->le_mode)) { - TCGv t0 = tcg_temp_new(); - tcg_gen_ext16u_tl(t0, arg1); - tcg_gen_bswap16_tl(t0, t0); - tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx); - tcg_temp_free(t0); - } else { - tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx); - } + TCGMemOp op = MO_UW | (ctx->default_tcg_memop_mask ^ MO_BSWAP); + tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op); } GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER); /* stwbrx */ static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2) { - if (likely(!ctx->le_mode)) { - TCGv t0 = tcg_temp_new(); - tcg_gen_ext32u_tl(t0, arg1); - tcg_gen_bswap32_tl(t0, t0); - tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx); - tcg_temp_free(t0); - } else { - tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx); - } + TCGMemOp op = MO_UL | (ctx->default_tcg_memop_mask ^ MO_BSWAP); + tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op); } GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER); @@ -3115,14 +3086,8 @@ GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER); /* stdbrx */ static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2) { - if (likely(!ctx->le_mode)) { - TCGv t0 = tcg_temp_new(); - tcg_gen_bswap64_tl(t0, arg1); - tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx); - tcg_temp_free(t0); - } else { - tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx); - } + 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); #endif /* TARGET_PPC64 */ @@ -3542,7 +3507,9 @@ static void gen_lfdp(DisasContext *ctx) } gen_set_access_type(ctx, ACCESS_FLOAT); EA = tcg_temp_new(); - gen_addr_imm_index(ctx, EA, 0); \ + gen_addr_imm_index(ctx, EA, 0); + /* We only need to swap high and low halves. gen_qemu_ld64 does necessary + 64-bit byteswap already. */ if (unlikely(ctx->le_mode)) { gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA); tcg_gen_addi_tl(EA, EA, 8); @@ -3566,6 +3533,8 @@ static void gen_lfdpx(DisasContext *ctx) gen_set_access_type(ctx, ACCESS_FLOAT); EA = tcg_temp_new(); gen_addr_reg_index(ctx, EA); + /* We only need to swap high and low halves. gen_qemu_ld64 does necessary + 64-bit byteswap already. */ if (unlikely(ctx->le_mode)) { gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA); tcg_gen_addi_tl(EA, EA, 8); @@ -3714,7 +3683,9 @@ static void gen_stfdp(DisasContext *ctx) } gen_set_access_type(ctx, ACCESS_FLOAT); EA = tcg_temp_new(); - gen_addr_imm_index(ctx, EA, 0); \ + gen_addr_imm_index(ctx, EA, 0); + /* We only need to swap high and low halves. gen_qemu_st64 does necessary + 64-bit byteswap already. */ if (unlikely(ctx->le_mode)) { gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA); tcg_gen_addi_tl(EA, EA, 8); @@ -3738,6 +3709,8 @@ static void gen_stfdpx(DisasContext *ctx) gen_set_access_type(ctx, ACCESS_FLOAT); EA = tcg_temp_new(); gen_addr_reg_index(ctx, EA); + /* We only need to swap high and low halves. gen_qemu_st64 does necessary + 64-bit byteswap already. */ if (unlikely(ctx->le_mode)) { gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA); tcg_gen_addi_tl(EA, EA, 8); @@ -3913,6 +3886,9 @@ static inline void gen_bcond(DisasContext *ctx, int type) gen_update_nip(ctx, ctx->nip); tcg_gen_exit_tb(0); } + if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) { + tcg_temp_free(target); + } } static void gen_bc(DisasContext *ctx) @@ -4360,6 +4336,7 @@ static void gen_mtmsr(DisasContext *ctx) tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]); #endif gen_helper_store_msr(cpu_env, msr); + tcg_temp_free(msr); /* Must stop the translation as machine state (may have) changed */ /* Note that mtmsr is not always defined as context-synchronizing */ gen_stop_exception(ctx); @@ -4469,6 +4446,17 @@ static void gen_dcbtst(DisasContext *ctx) */ } +/* dcbtls */ +static void gen_dcbtls(DisasContext *ctx) +{ + /* Always fails locking the cache */ + TCGv t0 = tcg_temp_new(); + gen_load_spr(t0, SPR_Exxx_L1CSR0); + tcg_gen_ori_tl(t0, t0, L1CSR0_CUL); + gen_store_spr(SPR_Exxx_L1CSR0, t0); + tcg_temp_free(t0); +} + /* dcbz */ static void gen_dcbz(DisasContext *ctx) { @@ -6494,6 +6482,7 @@ static void gen_tlbsx_booke206(DisasContext *ctx) tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]); gen_helper_booke206_tlbsx(cpu_env, t0); + tcg_temp_free(t0); #endif } @@ -6527,6 +6516,7 @@ static void gen_tlbivax_booke206(DisasContext *ctx) gen_addr_reg_index(ctx, t0); gen_helper_booke206_tlbivax(cpu_env, t0); + tcg_temp_free(t0); #endif } @@ -6691,6 +6681,8 @@ static void glue(gen_, name)(DisasContext *ctx) EA = tcg_temp_new(); \ gen_addr_reg_index(ctx, EA); \ tcg_gen_andi_tl(EA, EA, ~0xf); \ + /* We only need to swap high and low halves. gen_qemu_ld64 does necessary \ + 64-bit byteswap already. */ \ if (ctx->le_mode) { \ gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \ tcg_gen_addi_tl(EA, EA, 8); \ @@ -6715,6 +6707,8 @@ static void gen_st##name(DisasContext *ctx) \ EA = tcg_temp_new(); \ gen_addr_reg_index(ctx, EA); \ tcg_gen_andi_tl(EA, EA, ~0xf); \ + /* We only need to swap high and low halves. gen_qemu_st64 does necessary \ + 64-bit byteswap already. */ \ if (ctx->le_mode) { \ gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \ tcg_gen_addi_tl(EA, EA, 8); \ @@ -8180,6 +8174,225 @@ static void gen_xxsldwi(DisasContext *ctx) tcg_temp_free_i64(xtl); } +/*** Decimal Floating Point ***/ + +static inline TCGv_ptr gen_fprp_ptr(int reg) +{ + TCGv_ptr r = tcg_temp_new_ptr(); + tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, fpr[reg])); + return r; +} + +#if defined(TARGET_PPC64) +static void gen_set_cr6_from_fpscr(DisasContext *ctx) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_trunc_tl_i32(tmp, cpu_fpscr); + tcg_gen_shri_i32(cpu_crf[1], tmp, 28); + tcg_temp_free_i32(tmp); +} +#else +static void gen_set_cr6_from_fpscr(DisasContext *ctx) +{ + tcg_gen_shri_tl(cpu_crf[1], cpu_fpscr, 28); +} +#endif + +#define GEN_DFP_T_A_B_Rc(name) \ +static void gen_##name(DisasContext *ctx) \ +{ \ + TCGv_ptr rd, ra, rb; \ + if (unlikely(!ctx->fpu_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_FPU); \ + return; \ + } \ + gen_update_nip(ctx, ctx->nip - 4); \ + rd = gen_fprp_ptr(rD(ctx->opcode)); \ + ra = gen_fprp_ptr(rA(ctx->opcode)); \ + rb = gen_fprp_ptr(rB(ctx->opcode)); \ + gen_helper_##name(cpu_env, rd, ra, rb); \ + if (unlikely(Rc(ctx->opcode) != 0)) { \ + gen_set_cr6_from_fpscr(ctx); \ + } \ + tcg_temp_free_ptr(rd); \ + tcg_temp_free_ptr(ra); \ + tcg_temp_free_ptr(rb); \ +} + +#define GEN_DFP_BF_A_B(name) \ +static void gen_##name(DisasContext *ctx) \ +{ \ + TCGv_ptr ra, rb; \ + if (unlikely(!ctx->fpu_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_FPU); \ + return; \ + } \ + gen_update_nip(ctx, ctx->nip - 4); \ + ra = gen_fprp_ptr(rA(ctx->opcode)); \ + rb = gen_fprp_ptr(rB(ctx->opcode)); \ + gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \ + cpu_env, ra, rb); \ + tcg_temp_free_ptr(ra); \ + tcg_temp_free_ptr(rb); \ +} + +#define GEN_DFP_BF_A_DCM(name) \ +static void gen_##name(DisasContext *ctx) \ +{ \ + TCGv_ptr ra; \ + TCGv_i32 dcm; \ + if (unlikely(!ctx->fpu_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_FPU); \ + return; \ + } \ + gen_update_nip(ctx, ctx->nip - 4); \ + ra = gen_fprp_ptr(rA(ctx->opcode)); \ + dcm = tcg_const_i32(DCM(ctx->opcode)); \ + gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \ + cpu_env, ra, dcm); \ + tcg_temp_free_ptr(ra); \ + tcg_temp_free_i32(dcm); \ +} + +#define GEN_DFP_T_B_U32_U32_Rc(name, u32f1, u32f2) \ +static void gen_##name(DisasContext *ctx) \ +{ \ + TCGv_ptr rt, rb; \ + TCGv_i32 u32_1, u32_2; \ + if (unlikely(!ctx->fpu_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_FPU); \ + return; \ + } \ + gen_update_nip(ctx, ctx->nip - 4); \ + rt = gen_fprp_ptr(rD(ctx->opcode)); \ + rb = gen_fprp_ptr(rB(ctx->opcode)); \ + u32_1 = tcg_const_i32(u32f1(ctx->opcode)); \ + u32_2 = tcg_const_i32(u32f2(ctx->opcode)); \ + gen_helper_##name(cpu_env, rt, rb, u32_1, u32_2); \ + if (unlikely(Rc(ctx->opcode) != 0)) { \ + gen_set_cr6_from_fpscr(ctx); \ + } \ + tcg_temp_free_ptr(rt); \ + tcg_temp_free_ptr(rb); \ + tcg_temp_free_i32(u32_1); \ + tcg_temp_free_i32(u32_2); \ +} + +#define GEN_DFP_T_A_B_I32_Rc(name, i32fld) \ +static void gen_##name(DisasContext *ctx) \ +{ \ + TCGv_ptr rt, ra, rb; \ + TCGv_i32 i32; \ + if (unlikely(!ctx->fpu_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_FPU); \ + return; \ + } \ + gen_update_nip(ctx, ctx->nip - 4); \ + rt = gen_fprp_ptr(rD(ctx->opcode)); \ + ra = gen_fprp_ptr(rA(ctx->opcode)); \ + rb = gen_fprp_ptr(rB(ctx->opcode)); \ + i32 = tcg_const_i32(i32fld(ctx->opcode)); \ + gen_helper_##name(cpu_env, rt, ra, rb, i32); \ + if (unlikely(Rc(ctx->opcode) != 0)) { \ + gen_set_cr6_from_fpscr(ctx); \ + } \ + tcg_temp_free_ptr(rt); \ + tcg_temp_free_ptr(rb); \ + tcg_temp_free_ptr(ra); \ + tcg_temp_free_i32(i32); \ + } + +#define GEN_DFP_T_B_Rc(name) \ +static void gen_##name(DisasContext *ctx) \ +{ \ + TCGv_ptr rt, rb; \ + if (unlikely(!ctx->fpu_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_FPU); \ + return; \ + } \ + gen_update_nip(ctx, ctx->nip - 4); \ + rt = gen_fprp_ptr(rD(ctx->opcode)); \ + rb = gen_fprp_ptr(rB(ctx->opcode)); \ + gen_helper_##name(cpu_env, rt, rb); \ + if (unlikely(Rc(ctx->opcode) != 0)) { \ + gen_set_cr6_from_fpscr(ctx); \ + } \ + tcg_temp_free_ptr(rt); \ + tcg_temp_free_ptr(rb); \ + } + +#define GEN_DFP_T_FPR_I32_Rc(name, fprfld, i32fld) \ +static void gen_##name(DisasContext *ctx) \ +{ \ + TCGv_ptr rt, rs; \ + TCGv_i32 i32; \ + if (unlikely(!ctx->fpu_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_FPU); \ + return; \ + } \ + gen_update_nip(ctx, ctx->nip - 4); \ + rt = gen_fprp_ptr(rD(ctx->opcode)); \ + rs = gen_fprp_ptr(fprfld(ctx->opcode)); \ + i32 = tcg_const_i32(i32fld(ctx->opcode)); \ + gen_helper_##name(cpu_env, rt, rs, i32); \ + if (unlikely(Rc(ctx->opcode) != 0)) { \ + gen_set_cr6_from_fpscr(ctx); \ + } \ + tcg_temp_free_ptr(rt); \ + tcg_temp_free_ptr(rs); \ + tcg_temp_free_i32(i32); \ +} + +GEN_DFP_T_A_B_Rc(dadd) +GEN_DFP_T_A_B_Rc(daddq) +GEN_DFP_T_A_B_Rc(dsub) +GEN_DFP_T_A_B_Rc(dsubq) +GEN_DFP_T_A_B_Rc(dmul) +GEN_DFP_T_A_B_Rc(dmulq) +GEN_DFP_T_A_B_Rc(ddiv) +GEN_DFP_T_A_B_Rc(ddivq) +GEN_DFP_BF_A_B(dcmpu) +GEN_DFP_BF_A_B(dcmpuq) +GEN_DFP_BF_A_B(dcmpo) +GEN_DFP_BF_A_B(dcmpoq) +GEN_DFP_BF_A_DCM(dtstdc) +GEN_DFP_BF_A_DCM(dtstdcq) +GEN_DFP_BF_A_DCM(dtstdg) +GEN_DFP_BF_A_DCM(dtstdgq) +GEN_DFP_BF_A_B(dtstex) +GEN_DFP_BF_A_B(dtstexq) +GEN_DFP_BF_A_B(dtstsf) +GEN_DFP_BF_A_B(dtstsfq) +GEN_DFP_T_B_U32_U32_Rc(dquai, SIMM5, RMC) +GEN_DFP_T_B_U32_U32_Rc(dquaiq, SIMM5, RMC) +GEN_DFP_T_A_B_I32_Rc(dqua, RMC) +GEN_DFP_T_A_B_I32_Rc(dquaq, RMC) +GEN_DFP_T_A_B_I32_Rc(drrnd, RMC) +GEN_DFP_T_A_B_I32_Rc(drrndq, RMC) +GEN_DFP_T_B_U32_U32_Rc(drintx, FPW, RMC) +GEN_DFP_T_B_U32_U32_Rc(drintxq, FPW, RMC) +GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC) +GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC) +GEN_DFP_T_B_Rc(dctdp) +GEN_DFP_T_B_Rc(dctqpq) +GEN_DFP_T_B_Rc(drsp) +GEN_DFP_T_B_Rc(drdpq) +GEN_DFP_T_B_Rc(dcffix) +GEN_DFP_T_B_Rc(dcffixq) +GEN_DFP_T_B_Rc(dctfix) +GEN_DFP_T_B_Rc(dctfixq) +GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP) +GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP) +GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP) +GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP) +GEN_DFP_T_B_Rc(dxex) +GEN_DFP_T_B_Rc(dxexq) +GEN_DFP_T_A_B_Rc(diex) +GEN_DFP_T_A_B_Rc(diexq) +GEN_DFP_T_FPR_I32_Rc(dscli, rA, DCM) +GEN_DFP_T_FPR_I32_Rc(dscliq, rA, DCM) +GEN_DFP_T_FPR_I32_Rc(dscri, rA, DCM) +GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM) /*** SPE extension ***/ /* Register moves */ @@ -8192,50 +8405,28 @@ static inline void gen_evmra(DisasContext *ctx) return; } -#if defined(TARGET_PPC64) - /* rD := rA */ - tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); - - /* spe_acc := rA */ - tcg_gen_st_i64(cpu_gpr[rA(ctx->opcode)], - cpu_env, - offsetof(CPUPPCState, spe_acc)); -#else TCGv_i64 tmp = tcg_temp_new_i64(); /* tmp := rA_lo + rA_hi << 32 */ - tcg_gen_concat_i32_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); + tcg_gen_concat_tl_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); /* spe_acc := tmp */ tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc)); tcg_temp_free_i64(tmp); /* rD := rA */ - tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); - tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); -#endif + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); + tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); } static inline void gen_load_gpr64(TCGv_i64 t, int reg) { -#if defined(TARGET_PPC64) - tcg_gen_mov_i64(t, cpu_gpr[reg]); -#else - tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]); -#endif + tcg_gen_concat_tl_i64(t, cpu_gpr[reg], cpu_gprh[reg]); } static inline void gen_store_gpr64(int reg, TCGv_i64 t) { -#if defined(TARGET_PPC64) - tcg_gen_mov_i64(cpu_gpr[reg], t); -#else - TCGv_i64 tmp = tcg_temp_new_i64(); - tcg_gen_trunc_i64_i32(cpu_gpr[reg], t); - tcg_gen_shri_i64(tmp, t, 32); - tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp); - tcg_temp_free_i64(tmp); -#endif + tcg_gen_extr_i64_tl(cpu_gpr[reg], cpu_gprh[reg], t); } #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ @@ -8254,18 +8445,6 @@ static inline void gen_speundef(DisasContext *ctx) } /* SPE logic */ -#if defined(TARGET_PPC64) -#define GEN_SPEOP_LOGIC2(name, tcg_op) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_SPEU); \ - return; \ - } \ - tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ - cpu_gpr[rB(ctx->opcode)]); \ -} -#else #define GEN_SPEOP_LOGIC2(name, tcg_op) \ static inline void gen_##name(DisasContext *ctx) \ { \ @@ -8278,7 +8457,6 @@ static inline void gen_##name(DisasContext *ctx) \ tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], \ cpu_gprh[rB(ctx->opcode)]); \ } -#endif GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl); GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl); @@ -8290,80 +8468,52 @@ GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl); GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl); /* SPE logic immediate */ -#if defined(TARGET_PPC64) #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi) \ static inline void gen_##name(DisasContext *ctx) \ { \ + TCGv_i32 t0; \ if (unlikely(!ctx->spe_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ - TCGv_i32 t0 = tcg_temp_local_new_i32(); \ - TCGv_i32 t1 = tcg_temp_local_new_i32(); \ - TCGv_i64 t2 = tcg_temp_local_new_i64(); \ - tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ + t0 = tcg_temp_new_i32(); \ + \ + tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ + tcg_opi(t0, t0, rB(ctx->opcode)); \ + tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \ + \ + tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \ tcg_opi(t0, t0, rB(ctx->opcode)); \ - tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32); \ - tcg_gen_trunc_i64_i32(t1, t2); \ - tcg_temp_free_i64(t2); \ - tcg_opi(t1, t1, rB(ctx->opcode)); \ - tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); \ + tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \ + \ tcg_temp_free_i32(t0); \ - tcg_temp_free_i32(t1); \ -} -#else -#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_SPEU); \ - return; \ - } \ - tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ - rB(ctx->opcode)); \ - tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], \ - rB(ctx->opcode)); \ } -#endif GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32); GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32); GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32); GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32); /* SPE arithmetic */ -#if defined(TARGET_PPC64) #define GEN_SPEOP_ARITH1(name, tcg_op) \ static inline void gen_##name(DisasContext *ctx) \ { \ + TCGv_i32 t0; \ if (unlikely(!ctx->spe_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ - TCGv_i32 t0 = tcg_temp_local_new_i32(); \ - TCGv_i32 t1 = tcg_temp_local_new_i32(); \ - TCGv_i64 t2 = tcg_temp_local_new_i64(); \ - tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ + t0 = tcg_temp_new_i32(); \ + \ + tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ + tcg_op(t0, t0); \ + tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \ + \ + tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \ tcg_op(t0, t0); \ - tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32); \ - tcg_gen_trunc_i64_i32(t1, t2); \ - tcg_temp_free_i64(t2); \ - tcg_op(t1, t1); \ - tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); \ + tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \ + \ tcg_temp_free_i32(t0); \ - tcg_temp_free_i32(t1); \ } -#else -#define GEN_SPEOP_ARITH1(name, tcg_op) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_SPEU); \ - return; \ - } \ - tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \ - tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); \ -} -#endif static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1) { @@ -8390,46 +8540,30 @@ GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw); GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32); GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32); -#if defined(TARGET_PPC64) #define GEN_SPEOP_ARITH2(name, tcg_op) \ static inline void gen_##name(DisasContext *ctx) \ { \ + TCGv_i32 t0, t1; \ if (unlikely(!ctx->spe_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ - TCGv_i32 t0 = tcg_temp_local_new_i32(); \ - TCGv_i32 t1 = tcg_temp_local_new_i32(); \ - TCGv_i32 t2 = tcg_temp_local_new_i32(); \ - TCGv_i64 t3 = tcg_temp_local_new_i64(); \ - tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ - tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]); \ - tcg_op(t0, t0, t2); \ - tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32); \ - tcg_gen_trunc_i64_i32(t1, t3); \ - tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32); \ - tcg_gen_trunc_i64_i32(t2, t3); \ - tcg_temp_free_i64(t3); \ - tcg_op(t1, t1, t2); \ - tcg_temp_free_i32(t2); \ - tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); \ + t0 = tcg_temp_new_i32(); \ + t1 = tcg_temp_new_i32(); \ + \ + tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ + tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \ + tcg_op(t0, t0, t1); \ + tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \ + \ + tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \ + tcg_gen_trunc_tl_i32(t1, cpu_gprh[rB(ctx->opcode)]); \ + tcg_op(t0, t0, t1); \ + tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \ + \ tcg_temp_free_i32(t0); \ tcg_temp_free_i32(t1); \ } -#else -#define GEN_SPEOP_ARITH2(name, tcg_op) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_SPEU); \ - return; \ - } \ - tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ - cpu_gpr[rB(ctx->opcode)]); \ - tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], \ - cpu_gprh[rB(ctx->opcode)]); \ -} -#endif static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { @@ -8502,18 +8636,8 @@ static inline void gen_evmergehi(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_SPEU); return; } -#if defined(TARGET_PPC64) - TCGv t0 = tcg_temp_new(); - TCGv t1 = tcg_temp_new(); - tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32); - tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); - tcg_temp_free(t0); - tcg_temp_free(t1); -#else - tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); - tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); -#endif + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); + tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); } GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32); static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) @@ -8523,86 +8647,30 @@ static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf); /* SPE arithmetic immediate */ -#if defined(TARGET_PPC64) #define GEN_SPEOP_ARITH_IMM2(name, tcg_op) \ static inline void gen_##name(DisasContext *ctx) \ { \ + TCGv_i32 t0; \ if (unlikely(!ctx->spe_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ - TCGv_i32 t0 = tcg_temp_local_new_i32(); \ - TCGv_i32 t1 = tcg_temp_local_new_i32(); \ - TCGv_i64 t2 = tcg_temp_local_new_i64(); \ - tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]); \ + t0 = tcg_temp_new_i32(); \ + \ + tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \ tcg_op(t0, t0, rA(ctx->opcode)); \ - tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32); \ - tcg_gen_trunc_i64_i32(t1, t2); \ - tcg_temp_free_i64(t2); \ - tcg_op(t1, t1, rA(ctx->opcode)); \ - tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); \ + tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \ + \ + tcg_gen_trunc_tl_i32(t0, cpu_gprh[rB(ctx->opcode)]); \ + tcg_op(t0, t0, rA(ctx->opcode)); \ + tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \ + \ tcg_temp_free_i32(t0); \ - tcg_temp_free_i32(t1); \ -} -#else -#define GEN_SPEOP_ARITH_IMM2(name, tcg_op) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_SPEU); \ - return; \ - } \ - tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \ - rA(ctx->opcode)); \ - tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)], \ - rA(ctx->opcode)); \ } -#endif GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32); GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32); /* SPE comparison */ -#if defined(TARGET_PPC64) -#define GEN_SPEOP_COMP(name, tcg_cond) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_SPEU); \ - return; \ - } \ - int l1 = gen_new_label(); \ - int l2 = gen_new_label(); \ - int l3 = gen_new_label(); \ - int l4 = gen_new_label(); \ - TCGv_i32 t0 = tcg_temp_local_new_i32(); \ - TCGv_i32 t1 = tcg_temp_local_new_i32(); \ - TCGv_i64 t2 = tcg_temp_local_new_i64(); \ - tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ - tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]); \ - tcg_gen_brcond_i32(tcg_cond, t0, t1, l1); \ - tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0); \ - tcg_gen_br(l2); \ - gen_set_label(l1); \ - tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], \ - CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL); \ - gen_set_label(l2); \ - tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32); \ - tcg_gen_trunc_i64_i32(t0, t2); \ - tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32); \ - tcg_gen_trunc_i64_i32(t1, t2); \ - tcg_temp_free_i64(t2); \ - tcg_gen_brcond_i32(tcg_cond, t0, t1, l3); \ - tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \ - ~(CRF_CH | CRF_CH_AND_CL)); \ - tcg_gen_br(l4); \ - gen_set_label(l3); \ - tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \ - CRF_CH | CRF_CH_OR_CL); \ - gen_set_label(l4); \ - tcg_temp_free_i32(t0); \ - tcg_temp_free_i32(t1); \ -} -#else #define GEN_SPEOP_COMP(name, tcg_cond) \ static inline void gen_##name(DisasContext *ctx) \ { \ @@ -8615,15 +8683,20 @@ static inline void gen_##name(DisasContext *ctx) \ int l3 = gen_new_label(); \ int l4 = gen_new_label(); \ \ - tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)], \ + tcg_gen_ext32s_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \ + tcg_gen_ext32s_tl(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \ + tcg_gen_ext32s_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); \ + tcg_gen_ext32s_tl(cpu_gprh[rB(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); \ + \ + tcg_gen_brcond_tl(tcg_cond, cpu_gpr[rA(ctx->opcode)], \ cpu_gpr[rB(ctx->opcode)], l1); \ - tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0); \ + tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0); \ tcg_gen_br(l2); \ gen_set_label(l1); \ tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], \ CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL); \ gen_set_label(l2); \ - tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)], \ + tcg_gen_brcond_tl(tcg_cond, cpu_gprh[rA(ctx->opcode)], \ cpu_gprh[rB(ctx->opcode)], l3); \ tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \ ~(CRF_CH | CRF_CH_AND_CL)); \ @@ -8633,7 +8706,6 @@ static inline void gen_##name(DisasContext *ctx) \ CRF_CH | CRF_CH_OR_CL); \ gen_set_label(l4); \ } -#endif GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU); GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT); GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU); @@ -8653,18 +8725,8 @@ static inline void gen_evmergelo(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_SPEU); return; } -#if defined(TARGET_PPC64) - TCGv t0 = tcg_temp_new(); - TCGv t1 = tcg_temp_new(); - tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]); - tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); - tcg_temp_free(t0); - tcg_temp_free(t1); -#else - tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); - tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); -#endif + tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); } static inline void gen_evmergehilo(DisasContext *ctx) { @@ -8672,18 +8734,8 @@ static inline void gen_evmergehilo(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_SPEU); return; } -#if defined(TARGET_PPC64) - TCGv t0 = tcg_temp_new(); - TCGv t1 = tcg_temp_new(); - tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]); - tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); - tcg_temp_free(t0); - tcg_temp_free(t1); -#else - tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); - tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); -#endif + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); + tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); } static inline void gen_evmergelohi(DisasContext *ctx) { @@ -8691,48 +8743,30 @@ static inline void gen_evmergelohi(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_SPEU); return; } -#if defined(TARGET_PPC64) - TCGv t0 = tcg_temp_new(); - TCGv t1 = tcg_temp_new(); - tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32); - tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); - tcg_temp_free(t0); - tcg_temp_free(t1); -#else if (rD(ctx->opcode) == rA(ctx->opcode)) { - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]); - tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); - tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp); - tcg_temp_free_i32(tmp); + TCGv tmp = tcg_temp_new(); + tcg_gen_mov_tl(tmp, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); + tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], tmp); + tcg_temp_free(tmp); } else { - tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); - tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); + tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); } -#endif } static inline void gen_evsplati(DisasContext *ctx) { uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27; -#if defined(TARGET_PPC64) - tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm); -#else - tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm); - tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm); -#endif + tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm); + tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm); } static inline void gen_evsplatfi(DisasContext *ctx) { uint64_t imm = rA(ctx->opcode) << 27; -#if defined(TARGET_PPC64) - tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm); -#else - tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm); - tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm); -#endif + tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm); + tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm); } static inline void gen_evsel(DisasContext *ctx) @@ -8742,46 +8776,21 @@ static inline void gen_evsel(DisasContext *ctx) int l3 = gen_new_label(); int l4 = gen_new_label(); TCGv_i32 t0 = tcg_temp_local_new_i32(); -#if defined(TARGET_PPC64) - TCGv t1 = tcg_temp_local_new(); - TCGv t2 = tcg_temp_local_new(); -#endif tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3); tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1); -#if defined(TARGET_PPC64) - tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL); -#else tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); -#endif tcg_gen_br(l2); gen_set_label(l1); -#if defined(TARGET_PPC64) - tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL); -#else tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); -#endif gen_set_label(l2); tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2); tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3); -#if defined(TARGET_PPC64) - tcg_gen_ext32u_tl(t2, cpu_gpr[rA(ctx->opcode)]); -#else tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); -#endif tcg_gen_br(l4); gen_set_label(l3); -#if defined(TARGET_PPC64) - tcg_gen_ext32u_tl(t2, cpu_gpr[rB(ctx->opcode)]); -#else tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); -#endif gen_set_label(l4); tcg_temp_free_i32(t0); -#if defined(TARGET_PPC64) - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2); - tcg_temp_free(t1); - tcg_temp_free(t2); -#endif } static void gen_evsel0(DisasContext *ctx) @@ -8819,13 +8828,10 @@ static inline void gen_evmwumi(DisasContext *ctx) t1 = tcg_temp_new_i64(); /* t0 := rA; t1 := rB */ -#if defined(TARGET_PPC64) - tcg_gen_ext32u_tl(t0, cpu_gpr[rA(ctx->opcode)]); - tcg_gen_ext32u_tl(t1, cpu_gpr[rB(ctx->opcode)]); -#else tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_ext32u_i64(t0, t0); tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); -#endif + tcg_gen_ext32u_i64(t1, t1); tcg_gen_mul_i64(t0, t0, t1); /* t0 := rA * rB */ @@ -8901,13 +8907,10 @@ static inline void gen_evmwsmi(DisasContext *ctx) t1 = tcg_temp_new_i64(); /* t0 := rA; t1 := rB */ -#if defined(TARGET_PPC64) - tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]); - tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]); -#else - tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); - tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); -#endif + tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_ext32s_i64(t0, t0); + tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); + tcg_gen_ext32s_i64(t1, t1); tcg_gen_mul_i64(t0, t0, t1); /* t0 := rA * rB */ @@ -9008,53 +9011,22 @@ static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh) static inline void gen_op_evldd(DisasContext *ctx, TCGv addr) { -#if defined(TARGET_PPC64) - gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr); -#else TCGv_i64 t0 = tcg_temp_new_i64(); gen_qemu_ld64(ctx, t0, addr); - tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0); - tcg_gen_shri_i64(t0, t0, 32); - tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0); + gen_store_gpr64(rD(ctx->opcode), t0); tcg_temp_free_i64(t0); -#endif } static inline void gen_op_evldw(DisasContext *ctx, TCGv addr) { -#if defined(TARGET_PPC64) - TCGv t0 = tcg_temp_new(); - gen_qemu_ld32u(ctx, t0, addr); - tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32); - gen_addr_add(ctx, addr, addr, 4); - gen_qemu_ld32u(ctx, t0, addr); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); - tcg_temp_free(t0); -#else gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr); gen_addr_add(ctx, addr, addr, 4); gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr); -#endif } static inline void gen_op_evldh(DisasContext *ctx, TCGv addr) { TCGv t0 = tcg_temp_new(); -#if defined(TARGET_PPC64) - gen_qemu_ld16u(ctx, t0, addr); - tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48); - gen_addr_add(ctx, addr, addr, 2); - gen_qemu_ld16u(ctx, t0, addr); - tcg_gen_shli_tl(t0, t0, 32); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); - gen_addr_add(ctx, addr, addr, 2); - gen_qemu_ld16u(ctx, t0, addr); - tcg_gen_shli_tl(t0, t0, 16); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); - gen_addr_add(ctx, addr, addr, 2); - gen_qemu_ld16u(ctx, t0, addr); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); -#else gen_qemu_ld16u(ctx, t0, addr); tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16); gen_addr_add(ctx, addr, addr, 2); @@ -9066,7 +9038,6 @@ static inline void gen_op_evldh(DisasContext *ctx, TCGv addr) gen_addr_add(ctx, addr, addr, 2); gen_qemu_ld16u(ctx, t0, addr); tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); -#endif tcg_temp_free(t0); } @@ -9074,15 +9045,9 @@ static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr) { TCGv t0 = tcg_temp_new(); gen_qemu_ld16u(ctx, t0, addr); -#if defined(TARGET_PPC64) - tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48); - tcg_gen_shli_tl(t0, t0, 16); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); -#else tcg_gen_shli_tl(t0, t0, 16); tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0); tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0); -#endif tcg_temp_free(t0); } @@ -9090,13 +9055,8 @@ static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr) { TCGv t0 = tcg_temp_new(); gen_qemu_ld16u(ctx, t0, addr); -#if defined(TARGET_PPC64) - tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); -#else tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0); tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0); -#endif tcg_temp_free(t0); } @@ -9104,100 +9064,48 @@ static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr) { TCGv t0 = tcg_temp_new(); gen_qemu_ld16s(ctx, t0, addr); -#if defined(TARGET_PPC64) - tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32); - tcg_gen_ext32u_tl(t0, t0); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); -#else tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0); tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0); -#endif tcg_temp_free(t0); } static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr) { TCGv t0 = tcg_temp_new(); -#if defined(TARGET_PPC64) - gen_qemu_ld16u(ctx, t0, addr); - tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48); - gen_addr_add(ctx, addr, addr, 2); - gen_qemu_ld16u(ctx, t0, addr); - tcg_gen_shli_tl(t0, t0, 16); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); -#else gen_qemu_ld16u(ctx, t0, addr); tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16); gen_addr_add(ctx, addr, addr, 2); gen_qemu_ld16u(ctx, t0, addr); tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16); -#endif tcg_temp_free(t0); } static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr) { -#if defined(TARGET_PPC64) - TCGv t0 = tcg_temp_new(); - gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr); - gen_addr_add(ctx, addr, addr, 2); - gen_qemu_ld16u(ctx, t0, addr); - tcg_gen_shli_tl(t0, t0, 32); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); - tcg_temp_free(t0); -#else gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr); gen_addr_add(ctx, addr, addr, 2); gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr); -#endif } static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr) { -#if defined(TARGET_PPC64) - TCGv t0 = tcg_temp_new(); - gen_qemu_ld16s(ctx, t0, addr); - tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0); - gen_addr_add(ctx, addr, addr, 2); - gen_qemu_ld16s(ctx, t0, addr); - tcg_gen_shli_tl(t0, t0, 32); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); - tcg_temp_free(t0); -#else gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr); gen_addr_add(ctx, addr, addr, 2); gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr); -#endif } static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr) { TCGv t0 = tcg_temp_new(); gen_qemu_ld32u(ctx, t0, addr); -#if defined(TARGET_PPC64) - tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); -#else tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0); tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0); -#endif tcg_temp_free(t0); } static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr) { TCGv t0 = tcg_temp_new(); -#if defined(TARGET_PPC64) - gen_qemu_ld16u(ctx, t0, addr); - tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48); - tcg_gen_shli_tl(t0, t0, 32); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); - gen_addr_add(ctx, addr, addr, 2); - gen_qemu_ld16u(ctx, t0, addr); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); - tcg_gen_shli_tl(t0, t0, 16); - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0); -#else gen_qemu_ld16u(ctx, t0, addr); tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16); tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0); @@ -9205,32 +9113,20 @@ static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr) gen_qemu_ld16u(ctx, t0, addr); tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16); tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0); -#endif tcg_temp_free(t0); } static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr) { -#if defined(TARGET_PPC64) - gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr); -#else TCGv_i64 t0 = tcg_temp_new_i64(); - tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]); + gen_load_gpr64(t0, rS(ctx->opcode)); gen_qemu_st64(ctx, t0, addr); tcg_temp_free_i64(t0); -#endif } static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr) { -#if defined(TARGET_PPC64) - TCGv t0 = tcg_temp_new(); - tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32); - gen_qemu_st32(ctx, t0, addr); - tcg_temp_free(t0); -#else gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr); -#endif gen_addr_add(ctx, addr, addr, 4); gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr); } @@ -9238,19 +9134,10 @@ static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr) static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr) { TCGv t0 = tcg_temp_new(); -#if defined(TARGET_PPC64) - tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48); -#else tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16); -#endif gen_qemu_st16(ctx, t0, addr); gen_addr_add(ctx, addr, addr, 2); -#if defined(TARGET_PPC64) - tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32); - gen_qemu_st16(ctx, t0, addr); -#else gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr); -#endif gen_addr_add(ctx, addr, addr, 2); tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16); gen_qemu_st16(ctx, t0, addr); @@ -9262,11 +9149,7 @@ static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr) static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr) { TCGv t0 = tcg_temp_new(); -#if defined(TARGET_PPC64) - tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48); -#else tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16); -#endif gen_qemu_st16(ctx, t0, addr); gen_addr_add(ctx, addr, addr, 2); tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16); @@ -9276,28 +9159,14 @@ static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr) static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr) { -#if defined(TARGET_PPC64) - TCGv t0 = tcg_temp_new(); - tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32); - gen_qemu_st16(ctx, t0, addr); - tcg_temp_free(t0); -#else gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr); -#endif gen_addr_add(ctx, addr, addr, 2); gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr); } static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr) { -#if defined(TARGET_PPC64) - TCGv t0 = tcg_temp_new(); - tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32); - gen_qemu_st32(ctx, t0, addr); - tcg_temp_free(t0); -#else gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr); -#endif } static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr) @@ -9417,133 +9286,36 @@ GEN_SPE(speundef, evmwsmfan, 0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_S #endif /*** SPE floating-point extension ***/ -#if defined(TARGET_PPC64) #define GEN_SPEFPUOP_CONV_32_32(name) \ static inline void gen_##name(DisasContext *ctx) \ { \ - TCGv_i32 t0; \ - TCGv t1; \ - t0 = tcg_temp_new_i32(); \ + TCGv_i32 t0 = tcg_temp_new_i32(); \ tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \ gen_helper_##name(t0, cpu_env, t0); \ - t1 = tcg_temp_new(); \ - tcg_gen_extu_i32_tl(t1, t0); \ + tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \ tcg_temp_free_i32(t0); \ - tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], \ - 0xFFFFFFFF00000000ULL); \ - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1); \ - tcg_temp_free(t1); \ -} -#define GEN_SPEFPUOP_CONV_32_64(name) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - TCGv_i32 t0; \ - TCGv t1; \ - t0 = tcg_temp_new_i32(); \ - gen_helper_##name(t0, cpu_env, cpu_gpr[rB(ctx->opcode)]); \ - t1 = tcg_temp_new(); \ - tcg_gen_extu_i32_tl(t1, t0); \ - tcg_temp_free_i32(t0); \ - tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], \ - 0xFFFFFFFF00000000ULL); \ - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1); \ - tcg_temp_free(t1); \ -} -#define GEN_SPEFPUOP_CONV_64_32(name) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - TCGv_i32 t0 = tcg_temp_new_i32(); \ - tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \ - gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); \ - tcg_temp_free_i32(t0); \ -} -#define GEN_SPEFPUOP_CONV_64_64(name) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, \ - cpu_gpr[rB(ctx->opcode)]); \ -} -#define GEN_SPEFPUOP_ARITH2_32_32(name) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - TCGv_i32 t0, t1; \ - TCGv_i64 t2; \ - if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_SPEU); \ - return; \ - } \ - t0 = tcg_temp_new_i32(); \ - t1 = tcg_temp_new_i32(); \ - tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ - tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \ - gen_helper_##name(t0, cpu_env, t0, t1); \ - tcg_temp_free_i32(t1); \ - t2 = tcg_temp_new(); \ - tcg_gen_extu_i32_tl(t2, t0); \ - tcg_temp_free_i32(t0); \ - tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], \ - 0xFFFFFFFF00000000ULL); \ - tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2); \ - tcg_temp_free(t2); \ -} -#define GEN_SPEFPUOP_ARITH2_64_64(name) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_SPEU); \ - return; \ - } \ - gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, \ - cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \ -} -#define GEN_SPEFPUOP_COMP_32(name) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - TCGv_i32 t0, t1; \ - if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_SPEU); \ - return; \ - } \ - t0 = tcg_temp_new_i32(); \ - t1 = tcg_temp_new_i32(); \ - tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ - tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \ - gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1); \ - tcg_temp_free_i32(t0); \ - tcg_temp_free_i32(t1); \ -} -#define GEN_SPEFPUOP_COMP_64(name) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_SPEU); \ - return; \ - } \ - gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, \ - cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \ -} -#else -#define GEN_SPEFPUOP_CONV_32_32(name) \ -static inline void gen_##name(DisasContext *ctx) \ -{ \ - gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, \ - cpu_gpr[rB(ctx->opcode)]); \ } #define GEN_SPEFPUOP_CONV_32_64(name) \ static inline void gen_##name(DisasContext *ctx) \ { \ TCGv_i64 t0 = tcg_temp_new_i64(); \ + TCGv_i32 t1 = tcg_temp_new_i32(); \ gen_load_gpr64(t0, rB(ctx->opcode)); \ - gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); \ + gen_helper_##name(t1, cpu_env, t0); \ + tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1); \ tcg_temp_free_i64(t0); \ + tcg_temp_free_i32(t1); \ } #define GEN_SPEFPUOP_CONV_64_32(name) \ static inline void gen_##name(DisasContext *ctx) \ { \ TCGv_i64 t0 = tcg_temp_new_i64(); \ - gen_helper_##name(t0, cpu_env, cpu_gpr[rB(ctx->opcode)]); \ + TCGv_i32 t1 = tcg_temp_new_i32(); \ + tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \ + gen_helper_##name(t0, cpu_env, t1); \ gen_store_gpr64(rD(ctx->opcode), t0); \ tcg_temp_free_i64(t0); \ + tcg_temp_free_i32(t1); \ } #define GEN_SPEFPUOP_CONV_64_64(name) \ static inline void gen_##name(DisasContext *ctx) \ @@ -9557,12 +9329,20 @@ static inline void gen_##name(DisasContext *ctx) \ #define GEN_SPEFPUOP_ARITH2_32_32(name) \ static inline void gen_##name(DisasContext *ctx) \ { \ + TCGv_i32 t0, t1; \ if (unlikely(!ctx->spe_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ - gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, \ - cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \ + t0 = tcg_temp_new_i32(); \ + t1 = tcg_temp_new_i32(); \ + tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ + tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \ + gen_helper_##name(t0, cpu_env, t0, t1); \ + tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \ + \ + tcg_temp_free_i32(t0); \ + tcg_temp_free_i32(t1); \ } #define GEN_SPEFPUOP_ARITH2_64_64(name) \ static inline void gen_##name(DisasContext *ctx) \ @@ -9584,12 +9364,20 @@ static inline void gen_##name(DisasContext *ctx) \ #define GEN_SPEFPUOP_COMP_32(name) \ static inline void gen_##name(DisasContext *ctx) \ { \ + TCGv_i32 t0, t1; \ if (unlikely(!ctx->spe_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ - gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, \ - cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \ + t0 = tcg_temp_new_i32(); \ + t1 = tcg_temp_new_i32(); \ + \ + tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ + tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \ + gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1); \ + \ + tcg_temp_free_i32(t0); \ + tcg_temp_free_i32(t1); \ } #define GEN_SPEFPUOP_COMP_64(name) \ static inline void gen_##name(DisasContext *ctx) \ @@ -9607,7 +9395,6 @@ static inline void gen_##name(DisasContext *ctx) \ tcg_temp_free_i64(t0); \ tcg_temp_free_i64(t1); \ } -#endif /* Single precision floating-point vectors operations */ /* Arithmetic */ @@ -9621,12 +9408,10 @@ static inline void gen_evfsabs(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_SPEU); return; } -#if defined(TARGET_PPC64) - tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL); -#else - tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000); - tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000); -#endif + tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], + ~0x80000000); + tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], + ~0x80000000); } static inline void gen_evfsnabs(DisasContext *ctx) { @@ -9634,12 +9419,10 @@ static inline void gen_evfsnabs(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_SPEU); return; } -#if defined(TARGET_PPC64) - tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL); -#else - tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); - tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000); -#endif + tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], + 0x80000000); + tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], + 0x80000000); } static inline void gen_evfsneg(DisasContext *ctx) { @@ -9647,12 +9430,10 @@ static inline void gen_evfsneg(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_SPEU); return; } -#if defined(TARGET_PPC64) - tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL); -#else - tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); - tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000); -#endif + tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], + 0x80000000); + tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], + 0x80000000); } /* Conversion */ @@ -9771,12 +9552,9 @@ static inline void gen_efdabs(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_SPEU); return; } -#if defined(TARGET_PPC64) - tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL); -#else tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); - tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000); -#endif + tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], + ~0x80000000); } static inline void gen_efdnabs(DisasContext *ctx) { @@ -9784,12 +9562,9 @@ static inline void gen_efdnabs(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_SPEU); return; } -#if defined(TARGET_PPC64) - tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL); -#else tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); - tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000); -#endif + tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], + 0x80000000); } static inline void gen_efdneg(DisasContext *ctx) { @@ -9797,12 +9572,9 @@ static inline void gen_efdneg(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_SPEU); return; } -#if defined(TARGET_PPC64) - tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL); -#else tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); - tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000); -#endif + tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], + 0x80000000); } /* Conversion */ @@ -9880,7 +9652,7 @@ GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), -GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB), +GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0x0000F801, PPC_POPCNTB), GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD), GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205), #if defined(TARGET_PPC64) @@ -9982,6 +9754,7 @@ GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE), GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE), GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE), GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE), +GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206), GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ), GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC), GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC), @@ -10999,6 +10772,166 @@ GEN_XXSEL_ROW(0x1F) GEN_XX3FORM_DM(xxpermdi, 0x08, 0x01), +#undef GEN_DFP_T_A_B_Rc +#undef GEN_DFP_BF_A_B +#undef GEN_DFP_BF_A_DCM +#undef GEN_DFP_T_B_U32_U32_Rc +#undef GEN_DFP_T_A_B_I32_Rc +#undef GEN_DFP_T_B_Rc +#undef GEN_DFP_T_FPR_I32_Rc + +#define _GEN_DFP_LONG(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3B, op1, op2, mask, PPC_NONE, PPC2_DFP) + +#define _GEN_DFP_LONGx2(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP) + +#define _GEN_DFP_LONGx4(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3B, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3B, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP) + +#define _GEN_DFP_QUAD(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3F, op1, op2, mask, PPC_NONE, PPC2_DFP) + +#define _GEN_DFP_QUADx2(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP) + +#define _GEN_DFP_QUADx4(name, op1, op2, mask) \ +GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3F, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \ +GEN_HANDLER_E(name, 0x3F, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP) + +#define GEN_DFP_T_A_B_Rc(name, op1, op2) \ +_GEN_DFP_LONG(name, op1, op2, 0x00000000) + +#define GEN_DFP_Tp_Ap_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x00210800) + +#define GEN_DFP_Tp_A_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x00200800) + +#define GEN_DFP_T_B_Rc(name, op1, op2) \ +_GEN_DFP_LONG(name, op1, op2, 0x001F0000) + +#define GEN_DFP_Tp_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x003F0800) + +#define GEN_DFP_Tp_B_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x003F0000) + +#define GEN_DFP_T_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x001F0800) + +#define GEN_DFP_BF_A_B(name, op1, op2) \ +_GEN_DFP_LONG(name, op1, op2, 0x00000001) + +#define GEN_DFP_BF_Ap_Bp(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x00610801) + +#define GEN_DFP_BF_A_Bp(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x00600801) + +#define GEN_DFP_BF_A_DCM(name, op1, op2) \ +_GEN_DFP_LONGx2(name, op1, op2, 0x00600001) + +#define GEN_DFP_BF_Ap_DCM(name, op1, op2) \ +_GEN_DFP_QUADx2(name, op1, op2, 0x00610001) + +#define GEN_DFP_T_A_B_RMC_Rc(name, op1, op2) \ +_GEN_DFP_LONGx4(name, op1, op2, 0x00000000) + +#define GEN_DFP_Tp_Ap_Bp_RMC_Rc(name, op1, op2) \ +_GEN_DFP_QUADx4(name, op1, op2, 0x02010800) + +#define GEN_DFP_Tp_A_Bp_RMC_Rc(name, op1, op2) \ +_GEN_DFP_QUADx4(name, op1, op2, 0x02000800) + +#define GEN_DFP_TE_T_B_RMC_Rc(name, op1, op2) \ +_GEN_DFP_LONGx4(name, op1, op2, 0x00000000) + +#define GEN_DFP_TE_Tp_Bp_RMC_Rc(name, op1, op2) \ +_GEN_DFP_QUADx4(name, op1, op2, 0x00200800) + +#define GEN_DFP_R_T_B_RMC_Rc(name, op1, op2) \ +_GEN_DFP_LONGx4(name, op1, op2, 0x001E0000) + +#define GEN_DFP_R_Tp_Bp_RMC_Rc(name, op1, op2) \ +_GEN_DFP_QUADx4(name, op1, op2, 0x003E0800) + +#define GEN_DFP_SP_T_B_Rc(name, op1, op2) \ +_GEN_DFP_LONG(name, op1, op2, 0x00070000) + +#define GEN_DFP_SP_Tp_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x00270800) + +#define GEN_DFP_S_T_B_Rc(name, op1, op2) \ +_GEN_DFP_LONG(name, op1, op2, 0x000F0000) + +#define GEN_DFP_S_Tp_Bp_Rc(name, op1, op2) \ +_GEN_DFP_QUAD(name, op1, op2, 0x002F0800) + +#define GEN_DFP_T_A_SH_Rc(name, op1, op2) \ +_GEN_DFP_LONGx2(name, op1, op2, 0x00000000) + +#define GEN_DFP_Tp_Ap_SH_Rc(name, op1, op2) \ +_GEN_DFP_QUADx2(name, op1, op2, 0x00210000) + +GEN_DFP_T_A_B_Rc(dadd, 0x02, 0x00), +GEN_DFP_Tp_Ap_Bp_Rc(daddq, 0x02, 0x00), +GEN_DFP_T_A_B_Rc(dsub, 0x02, 0x10), +GEN_DFP_Tp_Ap_Bp_Rc(dsubq, 0x02, 0x10), +GEN_DFP_T_A_B_Rc(dmul, 0x02, 0x01), +GEN_DFP_Tp_Ap_Bp_Rc(dmulq, 0x02, 0x01), +GEN_DFP_T_A_B_Rc(ddiv, 0x02, 0x11), +GEN_DFP_Tp_Ap_Bp_Rc(ddivq, 0x02, 0x11), +GEN_DFP_BF_A_B(dcmpu, 0x02, 0x14), +GEN_DFP_BF_Ap_Bp(dcmpuq, 0x02, 0x14), +GEN_DFP_BF_A_B(dcmpo, 0x02, 0x04), +GEN_DFP_BF_Ap_Bp(dcmpoq, 0x02, 0x04), +GEN_DFP_BF_A_DCM(dtstdc, 0x02, 0x06), +GEN_DFP_BF_Ap_DCM(dtstdcq, 0x02, 0x06), +GEN_DFP_BF_A_DCM(dtstdg, 0x02, 0x07), +GEN_DFP_BF_Ap_DCM(dtstdgq, 0x02, 0x07), +GEN_DFP_BF_A_B(dtstex, 0x02, 0x05), +GEN_DFP_BF_Ap_Bp(dtstexq, 0x02, 0x05), +GEN_DFP_BF_A_B(dtstsf, 0x02, 0x15), +GEN_DFP_BF_A_Bp(dtstsfq, 0x02, 0x15), +GEN_DFP_TE_T_B_RMC_Rc(dquai, 0x03, 0x02), +GEN_DFP_TE_Tp_Bp_RMC_Rc(dquaiq, 0x03, 0x02), +GEN_DFP_T_A_B_RMC_Rc(dqua, 0x03, 0x00), +GEN_DFP_Tp_Ap_Bp_RMC_Rc(dquaq, 0x03, 0x00), +GEN_DFP_T_A_B_RMC_Rc(drrnd, 0x03, 0x01), +GEN_DFP_Tp_A_Bp_RMC_Rc(drrndq, 0x03, 0x01), +GEN_DFP_R_T_B_RMC_Rc(drintx, 0x03, 0x03), +GEN_DFP_R_Tp_Bp_RMC_Rc(drintxq, 0x03, 0x03), +GEN_DFP_R_T_B_RMC_Rc(drintn, 0x03, 0x07), +GEN_DFP_R_Tp_Bp_RMC_Rc(drintnq, 0x03, 0x07), +GEN_DFP_T_B_Rc(dctdp, 0x02, 0x08), +GEN_DFP_Tp_B_Rc(dctqpq, 0x02, 0x08), +GEN_DFP_T_B_Rc(drsp, 0x02, 0x18), +GEN_DFP_Tp_Bp_Rc(drdpq, 0x02, 0x18), +GEN_DFP_T_B_Rc(dcffix, 0x02, 0x19), +GEN_DFP_Tp_B_Rc(dcffixq, 0x02, 0x19), +GEN_DFP_T_B_Rc(dctfix, 0x02, 0x09), +GEN_DFP_T_Bp_Rc(dctfixq, 0x02, 0x09), +GEN_DFP_SP_T_B_Rc(ddedpd, 0x02, 0x0a), +GEN_DFP_SP_Tp_Bp_Rc(ddedpdq, 0x02, 0x0a), +GEN_DFP_S_T_B_Rc(denbcd, 0x02, 0x1a), +GEN_DFP_S_Tp_Bp_Rc(denbcdq, 0x02, 0x1a), +GEN_DFP_T_B_Rc(dxex, 0x02, 0x0b), +GEN_DFP_T_Bp_Rc(dxexq, 0x02, 0x0b), +GEN_DFP_T_A_B_Rc(diex, 0x02, 0x1b), +GEN_DFP_Tp_A_Bp_Rc(diexq, 0x02, 0x1b), +GEN_DFP_T_A_SH_Rc(dscli, 0x02, 0x02), +GEN_DFP_Tp_Ap_SH_Rc(dscliq, 0x02, 0x02), +GEN_DFP_T_A_SH_Rc(dscri, 0x02, 0x03), +GEN_DFP_Tp_Ap_SH_Rc(dscriq, 0x02, 0x03), + #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) @@ -11337,6 +11270,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, ctx.insns_flags2 = env->insns_flags2; ctx.access_type = -1; ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0; + 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); ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR); @@ -11374,6 +11308,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, max_insns = CF_COUNT_MASK; gen_tb_start(); + tcg_clear_temp_count(); /* Set env in case of segfault during code fetch */ while (ctx.exception == POWERPC_EXCP_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end) { @@ -11401,7 +11336,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, ctx.nip, ctx.mem_idx, (int)msr_ir); if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) gen_io_start(); - if (unlikely(ctx.le_mode)) { + if (unlikely(need_byteswap(&ctx))) { ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip)); } else { ctx.opcode = cpu_ldl_code(env, ctx.nip); @@ -11473,6 +11408,12 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, */ break; } + if (tcg_check_temp_count()) { + fprintf(stderr, "Opcode %02x %02x %02x (%08x) leaked temporaries\n", + opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), + ctx.opcode); + exit(1); + } } if (tb->cflags & CF_LAST_IO) gen_io_end(); |