#include "cpu.h"
#include "exec-all.h"
#include "disas.h"
-#include "helper.h"
#include "tcg-op.h"
#include "qemu-common.h"
+#include "helper.h"
+#define GEN_HELPER 1
+#include "helper.h"
+
#define CPU_SINGLE_STEP 0x1
#define CPU_BRANCH_STEP 0x2
#define GDBSTUB_SINGLE_STEP 0x4
/* Code translation helpers */
/* global register indexes */
-static TCGv cpu_env;
+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 */
#if !defined(TARGET_PPC64)
static TCGv cpu_gprh[32];
#endif
-static TCGv cpu_fpr[32];
-static TCGv cpu_avrh[32], cpu_avrl[32];
-static TCGv cpu_crf[8];
+static TCGv_i64 cpu_fpr[32];
+static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
+static TCGv_i32 cpu_crf[8];
static TCGv cpu_nip;
static TCGv cpu_ctr;
static TCGv cpu_lr;
static TCGv cpu_xer;
-static TCGv cpu_fpscr;
+static TCGv_i32 cpu_fpscr;
/* dyngen register indexes */
static TCGv cpu_T[3];
#if defined(TARGET_PPC64)
#define cpu_T64 cpu_T
#else
-static TCGv cpu_T64[3];
+static TCGv_i64 cpu_T64[3];
#endif
-static TCGv cpu_FT[3];
-static TCGv cpu_AVRh[3], cpu_AVRl[3];
+static TCGv_i64 cpu_FT[3];
+static TCGv_i64 cpu_AVRh[3], cpu_AVRl[3];
#include "gen-icount.h"
if (done_init)
return;
- cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
+ cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
#if TARGET_LONG_BITS > HOST_LONG_BITS
- cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
- TCG_AREG0, offsetof(CPUState, t0), "T0");
- cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
- TCG_AREG0, offsetof(CPUState, t1), "T1");
- cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
- TCG_AREG0, offsetof(CPUState, t2), "T2");
+ cpu_T[0] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, t0), "T0");
+ cpu_T[1] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, t1), "T1");
+ cpu_T[2] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, t2), "T2");
#else
- cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
- cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
- cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
+ cpu_T[0] = tcg_global_reg_new(TCG_AREG1, "T0");
+ cpu_T[1] = tcg_global_reg_new(TCG_AREG2, "T1");
+#ifdef HOST_I386
+ /* XXX: This is a temporary workaround for i386.
+ * On i386 qemu_st32 runs out of registers.
+ * The proper fix is to remove cpu_T.
+ */
+ cpu_T[2] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, t2), "T2");
+#else
+ cpu_T[2] = tcg_global_reg_new(TCG_AREG3, "T2");
+#endif
#endif
#if !defined(TARGET_PPC64)
- cpu_T64[0] = tcg_global_mem_new(TCG_TYPE_I64,
- TCG_AREG0, offsetof(CPUState, t0_64),
- "T0_64");
- cpu_T64[1] = tcg_global_mem_new(TCG_TYPE_I64,
- TCG_AREG0, offsetof(CPUState, t1_64),
- "T1_64");
- cpu_T64[2] = tcg_global_mem_new(TCG_TYPE_I64,
- TCG_AREG0, offsetof(CPUState, t2_64),
- "T2_64");
-#endif
-
- cpu_FT[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
- offsetof(CPUState, ft0), "FT0");
- cpu_FT[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
- offsetof(CPUState, ft1), "FT1");
- cpu_FT[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
- offsetof(CPUState, ft2), "FT2");
-
- cpu_AVRh[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+ cpu_T64[0] = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, t0_64),
+ "T0_64");
+ cpu_T64[1] = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, t1_64),
+ "T1_64");
+ cpu_T64[2] = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, t2_64),
+ "T2_64");
+#endif
+
+ cpu_FT[0] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, ft0), "FT0");
+ cpu_FT[1] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, ft1), "FT1");
+ cpu_FT[2] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, ft2), "FT2");
+
+ cpu_AVRh[0] = tcg_global_mem_new_i64(TCG_AREG0,
offsetof(CPUState, avr0.u64[0]), "AVR0H");
- cpu_AVRl[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+ cpu_AVRl[0] = tcg_global_mem_new_i64(TCG_AREG0,
offsetof(CPUState, avr0.u64[1]), "AVR0L");
- cpu_AVRh[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+ cpu_AVRh[1] = tcg_global_mem_new_i64(TCG_AREG0,
offsetof(CPUState, avr1.u64[0]), "AVR1H");
- cpu_AVRl[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+ cpu_AVRl[1] = tcg_global_mem_new_i64(TCG_AREG0,
offsetof(CPUState, avr1.u64[1]), "AVR1L");
- cpu_AVRh[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+ cpu_AVRh[2] = tcg_global_mem_new_i64(TCG_AREG0,
offsetof(CPUState, avr2.u64[0]), "AVR2H");
- cpu_AVRl[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+ cpu_AVRl[2] = tcg_global_mem_new_i64(TCG_AREG0,
offsetof(CPUState, avr2.u64[1]), "AVR2L");
p = cpu_reg_names;
for (i = 0; i < 8; i++) {
sprintf(p, "crf%d", i);
- cpu_crf[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
- offsetof(CPUState, crf[i]), p);
+ cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, crf[i]), p);
p += 5;
}
for (i = 0; i < 32; i++) {
sprintf(p, "r%d", i);
- cpu_gpr[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
+ cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, gpr[i]), p);
p += (i < 10) ? 3 : 4;
#if !defined(TARGET_PPC64)
sprintf(p, "r%dH", i);
- cpu_gprh[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
- offsetof(CPUState, gprh[i]), p);
+ cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, gprh[i]), p);
p += (i < 10) ? 4 : 5;
#endif
sprintf(p, "fp%d", i);
- cpu_fpr[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
- offsetof(CPUState, fpr[i]), p);
+ cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, fpr[i]), p);
p += (i < 10) ? 4 : 5;
sprintf(p, "avr%dH", i);
- cpu_avrh[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+ cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
offsetof(CPUState, avr[i].u64[0]), p);
p += (i < 10) ? 6 : 7;
sprintf(p, "avr%dL", i);
- cpu_avrl[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+ cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
offsetof(CPUState, avr[i].u64[1]), p);
p += (i < 10) ? 6 : 7;
}
- cpu_nip = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
+ cpu_nip = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, nip), "nip");
- cpu_ctr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
+ cpu_ctr = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, ctr), "ctr");
- cpu_lr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
+ cpu_lr = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, lr), "lr");
- cpu_xer = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+ cpu_xer = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, xer), "xer");
- cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
- offsetof(CPUState, fpscr), "fpscr");
+ cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, fpscr), "fpscr");
/* register helpers */
-#undef DEF_HELPER
-#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
+#define GEN_HELPER 2
#include "helper.h"
done_init = 1;
*gen_fprf_ptr++ = gen_opc_ptr;
#endif
gen_op_compute_fprf(1);
- if (unlikely(set_rc))
- tcg_gen_andi_i32(cpu_crf[1], cpu_T[0], 0xf);
+ if (unlikely(set_rc)) {
+ tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_T[0]);
+ tcg_gen_andi_i32(cpu_crf[1], cpu_crf[1], 0xf);
+ }
gen_op_float_check_status();
} else if (unlikely(set_rc)) {
/* We always need to compute fpcc */
gen_op_compute_fprf(0);
- tcg_gen_andi_i32(cpu_crf[1], cpu_T[0], 0xf);
+ tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_T[0]);
+ tcg_gen_andi_i32(cpu_crf[1], cpu_crf[1], 0xf);
if (set_fprf)
gen_op_float_check_status();
}
static always_inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
{
TCGv t0, t1;
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
- t1 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
+ t1 = tcg_temp_local_new();
if (s) {
tcg_gen_ext32s_tl(t0, arg0);
tcg_gen_ext32s_tl(t1, arg1);
int l1, l2;
uint32_t bi = rC(ctx->opcode);
uint32_t mask;
- TCGv t0;
+ TCGv_i32 t0;
l1 = gen_new_label();
l2 = gen_new_label();
mask = 1 << (3 - (bi & 0x03));
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ t0 = tcg_temp_new_i32();
tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
if (rA(ctx->opcode) == 0)
gen_set_label(l1);
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
gen_set_label(l2);
+ tcg_temp_free_i32(t0);
}
/*** Integer arithmetic ***/
l1 = gen_new_label();
/* Start with XER OV disabled, the most likely case */
tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
tcg_gen_xor_tl(t0, arg0, arg1);
#if defined(TARGET_PPC64)
if (!ctx->sf_mode)
#if defined(TARGET_PPC64)
if (!(ctx->sf_mode)) {
TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_TL);
- t1 = tcg_temp_new(TCG_TYPE_TL);
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
tcg_gen_ext32u_tl(t0, arg1);
tcg_gen_ext32u_tl(t1, arg2);
if (sub) {
tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l1);
- } else {
+ } else {
tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
}
+ tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
+ gen_set_label(l1);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
} else
#endif
- if (sub) {
- tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
- } else {
- tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
+ {
+ if (sub) {
+ tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
+ } else {
+ tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
+ }
+ tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
+ gen_set_label(l1);
}
- tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
- gen_set_label(l1);
}
/* Common add function */
TCGv t0, t1;
if ((!compute_ca && !compute_ov) ||
- (GET_TCGV(ret) != GET_TCGV(arg1) && GET_TCGV(ret) != GET_TCGV(arg2))) {
+ (!TCGV_EQUAL(ret,arg1) && !TCGV_EQUAL(ret, arg2))) {
t0 = ret;
} else {
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
}
if (add_ca) {
- t1 = tcg_temp_local_new(TCG_TYPE_TL);
+ t1 = tcg_temp_local_new();
tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
tcg_gen_shri_tl(t1, t1, XER_CA);
}
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, t0);
- if (GET_TCGV(t0) != GET_TCGV(ret)) {
+ if (!TCGV_EQUAL(t0, ret)) {
tcg_gen_mov_tl(ret, t0);
tcg_temp_free(t0);
}
tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
if (likely(simm != 0)) {
- TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ TCGv t0 = tcg_temp_local_new();
tcg_gen_addi_tl(t0, arg1, simm);
gen_op_arith_compute_ca(ctx, t0, arg1, 0);
tcg_gen_mov_tl(ret, t0);
static always_inline void gen_op_arith_divw (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
int sign, int compute_ov)
{
- int l1, l2, l3;
- TCGv t0, t1, t2;
+ int l1 = gen_new_label();
+ int l2 = gen_new_label();
+ TCGv_i32 t0 = tcg_temp_local_new_i32();
+ TCGv_i32 t1 = tcg_temp_local_new_i32();
-#if defined(TARGET_PPC64)
- t0 = tcg_temp_local_new(TCG_TYPE_I32);
- t1 = t0;
- t2 = tcg_temp_local_new(TCG_TYPE_I32);
- tcg_gen_trunc_i64_i32(t1, arg1);
- tcg_gen_trunc_i64_i32(t2, arg2);
-#else
- t0 = ret;
- t1 = arg1;
- t2 = arg2;
-#endif
- l1 = gen_new_label();
- l2 = gen_new_label();
- tcg_gen_brcondi_i32(TCG_COND_EQ, t2, 0, l1);
+ tcg_gen_trunc_tl_i32(t0, arg1);
+ tcg_gen_trunc_tl_i32(t1, arg2);
+ tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l1);
if (sign) {
- l3 = gen_new_label();
- tcg_gen_brcondi_i32(TCG_COND_NE, t2, -1, l3);
- tcg_gen_brcondi_i32(TCG_COND_EQ, t1, INT32_MIN, l1);
+ int l3 = gen_new_label();
+ tcg_gen_brcondi_i32(TCG_COND_NE, t1, -1, l3);
+ tcg_gen_brcondi_i32(TCG_COND_EQ, t0, INT32_MIN, l1);
gen_set_label(l3);
- }
- if (sign) {
- tcg_gen_div_i32(t0, t1, t2);
+ tcg_gen_div_i32(t0, t0, t1);
} else {
- tcg_gen_divu_i32(t0, t1, t2);
+ tcg_gen_divu_i32(t0, t0, t1);
}
if (compute_ov) {
tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
tcg_gen_br(l2);
gen_set_label(l1);
if (sign) {
- tcg_gen_sari_i32(t0, t1, 31);
+ tcg_gen_sari_i32(t0, t0, 31);
} else {
tcg_gen_movi_i32(t0, 0);
}
tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
}
gen_set_label(l2);
-#if defined(TARGET_PPC64)
- tcg_gen_extu_i32_i64(ret, t0);
- tcg_temp_free(t0);
-#endif
+ tcg_gen_extu_i32_tl(ret, t0);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, ret);
}
GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
#if defined(TARGET_PPC64)
-static always_inline void gen_op_divd (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
- int sign, int compute_ov)
+static always_inline void gen_op_arith_divd (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
+ int sign, int compute_ov)
{
- int l1, l2, l3;
-
- l1 = gen_new_label();
- l2 = gen_new_label();
+ int l1 = gen_new_label();
+ int l2 = gen_new_label();
tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
if (sign) {
- l3 = gen_new_label();
+ int l3 = gen_new_label();
tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
gen_set_label(l3);
- }
- if (sign) {
tcg_gen_div_i64(ret, arg1, arg2);
} else {
tcg_gen_divu_i64(ret, arg1, arg2);
#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov) \
GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B) \
{ \
- gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)], \
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
- sign, compute_ov); \
+ gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)], \
+ cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
+ sign, compute_ov); \
}
/* divwu divwu. divwuo divwuo. */
GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
/* mulhw mulhw. */
GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER)
{
- TCGv t0, t1;
+ TCGv_i64 t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- t1 = tcg_temp_new(TCG_TYPE_I64);
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
#if defined(TARGET_PPC64)
tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
tcg_gen_shri_i64(t0, t0, 32);
tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
#endif
- tcg_temp_free(t0);
- tcg_temp_free(t1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
}
/* mulhwu mulhwu. */
GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER)
{
- TCGv t0, t1;
+ TCGv_i64 t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- t1 = tcg_temp_new(TCG_TYPE_I64);
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
#if defined(TARGET_PPC64)
tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx->opcode)]);
tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx->opcode)]);
tcg_gen_shri_i64(t0, t0, 32);
tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
#endif
- tcg_temp_free(t0);
- tcg_temp_free(t1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
}
/* mullw mullw. */
GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER)
{
-#if defined(TARGET_PPC64)
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_TL);
- t1 = tcg_temp_new(TCG_TYPE_TL);
- tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mul_tl(t0, t0, t1);
- tcg_temp_free(t0);
- tcg_gen_ext32s_tl(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_temp_free(t1);
-#else
tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
cpu_gpr[rB(ctx->opcode)]);
-#endif
+ tcg_gen_ext32s_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)]);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
}
GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER)
{
int l1;
- TCGv t0, t1;
+ TCGv_i64 t0, t1;
- t0 = tcg_temp_local_new(TCG_TYPE_I64);
- t1 = tcg_temp_local_new(TCG_TYPE_I64);
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
l1 = gen_new_label();
/* Start with XER OV disabled, the most likely case */
tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
#endif
tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
gen_set_label(l1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
}
#define GEN_INT_ARITH_MUL_HELPER(name, opc3) \
GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B) \
{ \
- tcg_gen_helper_1_2(helper_##name, cpu_gpr[rD(ctx->opcode)], \
+ gen_helper_##name (cpu_gpr[rD(ctx->opcode)], \
cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \
if (unlikely(Rc(ctx->opcode) != 0)) \
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); \
#endif
/* neg neg. nego nego. */
-static always_inline void gen_op_neg (DisasContext *ctx, TCGv ret, TCGv arg1, int ov_check)
+static always_inline void gen_op_arith_neg (DisasContext *ctx, TCGv ret, TCGv arg1, int ov_check)
{
- int l1, l2;
-
- l1 = gen_new_label();
- l2 = gen_new_label();
+ int l1 = gen_new_label();
+ int l2 = gen_new_label();
+ TCGv t0 = tcg_temp_local_new();
#if defined(TARGET_PPC64)
if (ctx->sf_mode) {
- tcg_gen_brcondi_tl(TCG_COND_EQ, arg1, INT64_MIN, l1);
- } else {
- TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
- tcg_gen_ext32s_tl(t0, arg1);
+ tcg_gen_mov_tl(t0, arg1);
+ tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT64_MIN, l1);
+ } else
+#endif
+ {
+ tcg_gen_ext32s_tl(t0, arg1);
tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT32_MIN, l1);
}
-#else
- tcg_gen_brcondi_tl(TCG_COND_EQ, arg1, INT32_MIN, l1);
-#endif
tcg_gen_neg_tl(ret, arg1);
if (ov_check) {
tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
}
tcg_gen_br(l2);
gen_set_label(l1);
- tcg_gen_mov_tl(ret, arg1);
+ tcg_gen_mov_tl(ret, t0);
if (ov_check) {
tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
}
gen_set_label(l2);
+ tcg_temp_free(t0);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, ret);
}
GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER)
{
- gen_op_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
+ gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
}
GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER)
{
- gen_op_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
+ gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
}
/* Common subf function */
TCGv t0, t1;
if ((!compute_ca && !compute_ov) ||
- (GET_TCGV(ret) != GET_TCGV(arg1) && GET_TCGV(ret) != GET_TCGV(arg2))) {
+ (!TCGV_EQUAL(ret, arg1) && !TCGV_EQUAL(ret, arg2))) {
t0 = ret;
} else {
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
}
if (add_ca) {
- t1 = tcg_temp_local_new(TCG_TYPE_TL);
+ t1 = tcg_temp_local_new();
tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
tcg_gen_shri_tl(t1, t1, XER_CA);
}
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, t0);
- if (GET_TCGV(t0) != GET_TCGV(ret)) {
+ if (!TCGV_EQUAL(t0, ret)) {
tcg_gen_mov_tl(ret, t0);
tcg_temp_free(t0);
}
{
/* Start with XER CA and OV disabled, the most likely case */
tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
- TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ TCGv t0 = tcg_temp_local_new();
TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
gen_op_arith_compute_ca(ctx, t0, t1, 1);
/* cntlzw */
GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER)
{
- tcg_gen_helper_1_1(helper_cntlzw, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+ gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
}
break;
}
if (prio) {
- TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+ TCGv t0 = tcg_temp_new();
tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, spr[SPR_PPR]));
tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
{
#if defined(TARGET_PPC64)
if (ctx->sf_mode)
- tcg_gen_helper_1_1(helper_popcntb_64, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+ gen_helper_popcntb_64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
else
#endif
- tcg_gen_helper_1_1(helper_popcntb, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+ gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
}
#if defined(TARGET_PPC64)
/* cntlzd */
GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B)
{
- tcg_gen_helper_1_1(helper_cntlzd, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+ gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
}
if (likely(sh == 0 && mb == 0 && me == 31)) {
tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
} else {
- TCGv t0, t1;
target_ulong mask;
-
- t0 = tcg_temp_new(TCG_TYPE_TL);
- t1 = tcg_temp_new(TCG_TYPE_TL);
- if (likely(sh == 0)) {
- tcg_gen_mov_tl(t0, cpu_gpr[rS(ctx->opcode)]);
- } else {
- tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_shli_tl(t0, t1, sh);
- tcg_gen_shri_tl(t1, t1, 32 - sh);
- tcg_gen_or_tl(t0, t0, t1);
- }
+ TCGv t1;
+ TCGv t0 = tcg_temp_new();
+#if defined(TARGET_PPC64)
+ TCGv_i32 t2 = tcg_temp_new_i32();
+ tcg_gen_trunc_i64_i32(t2, cpu_gpr[rS(ctx->opcode)]);
+ tcg_gen_rotli_i32(t2, t2, sh);
+ tcg_gen_extu_i32_i64(t0, t2);
+ tcg_temp_free_i32(t2);
+#else
+ tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
+#endif
#if defined(TARGET_PPC64)
mb += 32;
me += 32;
#endif
mask = MASK(mb, me);
+ t1 = tcg_temp_new();
tcg_gen_andi_tl(t0, t0, mask);
tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
if (likely(sh == 0)) {
tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
} else {
- TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+ TCGv t0 = tcg_temp_new();
tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
tcg_gen_shli_tl(t0, t0, sh);
tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
tcg_temp_free(t0);
}
} else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
- TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+ TCGv t0 = tcg_temp_new();
tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
tcg_gen_shri_tl(t0, t0, mb);
tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
tcg_temp_free(t0);
} else {
- TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
- if (likely(sh != 0)) {
- TCGv t1 = tcg_temp_new(TCG_TYPE_TL);
- tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_shli_tl(t1, t0, sh);
- tcg_gen_shri_tl(t0, t0, 32 - sh);
- tcg_gen_or_tl(t0, t0, t1);
- tcg_temp_free(t1);
- } else {
- tcg_gen_mov_tl(t0, cpu_gpr[rS(ctx->opcode)]);
- }
+ TCGv t0 = tcg_temp_new();
+#if defined(TARGET_PPC64)
+ TCGv_i32 t1 = tcg_temp_new_i32();
+ tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
+ tcg_gen_rotli_i32(t1, t1, sh);
+ tcg_gen_extu_i32_i64(t0, t1);
+ tcg_temp_free_i32(t1);
+#else
+ tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
+#endif
#if defined(TARGET_PPC64)
mb += 32;
me += 32;
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
{
uint32_t mb, me;
- TCGv t0, t1, t2;
+ TCGv t0;
+#if defined(TARGET_PPC64)
+ TCGv_i32 t1, t2;
+#endif
mb = MB(ctx->opcode);
me = ME(ctx->opcode);
- t0 = tcg_temp_new(TCG_TYPE_TL);
+ t0 = tcg_temp_new();
tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
- t1 = tcg_temp_new(TCG_TYPE_TL);
- tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
- t2 = tcg_temp_new(TCG_TYPE_TL);
- tcg_gen_shl_tl(t2, t1, t0);
- tcg_gen_subfi_tl(t0, 32, t0);
- tcg_gen_shr_tl(t1, t1, t0);
- tcg_temp_free(t0);
- tcg_gen_or_tl(t2, t2, t1);
- tcg_temp_free(t1);
+#if defined(TARGET_PPC64)
+ t1 = tcg_temp_new_i32();
+ t2 = tcg_temp_new_i32();
+ tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
+ tcg_gen_trunc_i64_i32(t2, t0);
+ tcg_gen_rotl_i32(t1, t1, t2);
+ tcg_gen_extu_i32_i64(t0, t1);
+ tcg_temp_free_i32(t1);
+ tcg_temp_free_i32(t2);
+#else
+ tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
+#endif
if (unlikely(mb != 0 || me != 31)) {
#if defined(TARGET_PPC64)
mb += 32;
me += 32;
#endif
- tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t2, MASK(mb, me));
+ tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
} else {
- tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t2);
+ tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
}
- tcg_temp_free(t2);
+ tcg_temp_free(t0);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
}
} else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
} else {
- TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
- if (likely(sh != 0)) {
- TCGv t1 = tcg_temp_new(TCG_TYPE_TL);
- tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
- tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 64 - sh);
- tcg_gen_or_tl(t0, t0, t1);
- tcg_temp_free(t1);
- } else {
- tcg_gen_mov_tl(t0, cpu_gpr[rS(ctx->opcode)]);
- }
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
if (likely(mb == 0 && me == 63)) {
- tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
+ tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
} else {
tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
}
static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
uint32_t me)
{
- TCGv t0, t1;
+ TCGv t0;
mb = MB(ctx->opcode);
me = ME(ctx->opcode);
- t0 = tcg_temp_new(TCG_TYPE_TL);
+ t0 = tcg_temp_new();
tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
- t1 = tcg_temp_new(TCG_TYPE_TL);
- tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t0);
- tcg_gen_subfi_tl(t0, 64, t0);
- tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
- tcg_gen_or_tl(t1, t1, t0);
- tcg_temp_free(t0);
+ tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
if (unlikely(mb != 0 || me != 63)) {
- tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t1, MASK(mb, me));
- } else
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
- tcg_temp_free(t1);
+ tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
+ } else {
+ tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
+ }
+ tcg_temp_free(t0);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
}
TCGv t0, t1;
target_ulong mask;
- t0 = tcg_temp_new(TCG_TYPE_TL);
- t1 = tcg_temp_new(TCG_TYPE_TL);
- if (likely(sh == 0)) {
- tcg_gen_mov_tl(t0, cpu_gpr[rS(ctx->opcode)]);
- } else {
- tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
- tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 64 - sh);
- tcg_gen_or_tl(t0, t0, t1);
- }
+ t0 = tcg_temp_new();
+ tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
+ t1 = tcg_temp_new();
mask = MASK(mb, me);
tcg_gen_andi_tl(t0, t0, mask);
tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
l1 = gen_new_label();
l2 = gen_new_label();
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x20, l1);
tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
/* sraw & sraw. */
GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER)
{
- tcg_gen_helper_1_2(helper_sraw, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+ gen_helper_sraw(cpu_gpr[rA(ctx->opcode)],
+ cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
}
TCGv t0;
l1 = gen_new_label();
l2 = gen_new_label();
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
l1 = gen_new_label();
l2 = gen_new_label();
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x20, l1);
tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
tcg_gen_br(l2);
gen_set_label(l1);
- t1 = tcg_temp_new(TCG_TYPE_TL);
+ t1 = tcg_temp_new();
tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t1, t0);
tcg_temp_free(t1);
l1 = gen_new_label();
l2 = gen_new_label();
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x7f);
tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x40, l1);
tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
/* srad & srad. */
GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B)
{
- tcg_gen_helper_1_2(helper_srad, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+ gen_helper_srad(cpu_gpr[rA(ctx->opcode)],
+ cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
}
TCGv t0;
l1 = gen_new_label();
l2 = gen_new_label();
+ t0 = tcg_temp_local_new();
tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
- t0 = tcg_temp_new(TCG_TYPE_TL);
tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
gen_set_label(l1);
tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
gen_set_label(l2);
+ tcg_temp_free(t0);
tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
} else {
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
l1 = gen_new_label();
l2 = gen_new_label();
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x7f);
tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x40, l1);
tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
gen_reset_fpstatus();
- tcg_gen_helper_1_0(helper_fcmpo, cpu_crf[crfD(ctx->opcode)]);
+ gen_helper_fcmpo(cpu_crf[crfD(ctx->opcode)]);
gen_op_float_check_status();
}
tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
gen_reset_fpstatus();
- tcg_gen_helper_1_0(helper_fcmpu, cpu_crf[crfD(ctx->opcode)]);
+ gen_helper_fcmpu(cpu_crf[crfD(ctx->opcode)]);
gen_op_float_check_status();
}
if (likely(flags & 2)) \
tcg_gen_qemu_ld##width(t0, t1, flags >> 2); \
else { \
- TCGv addr = tcg_temp_new(TCG_TYPE_TL); \
+ TCGv addr = tcg_temp_new(); \
tcg_gen_ext32u_tl(addr, t1); \
tcg_gen_qemu_ld##width(t0, addr, flags >> 2); \
tcg_temp_free(addr); \
if (likely(flags & 2)) \
tcg_gen_qemu_st##width(t0, t1, flags >> 2); \
else { \
- TCGv addr = tcg_temp_new(TCG_TYPE_TL); \
+ TCGv addr = tcg_temp_new(); \
tcg_gen_ext32u_tl(addr, t1); \
tcg_gen_qemu_st##width(t0, addr, flags >> 2); \
tcg_temp_free(addr); \
static always_inline void gen_qemu_ld16u(TCGv arg0, TCGv arg1, int flags)
{
if (unlikely(flags & 1)) {
- TCGv t0;
+ TCGv_i32 t0;
gen_qemu_ld16u_ppc64(arg0, arg1, flags);
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ t0 = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(t0, arg0);
tcg_gen_bswap16_i32(t0, t0);
tcg_gen_extu_i32_tl(arg0, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
} else
gen_qemu_ld16u_ppc64(arg0, arg1, flags);
}
static always_inline void gen_qemu_ld16s(TCGv arg0, TCGv arg1, int flags)
{
if (unlikely(flags & 1)) {
- TCGv t0;
+ TCGv_i32 t0;
gen_qemu_ld16u_ppc64(arg0, arg1, flags);
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ t0 = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(t0, arg0);
tcg_gen_bswap16_i32(t0, t0);
tcg_gen_extu_i32_tl(arg0, t0);
tcg_gen_ext16s_tl(arg0, arg0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
} else
gen_qemu_ld16s_ppc64(arg0, arg1, flags);
}
static always_inline void gen_qemu_ld32u(TCGv arg0, TCGv arg1, int flags)
{
if (unlikely(flags & 1)) {
- TCGv t0;
+ TCGv_i32 t0;
gen_qemu_ld32u_ppc64(arg0, arg1, flags);
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ t0 = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(t0, arg0);
tcg_gen_bswap_i32(t0, t0);
tcg_gen_extu_i32_tl(arg0, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
} else
gen_qemu_ld32u_ppc64(arg0, arg1, flags);
}
static always_inline void gen_qemu_ld32s(TCGv arg0, TCGv arg1, int flags)
{
if (unlikely(flags & 1)) {
- TCGv t0;
+ TCGv_i32 t0;
gen_qemu_ld32u_ppc64(arg0, arg1, flags);
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ t0 = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(t0, arg0);
tcg_gen_bswap_i32(t0, t0);
tcg_gen_ext_i32_tl(arg0, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
} else
gen_qemu_ld32s_ppc64(arg0, arg1, flags);
}
static always_inline void gen_qemu_st16(TCGv arg0, TCGv arg1, int flags)
{
if (unlikely(flags & 1)) {
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 t0;
+ TCGv_i64 t1;
+ t0 = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(t0, arg0);
tcg_gen_ext16u_i32(t0, t0);
tcg_gen_bswap16_i32(t0, t0);
- t1 = tcg_temp_new(TCG_TYPE_I64);
+ t1 = tcg_temp_new_i64();
tcg_gen_extu_i32_tl(t1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
gen_qemu_st16_ppc64(t1, arg1, flags);
- tcg_temp_free(t1);
+ tcg_temp_free_i64(t1);
} else
gen_qemu_st16_ppc64(arg0, arg1, flags);
}
static always_inline void gen_qemu_st32(TCGv arg0, TCGv arg1, int flags)
{
if (unlikely(flags & 1)) {
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 t0;
+ TCGv_i64 t1;
+ t0 = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(t0, arg0);
tcg_gen_bswap_i32(t0, t0);
- t1 = tcg_temp_new(TCG_TYPE_I64);
+ t1 = tcg_temp_new_i64();
tcg_gen_extu_i32_tl(t1, t0);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
gen_qemu_st32_ppc64(t1, arg1, flags);
- tcg_temp_free(t1);
+ tcg_temp_free_i64(t1);
} else
gen_qemu_st32_ppc64(arg0, arg1, flags);
}
static always_inline void gen_qemu_st64(TCGv arg0, TCGv arg1, int flags)
{
if (unlikely(flags & 1)) {
- TCGv t0 = tcg_temp_new(TCG_TYPE_I64);
+ TCGv_i64 t0 = tcg_temp_new_i64();
tcg_gen_bswap_i64(t0, arg0);
gen_qemu_st64_ppc64(t0, arg1, flags);
- tcg_temp_free(t0);
+ tcg_temp_free_i64(t0);
} else
gen_qemu_st64_ppc64(arg0, arg1, flags);
}
GEN_QEMU_LD_PPC32(16s)
GEN_QEMU_LD_PPC32(32u)
GEN_QEMU_LD_PPC32(32s)
-GEN_QEMU_LD_PPC32(64)
#define GEN_QEMU_ST_PPC32(width) \
static always_inline void gen_qemu_st##width##_ppc32(TCGv arg0, TCGv arg1, int flags)\
GEN_QEMU_ST_PPC32(8)
GEN_QEMU_ST_PPC32(16)
GEN_QEMU_ST_PPC32(32)
-GEN_QEMU_ST_PPC32(64)
static always_inline void gen_qemu_ld8u(TCGv arg0, TCGv arg1, int flags)
{
tcg_gen_bswap_i32(arg0, arg0);
}
-static always_inline void gen_qemu_ld64(TCGv arg0, TCGv arg1, int flags)
-{
- gen_qemu_ld64_ppc32(arg0, arg1, flags);
- if (unlikely(flags & 1))
- tcg_gen_bswap_i64(arg0, arg0);
-}
-
static always_inline void gen_qemu_st8(TCGv arg0, TCGv arg1, int flags)
{
- gen_qemu_st8_ppc32(arg0, arg1, flags >> 1);
+ gen_qemu_st8_ppc32(arg0, arg1, flags);
}
static always_inline void gen_qemu_st16(TCGv arg0, TCGv arg1, int flags)
{
if (unlikely(flags & 1)) {
- TCGv temp = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 temp = tcg_temp_new_i32();
tcg_gen_ext16u_i32(temp, arg0);
tcg_gen_bswap16_i32(temp, temp);
- gen_qemu_st16_ppc32(temp, arg1, flags >> 1);
- tcg_temp_free(temp);
+ gen_qemu_st16_ppc32(temp, arg1, flags);
+ tcg_temp_free_i32(temp);
} else
- gen_qemu_st16_ppc32(arg0, arg1, flags >> 1);
+ gen_qemu_st16_ppc32(arg0, arg1, flags);
}
static always_inline void gen_qemu_st32(TCGv arg0, TCGv arg1, int flags)
{
if (unlikely(flags & 1)) {
- TCGv temp = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 temp = tcg_temp_new_i32();
tcg_gen_bswap_i32(temp, arg0);
- gen_qemu_st32_ppc32(temp, arg1, flags >> 1);
- tcg_temp_free(temp);
- } else
- gen_qemu_st32_ppc32(arg0, arg1, flags >> 1);
-}
-
-static always_inline void gen_qemu_st64(TCGv arg0, TCGv arg1, int flags)
-{
- if (unlikely(flags & 1)) {
- TCGv temp = tcg_temp_new(TCG_TYPE_I64);
- tcg_gen_bswap_i64(temp, arg0);
- gen_qemu_st64_ppc32(temp, arg1, flags >> 1);
- tcg_temp_free(temp);
+ gen_qemu_st32_ppc32(temp, arg1, flags);
+ tcg_temp_free_i32(temp);
} else
- gen_qemu_st64_ppc32(arg0, arg1, flags >> 1);
+ gen_qemu_st32_ppc32(arg0, arg1, flags);
}
#endif
#define GEN_LD(width, opc, type) \
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
- TCGv EA = tcg_temp_new(TCG_TYPE_TL); \
+ TCGv EA = tcg_temp_new(); \
gen_addr_imm_index(EA, ctx, 0); \
gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
tcg_temp_free(EA); \
GEN_EXCP_INVAL(ctx); \
return; \
} \
- EA = tcg_temp_new(TCG_TYPE_TL); \
+ EA = tcg_temp_new(); \
if (type == PPC_64B) \
gen_addr_imm_index(EA, ctx, 0x03); \
else \
GEN_EXCP_INVAL(ctx); \
return; \
} \
- EA = tcg_temp_new(TCG_TYPE_TL); \
+ EA = tcg_temp_new(); \
gen_addr_reg_index(EA, ctx); \
gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
#define GEN_LDX(width, opc2, opc3, type) \
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
{ \
- TCGv EA = tcg_temp_new(TCG_TYPE_TL); \
+ TCGv EA = tcg_temp_new(); \
gen_addr_reg_index(EA, ctx); \
gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx); \
tcg_temp_free(EA); \
return;
}
}
- EA = tcg_temp_new(TCG_TYPE_TL);
+ EA = tcg_temp_new();
gen_addr_imm_index(EA, ctx, 0x03);
if (ctx->opcode & 0x02) {
/* lwa (lwau is undefined) */
GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
return;
}
- EA = tcg_temp_new(TCG_TYPE_TL);
+ EA = tcg_temp_new();
gen_addr_imm_index(EA, ctx, 0x0F);
gen_qemu_ld64(cpu_gpr[rd], EA, ctx->mem_idx);
tcg_gen_addi_tl(EA, EA, 8);
#define GEN_ST(width, opc, type) \
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \
{ \
- TCGv EA = tcg_temp_new(TCG_TYPE_TL); \
+ TCGv EA = tcg_temp_new(); \
gen_addr_imm_index(EA, ctx, 0); \
gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
tcg_temp_free(EA); \
GEN_EXCP_INVAL(ctx); \
return; \
} \
- EA = tcg_temp_new(TCG_TYPE_TL); \
+ EA = tcg_temp_new(); \
if (type == PPC_64B) \
gen_addr_imm_index(EA, ctx, 0x03); \
else \
GEN_EXCP_INVAL(ctx); \
return; \
} \
- EA = tcg_temp_new(TCG_TYPE_TL); \
+ EA = tcg_temp_new(); \
gen_addr_reg_index(EA, ctx); \
gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
#define GEN_STX(width, opc2, opc3, type) \
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
{ \
- TCGv EA = tcg_temp_new(TCG_TYPE_TL); \
+ TCGv EA = tcg_temp_new(); \
gen_addr_reg_index(EA, ctx); \
gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx); \
tcg_temp_free(EA); \
GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
return;
}
- EA = tcg_temp_new(TCG_TYPE_TL);
+ EA = tcg_temp_new();
gen_addr_imm_index(EA, ctx, 0x03);
gen_qemu_st64(cpu_gpr[rs], EA, ctx->mem_idx);
tcg_gen_addi_tl(EA, EA, 8);
return;
}
}
- EA = tcg_temp_new(TCG_TYPE_TL);
+ EA = tcg_temp_new();
gen_addr_imm_index(EA, ctx, 0x03);
gen_qemu_st64(cpu_gpr[rs], EA, ctx->mem_idx);
if (Rc(ctx->opcode))
/* lhbrx */
void always_inline gen_qemu_ld16ur(TCGv t0, TCGv t1, int flags)
{
- TCGv temp = tcg_temp_new(TCG_TYPE_I32);
- gen_qemu_ld16u(temp, t1, flags);
+ TCGv_i32 temp = tcg_temp_new_i32();
+ gen_qemu_ld16u(t0, t1, flags);
+ tcg_gen_trunc_tl_i32(temp, t0);
tcg_gen_bswap16_i32(temp, temp);
tcg_gen_extu_i32_tl(t0, temp);
- tcg_temp_free(temp);
+ tcg_temp_free_i32(temp);
}
GEN_LDX(16ur, 0x16, 0x18, PPC_INTEGER);
/* lwbrx */
void always_inline gen_qemu_ld32ur(TCGv t0, TCGv t1, int flags)
{
- TCGv temp = tcg_temp_new(TCG_TYPE_I32);
- gen_qemu_ld32u(temp, t1, flags);
+ TCGv_i32 temp = tcg_temp_new_i32();
+ gen_qemu_ld32u(t0, t1, flags);
+ tcg_gen_trunc_tl_i32(temp, t0);
tcg_gen_bswap_i32(temp, temp);
tcg_gen_extu_i32_tl(t0, temp);
- tcg_temp_free(temp);
+ tcg_temp_free_i32(temp);
}
GEN_LDX(32ur, 0x16, 0x10, PPC_INTEGER);
/* sthbrx */
void always_inline gen_qemu_st16r(TCGv t0, TCGv t1, int flags)
{
- TCGv temp = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 temp = tcg_temp_new_i32();
+ TCGv t2 = tcg_temp_new();
tcg_gen_trunc_tl_i32(temp, t0);
tcg_gen_ext16u_i32(temp, temp);
tcg_gen_bswap16_i32(temp, temp);
- gen_qemu_st16(temp, t1, flags);
- tcg_temp_free(temp);
+ tcg_gen_extu_i32_tl(t2, temp);
+ tcg_temp_free_i32(temp);
+ gen_qemu_st16(t2, t1, flags);
+ tcg_temp_free(t2);
}
GEN_STX(16r, 0x16, 0x1C, PPC_INTEGER);
/* stwbrx */
void always_inline gen_qemu_st32r(TCGv t0, TCGv t1, int flags)
{
- TCGv temp = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 temp = tcg_temp_new_i32();
+ TCGv t2 = tcg_temp_new();
tcg_gen_trunc_tl_i32(temp, t0);
tcg_gen_bswap_i32(temp, temp);
- gen_qemu_st32(temp, t1, flags);
- tcg_temp_free(temp);
+ tcg_gen_extu_i32_tl(t2, temp);
+ tcg_temp_free_i32(temp);
+ gen_qemu_st32(t2, t1, flags);
+ tcg_temp_free(t2);
}
GEN_STX(32r, 0x16, 0x14, PPC_INTEGER);
tcg_gen_movi_tl(cpu_nip, dest & ~3);
if (unlikely(ctx->singlestep_enabled)) {
if ((ctx->singlestep_enabled &
- (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
+ (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
ctx->exception == POWERPC_EXCP_BRANCH) {
target_ulong tmp = ctx->nip;
ctx->nip = dest;
ctx->exception = POWERPC_EXCP_BRANCH;
if (type == BCOND_LR || type == BCOND_CTR) {
- target = tcg_temp_local_new(TCG_TYPE_TL);
+ target = tcg_temp_local_new();
if (type == BCOND_CTR)
tcg_gen_mov_tl(target, cpu_ctr);
else
l1 = gen_new_label();
if ((bo & 0x4) == 0) {
/* Decrement and test CTR */
- TCGv temp = tcg_temp_new(TCG_TYPE_TL);
+ TCGv temp = tcg_temp_new();
if (unlikely(type == BCOND_CTR)) {
GEN_EXCP_INVAL(ctx);
return;
} else {
tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
}
+ tcg_temp_free(temp);
}
if ((bo & 0x10) == 0) {
/* Test CR */
uint32_t bi = BI(ctx->opcode);
uint32_t mask = 1 << (3 - (bi & 0x03));
- TCGv temp = tcg_temp_new(TCG_TYPE_I32);
+ TCGv_i32 temp = tcg_temp_new_i32();
if (bo & 0x8) {
tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
}
+ tcg_temp_free_i32(temp);
}
if (type == BCOND_IM) {
-
target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
if (likely(AA(ctx->opcode) == 0)) {
gen_goto_tb(ctx, 0, ctx->nip + li - 4);
{ \
uint8_t bitmask; \
int sh; \
- TCGv t0, t1; \
+ TCGv_i32 t0, t1; \
sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03); \
- t0 = tcg_temp_new(TCG_TYPE_I32); \
+ t0 = tcg_temp_new_i32(); \
if (sh > 0) \
tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh); \
else if (sh < 0) \
tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh); \
else \
tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]); \
- t1 = tcg_temp_new(TCG_TYPE_I32); \
+ t1 = tcg_temp_new_i32(); \
sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03); \
if (sh > 0) \
tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh); \
tcg_gen_andi_i32(t0, t0, bitmask); \
tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask); \
tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1); \
- tcg_temp_free(t0); \
- tcg_temp_free(t1); \
+ tcg_temp_free_i32(t0); \
+ tcg_temp_free_i32(t1); \
}
/* crand */
tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
}
} else {
- tcg_gen_helper_1_0(helper_load_cr, cpu_gpr[rD(ctx->opcode)]);
+ gen_helper_load_cr(cpu_gpr[rD(ctx->opcode)]);
}
}
crm = CRM(ctx->opcode);
if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
+ TCGv_i32 temp = tcg_temp_new_i32();
crn = ffs(crm);
- tcg_gen_shri_i32(cpu_crf[7 - crn], cpu_gpr[rS(ctx->opcode)], crn * 4);
+ tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
+ tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
+ tcg_temp_free_i32(temp);
} else {
- TCGv t0 = tcg_const_tl(crm);
- tcg_gen_helper_0_2(helper_store_cr, cpu_gpr[rS(ctx->opcode)], t0);
- tcg_temp_free(t0);
+ TCGv_i32 temp = tcg_const_i32(crm);
+ gen_helper_store_cr(cpu_gpr[rS(ctx->opcode)], temp);
+ tcg_temp_free_i32(temp);
}
}
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
{
/* XXX: specification says this is treated as a load by the MMU */
- TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+ TCGv t0 = tcg_temp_new();
gen_addr_reg_index(t0, ctx);
gen_qemu_ld8u(t0, t0, ctx->mem_idx);
tcg_temp_free(t0);
GEN_EXCP_PRIVOPC(ctx);
return;
}
- EA = tcg_temp_new(TCG_TYPE_TL);
+ EA = tcg_temp_new();
gen_addr_reg_index(EA, ctx);
- val = tcg_temp_new(TCG_TYPE_TL);
+ val = tcg_temp_new();
/* XXX: specification says this should be treated as a store by the MMU */
gen_qemu_ld8u(val, EA, ctx->mem_idx);
gen_qemu_st8(val, EA, ctx->mem_idx);
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
{
/* XXX: specification say this is treated as a load by the MMU */
- TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+ TCGv t0 = tcg_temp_new();
gen_addr_reg_index(t0, ctx);
gen_qemu_ld8u(t0, t0, ctx->mem_idx);
tcg_temp_free(t0);
{
TCGv t0, t1;
- t0 = tcg_temp_local_new(TCG_TYPE_TL);
- t1 = tcg_temp_local_new(TCG_TYPE_TL);
+ t0 = tcg_temp_local_new();
+ t1 = tcg_temp_local_new();
switch (opc3 & 0x0D) {
case 0x05:
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
- if (opc3 & 0x02) {
+ if (opc3 & 0x02) {
/* Saturate */
tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
tcg_gen_xori_tl(t0, t0, 0x7fffffff);
} else {
/* Unsigned */
tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
- if (opc3 & 0x02) {
+ if (opc3 & 0x02) {
/* Saturate */
tcg_gen_movi_tl(t0, UINT32_MAX);
}
GEN_EXCP_PRIVOPC(ctx);
return;
}
- EA = tcg_temp_new(TCG_TYPE_TL);
+ EA = tcg_temp_new();
gen_addr_reg_index(EA, ctx);
- val = tcg_temp_new(TCG_TYPE_TL);
+ val = tcg_temp_new();
gen_qemu_ld32u(val, EA, ctx->mem_idx);
tcg_temp_free(val);
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]);
if (Rc(ctx->opcode)) {
gen_op_440_dlmzb_update_Rc();
- tcg_gen_andi_i32(cpu_crf[0], cpu_T[0], 0xf);
+ tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_T[0]);
+ tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 0xf);
}
}
/*** SPE extension ***/
/* Register moves */
-static always_inline void gen_load_gpr64(TCGv t, int reg) {
+static always_inline void gen_load_gpr64(TCGv_i64 t, int reg) {
#if defined(TARGET_PPC64)
tcg_gen_mov_i64(t, cpu_gpr[reg]);
#else
#endif
}
-static always_inline void gen_store_gpr64(int reg, TCGv t) {
+static always_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);
- TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
tcg_gen_shri_i64(tmp, t, 32);
tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
- tcg_temp_free(tmp);
+ tcg_temp_free_i64(tmp);
#endif
}
GEN_SPEOP_LD(name, sh); \
GEN_SPEOP_ST(name, sh)
-/* SPE arithmetic and logic */
-#define GEN_SPEOP_ARITH2(name) \
+/* SPE logic */
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_LOGIC2(name, tcg_op) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
return; \
} \
- gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \
- gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \
- gen_op_##name(); \
- gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \
+ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \
+ cpu_gpr[rB(ctx->opcode)]); \
}
-
-#define GEN_SPEOP_TCG_ARITH2(name, tcg_op) \
+#else
+#define GEN_SPEOP_LOGIC2(name, tcg_op) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
return; \
} \
- TCGv t0 = tcg_temp_new(TCG_TYPE_I64); \
- TCGv t1 = tcg_temp_new(TCG_TYPE_I64); \
- gen_load_gpr64(t0, rA(ctx->opcode)); \
- gen_load_gpr64(t1, rB(ctx->opcode)); \
- tcg_op(t0, t0, t1); \
- gen_store_gpr64(rD(ctx->opcode), t0); \
- tcg_temp_free(t0); \
- tcg_temp_free(t1); \
+ 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
+
+GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
+GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
+GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
+GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
+GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
+GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
+GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
+GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
-#define GEN_SPEOP_ARITH1(name) \
+/* SPE logic immediate */
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
return; \
} \
- gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \
- gen_op_##name(); \
- gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \
+ 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_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_temp_free_i32(t0); \
+ tcg_temp_free_i32(t1); \
+}
+#else
+#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi) \
+static always_inline void gen_##name (DisasContext *ctx) \
+{ \
+ if (unlikely(!ctx->spe_enabled)) { \
+ GEN_EXCP_NO_AP(ctx); \
+ 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);
-#define GEN_SPEOP_COMP(name) \
+/* SPE arithmetic */
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_ARITH1(name, tcg_op) \
static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
return; \
} \
- gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \
- gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \
- gen_op_##name(); \
- tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf); \
-}
-
-/* Logical */
-GEN_SPEOP_TCG_ARITH2(evand, tcg_gen_and_i64);
-GEN_SPEOP_TCG_ARITH2(evandc, tcg_gen_andc_i64);
-GEN_SPEOP_TCG_ARITH2(evxor, tcg_gen_xor_i64);
-GEN_SPEOP_TCG_ARITH2(evor, tcg_gen_or_i64);
-GEN_SPEOP_TCG_ARITH2(evnor, tcg_gen_nor_i64);
-GEN_SPEOP_TCG_ARITH2(eveqv, tcg_gen_eqv_i64);
-GEN_SPEOP_TCG_ARITH2(evorc, tcg_gen_orc_i64);
-GEN_SPEOP_TCG_ARITH2(evnand, tcg_gen_nand_i64);
-GEN_SPEOP_ARITH2(evsrwu);
-GEN_SPEOP_ARITH2(evsrws);
-GEN_SPEOP_ARITH2(evslw);
-GEN_SPEOP_ARITH2(evrlw);
-GEN_SPEOP_ARITH2(evmergehi);
-GEN_SPEOP_ARITH2(evmergelo);
-GEN_SPEOP_ARITH2(evmergehilo);
-GEN_SPEOP_ARITH2(evmergelohi);
+ 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_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_temp_free_i32(t0); \
+ tcg_temp_free_i32(t1); \
+}
+#else
+#define GEN_SPEOP_ARITH1(name, tcg_op) \
+static always_inline void gen_##name (DisasContext *ctx) \
+{ \
+ if (unlikely(!ctx->spe_enabled)) { \
+ GEN_EXCP_NO_AP(ctx); \
+ 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
-/* Arithmetic */
-GEN_SPEOP_ARITH2(evaddw);
-GEN_SPEOP_ARITH2(evsubfw);
-GEN_SPEOP_ARITH1(evabs);
-GEN_SPEOP_ARITH1(evneg);
-GEN_SPEOP_ARITH1(evextsb);
-GEN_SPEOP_ARITH1(evextsh);
-GEN_SPEOP_ARITH1(evrndw);
-GEN_SPEOP_ARITH1(evcntlzw);
-GEN_SPEOP_ARITH1(evcntlsw);
-static always_inline void gen_brinc (DisasContext *ctx)
+static always_inline void gen_op_evabs (TCGv_i32 ret, TCGv_i32 arg1)
{
- /* Note: brinc is usable even if SPE is disabled */
- tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
- gen_op_brinc();
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
+ int l1 = gen_new_label();
+ int l2 = gen_new_label();
+
+ tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
+ tcg_gen_neg_i32(ret, arg1);
+ tcg_gen_br(l2);
+ gen_set_label(l1);
+ tcg_gen_mov_i32(ret, arg1);
+ gen_set_label(l2);
}
+GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
+GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
+GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
+GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
+static always_inline void gen_op_evrndw (TCGv_i32 ret, TCGv_i32 arg1)
+{
+ tcg_gen_addi_i32(ret, arg1, 0x8000);
+ tcg_gen_ext16u_i32(ret, ret);
+}
+GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
+GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
+GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
-#define GEN_SPEOP_ARITH_IMM2(name) \
-static always_inline void gen_##name##i (DisasContext *ctx) \
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_ARITH2(name, tcg_op) \
+static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
return; \
} \
- gen_load_gpr64(cpu_T64[0], rB(ctx->opcode)); \
- gen_op_splatwi_T1_64(rA(ctx->opcode)); \
- gen_op_##name(); \
- gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \
+ 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(TCG_TYPE_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); \
+ tcg_temp_free_i32(t0); \
+ tcg_temp_free_i32(t1); \
}
-
-#define GEN_SPEOP_LOGIC_IMM2(name) \
-static always_inline void gen_##name##i (DisasContext *ctx) \
+#else
+#define GEN_SPEOP_ARITH2(name, tcg_op) \
+static always_inline void gen_##name (DisasContext *ctx) \
{ \
if (unlikely(!ctx->spe_enabled)) { \
GEN_EXCP_NO_AP(ctx); \
return; \
} \
- gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \
- gen_op_splatwi_T1_64(rB(ctx->opcode)); \
- gen_op_##name(); \
- gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \
+ 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
-GEN_SPEOP_ARITH_IMM2(evaddw);
-#define gen_evaddiw gen_evaddwi
-GEN_SPEOP_ARITH_IMM2(evsubfw);
-#define gen_evsubifw gen_evsubfwi
-GEN_SPEOP_LOGIC_IMM2(evslw);
-GEN_SPEOP_LOGIC_IMM2(evsrwu);
-#define gen_evsrwis gen_evsrwsi
-GEN_SPEOP_LOGIC_IMM2(evsrws);
-#define gen_evsrwiu gen_evsrwui
-GEN_SPEOP_LOGIC_IMM2(evrlw);
+static always_inline void gen_op_evsrwu (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ TCGv_i32 t0;
+ int l1, l2;
-static always_inline void gen_evsplati (DisasContext *ctx)
+ l1 = gen_new_label();
+ l2 = gen_new_label();
+ t0 = tcg_temp_local_new_i32();
+ /* No error here: 6 bits are used */
+ tcg_gen_andi_i32(t0, arg2, 0x3F);
+ tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
+ tcg_gen_shr_i32(ret, arg1, t0);
+ tcg_gen_br(l2);
+ gen_set_label(l1);
+ tcg_gen_movi_i32(ret, 0);
+ tcg_gen_br(l2);
+ tcg_temp_free_i32(t0);
+}
+GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
+static always_inline void gen_op_evsrws (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ TCGv_i32 t0;
+ int l1, l2;
+
+ l1 = gen_new_label();
+ l2 = gen_new_label();
+ t0 = tcg_temp_local_new_i32();
+ /* No error here: 6 bits are used */
+ tcg_gen_andi_i32(t0, arg2, 0x3F);
+ tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
+ tcg_gen_sar_i32(ret, arg1, t0);
+ tcg_gen_br(l2);
+ gen_set_label(l1);
+ tcg_gen_movi_i32(ret, 0);
+ tcg_gen_br(l2);
+ tcg_temp_free_i32(t0);
+}
+GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
+static always_inline void gen_op_evslw (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ TCGv_i32 t0;
+ int l1, l2;
+
+ l1 = gen_new_label();
+ l2 = gen_new_label();
+ t0 = tcg_temp_local_new_i32();
+ /* No error here: 6 bits are used */
+ tcg_gen_andi_i32(t0, arg2, 0x3F);
+ tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
+ tcg_gen_shl_i32(ret, arg1, t0);
+ tcg_gen_br(l2);
+ gen_set_label(l1);
+ tcg_gen_movi_i32(ret, 0);
+ tcg_gen_br(l2);
+ tcg_temp_free_i32(t0);
+}
+GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
+static always_inline void gen_op_evrlw (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ tcg_gen_andi_i32(t0, arg2, 0x1F);
+ tcg_gen_rotl_i32(ret, arg1, t0);
+ tcg_temp_free_i32(t0);
+}
+GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
+static always_inline void gen_evmergehi (DisasContext *ctx)
+{
+ if (unlikely(!ctx->spe_enabled)) {
+ GEN_EXCP_NO_AP(ctx);
+ 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
+}
+GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
+static always_inline void gen_op_evsubf (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
{
- int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
+ tcg_gen_sub_i32(ret, arg2, arg1);
+}
+GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
- gen_op_splatwi_T0_64(imm);
- gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
+/* SPE arithmetic immediate */
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_ARITH_IMM2(name, tcg_op) \
+static always_inline void gen_##name (DisasContext *ctx) \
+{ \
+ if (unlikely(!ctx->spe_enabled)) { \
+ GEN_EXCP_NO_AP(ctx); \
+ 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)]); \
+ 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_temp_free_i32(t0); \
+ tcg_temp_free_i32(t1); \
}
+#else
+#define GEN_SPEOP_ARITH_IMM2(name, tcg_op) \
+static always_inline void gen_##name (DisasContext *ctx) \
+{ \
+ if (unlikely(!ctx->spe_enabled)) { \
+ GEN_EXCP_NO_AP(ctx); \
+ 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 always_inline void gen_##name (DisasContext *ctx) \
+{ \
+ if (unlikely(!ctx->spe_enabled)) { \
+ GEN_EXCP_NO_AP(ctx); \
+ 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 always_inline void gen_##name (DisasContext *ctx) \
+{ \
+ if (unlikely(!ctx->spe_enabled)) { \
+ GEN_EXCP_NO_AP(ctx); \
+ return; \
+ } \
+ int l1 = gen_new_label(); \
+ int l2 = gen_new_label(); \
+ int l3 = gen_new_label(); \
+ int l4 = gen_new_label(); \
+ \
+ tcg_gen_brcond_i32(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_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)], \
+ 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)); \
+ 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); \
+}
+#endif
+GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
+GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
+GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
+GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
+GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
+
+/* SPE misc */
+static always_inline void gen_brinc (DisasContext *ctx)
+{
+ /* Note: brinc is usable even if SPE is disabled */
+ gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
+ cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+}
+static always_inline void gen_evmergelo (DisasContext *ctx)
+{
+ if (unlikely(!ctx->spe_enabled)) {
+ GEN_EXCP_NO_AP(ctx);
+ return;
+ }
+#if defined(TARGET_PPC64)
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
+ 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_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+ tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+#endif
+}
+static always_inline void gen_evmergehilo (DisasContext *ctx)
+{
+ if (unlikely(!ctx->spe_enabled)) {
+ GEN_EXCP_NO_AP(ctx);
+ return;
+ }
+#if defined(TARGET_PPC64)
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
+ 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
+}
+static always_inline void gen_evmergelohi (DisasContext *ctx)
+{
+ if (unlikely(!ctx->spe_enabled)) {
+ GEN_EXCP_NO_AP(ctx);
+ 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
+ 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)]);
+#endif
+}
+static always_inline void gen_evsplati (DisasContext *ctx)
+{
+ int32_t imm = (int32_t)(rA(ctx->opcode) << 11) >> 27;
+
+#if defined(TARGET_PPC64)
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ tcg_gen_movi_tl(t0, imm);
+ tcg_gen_shri_tl(t1, t0, 32);
+ tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+#else
+ tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
+ tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
+#endif
+}
static always_inline void gen_evsplatfi (DisasContext *ctx)
{
- uint32_t imm = rA(ctx->opcode) << 27;
+ uint32_t imm = rA(ctx->opcode) << 11;
- gen_op_splatwi_T0_64(imm);
- gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
+#if defined(TARGET_PPC64)
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ tcg_gen_movi_tl(t0, imm);
+ tcg_gen_shri_tl(t1, t0, 32);
+ tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+#else
+ tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
+ tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
+#endif
}
-/* Comparison */
-GEN_SPEOP_COMP(evcmpgtu);
-GEN_SPEOP_COMP(evcmpgts);
-GEN_SPEOP_COMP(evcmpltu);
-GEN_SPEOP_COMP(evcmplts);
-GEN_SPEOP_COMP(evcmpeq);
+static always_inline void gen_evsel (DisasContext *ctx)
+{
+ 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();
+#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_andi_tl(t2, cpu_gpr[rA(ctx->opcode)], 0x00000000FFFFFFFFULL);
+#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_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFULL);
+#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
+}
+GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
+{
+ gen_evsel(ctx);
+}
+GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
+{
+ gen_evsel(ctx);
+}
+GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
+{
+ gen_evsel(ctx);
+}
+GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
+{
+ gen_evsel(ctx);
+}
GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, PPC_SPE); ////
GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, PPC_SPE);
GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, PPC_SPE); ////
GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, PPC_SPE); ////
-static always_inline void gen_evsel (DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- GEN_EXCP_NO_AP(ctx);
- return;
- }
- tcg_gen_mov_i32(cpu_T[0], cpu_crf[ctx->opcode & 0x7]);
- gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));
- gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));
- gen_op_evsel();
- gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
-}
-
-GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
-{
- gen_evsel(ctx);
-}
-GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
-{
- gen_evsel(ctx);
-}
-GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
-{
- gen_evsel(ctx);
-}
-GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
-{
- gen_evsel(ctx);
-}
-
/* Load and stores */
GEN_SPEOP_LDST(dd, 3);
GEN_SPEOP_LDST(dw, 3);
gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \
}
+#define GEN_SPEFPUOP_ARITH1(name) \
+static always_inline void gen_##name (DisasContext *ctx) \
+{ \
+ if (unlikely(!ctx->spe_enabled)) { \
+ GEN_EXCP_NO_AP(ctx); \
+ return; \
+ } \
+ gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \
+ gen_op_##name(); \
+ gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \
+}
+
+#define GEN_SPEFPUOP_ARITH2(name) \
+static always_inline void gen_##name (DisasContext *ctx) \
+{ \
+ if (unlikely(!ctx->spe_enabled)) { \
+ GEN_EXCP_NO_AP(ctx); \
+ return; \
+ } \
+ gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \
+ gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \
+ gen_op_##name(); \
+ gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \
+}
+
+#define GEN_SPEFPUOP_COMP(name) \
+static always_inline void gen_##name (DisasContext *ctx) \
+{ \
+ TCGv_i32 crf = cpu_crf[crfD(ctx->opcode)]; \
+ if (unlikely(!ctx->spe_enabled)) { \
+ GEN_EXCP_NO_AP(ctx); \
+ return; \
+ } \
+ gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \
+ gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \
+ gen_op_##name(); \
+ tcg_gen_trunc_tl_i32(crf, cpu_T[0]); \
+ tcg_gen_andi_i32(crf, crf, 0xf); \
+}
+
/* Single precision floating-point vectors operations */
/* Arithmetic */
-GEN_SPEOP_ARITH2(evfsadd);
-GEN_SPEOP_ARITH2(evfssub);
-GEN_SPEOP_ARITH2(evfsmul);
-GEN_SPEOP_ARITH2(evfsdiv);
-GEN_SPEOP_ARITH1(evfsabs);
-GEN_SPEOP_ARITH1(evfsnabs);
-GEN_SPEOP_ARITH1(evfsneg);
+GEN_SPEFPUOP_ARITH2(evfsadd);
+GEN_SPEFPUOP_ARITH2(evfssub);
+GEN_SPEFPUOP_ARITH2(evfsmul);
+GEN_SPEFPUOP_ARITH2(evfsdiv);
+GEN_SPEFPUOP_ARITH1(evfsabs);
+GEN_SPEFPUOP_ARITH1(evfsnabs);
+GEN_SPEFPUOP_ARITH1(evfsneg);
/* Conversion */
GEN_SPEFPUOP_CONV(evfscfui);
GEN_SPEFPUOP_CONV(evfscfsi);
GEN_SPEFPUOP_CONV(evfsctuiz);
GEN_SPEFPUOP_CONV(evfsctsiz);
/* Comparison */
-GEN_SPEOP_COMP(evfscmpgt);
-GEN_SPEOP_COMP(evfscmplt);
-GEN_SPEOP_COMP(evfscmpeq);
-GEN_SPEOP_COMP(evfststgt);
-GEN_SPEOP_COMP(evfststlt);
-GEN_SPEOP_COMP(evfststeq);
+GEN_SPEFPUOP_COMP(evfscmpgt);
+GEN_SPEFPUOP_COMP(evfscmplt);
+GEN_SPEFPUOP_COMP(evfscmpeq);
+GEN_SPEFPUOP_COMP(evfststgt);
+GEN_SPEFPUOP_COMP(evfststlt);
+GEN_SPEFPUOP_COMP(evfststeq);
/* Opcodes definitions */
GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
/* Single precision floating-point operations */
/* Arithmetic */
-GEN_SPEOP_ARITH2(efsadd);
-GEN_SPEOP_ARITH2(efssub);
-GEN_SPEOP_ARITH2(efsmul);
-GEN_SPEOP_ARITH2(efsdiv);
-GEN_SPEOP_ARITH1(efsabs);
-GEN_SPEOP_ARITH1(efsnabs);
-GEN_SPEOP_ARITH1(efsneg);
+GEN_SPEFPUOP_ARITH2(efsadd);
+GEN_SPEFPUOP_ARITH2(efssub);
+GEN_SPEFPUOP_ARITH2(efsmul);
+GEN_SPEFPUOP_ARITH2(efsdiv);
+GEN_SPEFPUOP_ARITH1(efsabs);
+GEN_SPEFPUOP_ARITH1(efsnabs);
+GEN_SPEFPUOP_ARITH1(efsneg);
/* Conversion */
GEN_SPEFPUOP_CONV(efscfui);
GEN_SPEFPUOP_CONV(efscfsi);
GEN_SPEFPUOP_CONV(efsctsiz);
GEN_SPEFPUOP_CONV(efscfd);
/* Comparison */
-GEN_SPEOP_COMP(efscmpgt);
-GEN_SPEOP_COMP(efscmplt);
-GEN_SPEOP_COMP(efscmpeq);
-GEN_SPEOP_COMP(efststgt);
-GEN_SPEOP_COMP(efststlt);
-GEN_SPEOP_COMP(efststeq);
+GEN_SPEFPUOP_COMP(efscmpgt);
+GEN_SPEFPUOP_COMP(efscmplt);
+GEN_SPEFPUOP_COMP(efscmpeq);
+GEN_SPEFPUOP_COMP(efststgt);
+GEN_SPEFPUOP_COMP(efststlt);
+GEN_SPEFPUOP_COMP(efststeq);
/* Opcodes definitions */
GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
/* Double precision floating-point operations */
/* Arithmetic */
-GEN_SPEOP_ARITH2(efdadd);
-GEN_SPEOP_ARITH2(efdsub);
-GEN_SPEOP_ARITH2(efdmul);
-GEN_SPEOP_ARITH2(efddiv);
-GEN_SPEOP_ARITH1(efdabs);
-GEN_SPEOP_ARITH1(efdnabs);
-GEN_SPEOP_ARITH1(efdneg);
+GEN_SPEFPUOP_ARITH2(efdadd);
+GEN_SPEFPUOP_ARITH2(efdsub);
+GEN_SPEFPUOP_ARITH2(efdmul);
+GEN_SPEFPUOP_ARITH2(efddiv);
+GEN_SPEFPUOP_ARITH1(efdabs);
+GEN_SPEFPUOP_ARITH1(efdnabs);
+GEN_SPEFPUOP_ARITH1(efdneg);
/* Conversion */
GEN_SPEFPUOP_CONV(efdcfui);
GEN_SPEFPUOP_CONV(efdctuidz);
GEN_SPEFPUOP_CONV(efdctsidz);
/* Comparison */
-GEN_SPEOP_COMP(efdcmpgt);
-GEN_SPEOP_COMP(efdcmplt);
-GEN_SPEOP_COMP(efdcmpeq);
-GEN_SPEOP_COMP(efdtstgt);
-GEN_SPEOP_COMP(efdtstlt);
-GEN_SPEOP_COMP(efdtsteq);
+GEN_SPEFPUOP_COMP(efdcmpgt);
+GEN_SPEFPUOP_COMP(efdcmplt);
+GEN_SPEFPUOP_COMP(efdcmpeq);
+GEN_SPEFPUOP_COMP(efdtstgt);
+GEN_SPEFPUOP_COMP(efdtstlt);
+GEN_SPEFPUOP_COMP(efdtsteq);
/* Opcodes definitions */
GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
target_ulong pc_start;
uint16_t *gen_opc_end;
int supervisor, little_endian;
+ CPUBreakpoint *bp;
int j, lj = -1;
int num_insns;
int max_insns;
gen_icount_start();
/* Set env in case of segfault during code fetch */
while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
- if (unlikely(env->nb_breakpoints > 0)) {
- for (j = 0; j < env->nb_breakpoints; j++) {
- if (env->breakpoints[j] == ctx.nip) {
+ if (unlikely(env->breakpoints)) {
+ for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (bp->pc == ctx.nip) {
gen_update_nip(&ctx, ctx.nip);
gen_op_debug();
break;