aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/helper.h21
-rw-r--r--target-ppc/op.c87
-rw-r--r--target-ppc/op_helper.c46
-rw-r--r--target-ppc/op_helper.h6
-rw-r--r--target-ppc/translate.c56
5 files changed, 86 insertions, 130 deletions
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
new file mode 100644
index 0000000000..1d3078e51b
--- /dev/null
+++ b/target-ppc/helper.h
@@ -0,0 +1,21 @@
+#ifndef DEF_HELPER
+#define DEF_HELPER(ret, name, params) ret name params;
+#endif
+
+DEF_HELPER(target_ulong, do_load_cr, (void))
+DEF_HELPER(void, do_print_mem_EA, (target_ulong))
+DEF_HELPER(void, do_store_cr, (uint32_t))
+
+#if !defined (CONFIG_USER_ONLY)
+DEF_HELPER(void, do_store_msr, (target_ulong))
+#if defined(TARGET_PPC64)
+DEF_HELPER(void, do_store_msr_32, (target_ulong))
+#endif
+#endif
+
+DEF_HELPER(target_ulong, do_popcntb, (target_ulong))
+#if defined(TARGET_PPC64)
+DEF_HELPER(target_ulong, do_popcntb_64, (target_ulong))
+#endif
+
+
diff --git a/target-ppc/op.c b/target-ppc/op.c
index 972b8bc29d..ea5967e79d 100644
--- a/target-ppc/op.c
+++ b/target-ppc/op.c
@@ -122,12 +122,6 @@
#define REG 31
#include "op_template.h"
-void OPPROTO op_print_mem_EA (void)
-{
- do_print_mem_EA(T0);
- RETURN();
-}
-
/* PowerPC state maintenance operations */
/* set_Rc0 */
void OPPROTO op_set_Rc0 (void)
@@ -136,13 +130,6 @@ void OPPROTO op_set_Rc0 (void)
RETURN();
}
-/* Constants load */
-void OPPROTO op_reset_T0 (void)
-{
- T0 = 0;
- RETURN();
-}
-
void OPPROTO op_set_T0 (void)
{
T0 = (uint32_t)PARAM1;
@@ -203,50 +190,11 @@ void OPPROTO op_raise_exception_err (void)
do_raise_exception_err(PARAM1, PARAM2);
}
-void OPPROTO op_update_nip (void)
-{
- env->nip = (uint32_t)PARAM1;
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_update_nip_64 (void)
-{
- env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
- RETURN();
-}
-#endif
-
void OPPROTO op_debug (void)
{
do_raise_exception(EXCP_DEBUG);
}
-/* Load/store special registers */
-void OPPROTO op_load_cr (void)
-{
- do_load_cr();
- RETURN();
-}
-
-void OPPROTO op_store_cr (void)
-{
- do_store_cr(PARAM1);
- RETURN();
-}
-
-void OPPROTO op_load_cro (void)
-{
- T0 = env->crf[PARAM1];
- RETURN();
-}
-
-void OPPROTO op_store_cro (void)
-{
- env->crf[PARAM1] = T0;
- RETURN();
-}
-
void OPPROTO op_load_xer_cr (void)
{
T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
@@ -352,27 +300,6 @@ void OPPROTO op_store_asr (void)
}
#endif
-void OPPROTO op_load_msr (void)
-{
- T0 = env->msr;
- RETURN();
-}
-
-void OPPROTO op_store_msr (void)
-{
- do_store_msr();
- RETURN();
-}
-
-#if defined (TARGET_PPC64)
-void OPPROTO op_store_msr_32 (void)
-{
- T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
- do_store_msr();
- RETURN();
-}
-#endif
-
void OPPROTO op_update_riee (void)
{
/* We don't call do_store_msr here as we won't trigger
@@ -1377,20 +1304,6 @@ void OPPROTO op_isel (void)
RETURN();
}
-void OPPROTO op_popcntb (void)
-{
- do_popcntb();
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_popcntb_64 (void)
-{
- do_popcntb_64();
- RETURN();
-}
-#endif
-
/*** Integer logical ***/
/* and */
void OPPROTO op_and (void)
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 1c08172807..19fa6ac6ea 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -68,16 +68,16 @@ void do_print_mem_EA (target_ulong EA)
/*****************************************************************************/
/* Registers load and stores */
-void do_load_cr (void)
+target_ulong do_load_cr (void)
{
- T0 = (env->crf[0] << 28) |
- (env->crf[1] << 24) |
- (env->crf[2] << 20) |
- (env->crf[3] << 16) |
- (env->crf[4] << 12) |
- (env->crf[5] << 8) |
- (env->crf[6] << 4) |
- (env->crf[7] << 0);
+ return (env->crf[0] << 28) |
+ (env->crf[1] << 24) |
+ (env->crf[2] << 20) |
+ (env->crf[3] << 16) |
+ (env->crf[4] << 12) |
+ (env->crf[5] << 8) |
+ (env->crf[6] << 4) |
+ (env->crf[7] << 0);
}
void do_store_cr (uint32_t mask)
@@ -429,27 +429,27 @@ void do_srad (void)
}
#endif
-void do_popcntb (void)
+target_ulong do_popcntb (target_ulong t0)
{
uint32_t ret;
int i;
ret = 0;
for (i = 0; i < 32; i += 8)
- ret |= ctpop8((T0 >> i) & 0xFF) << i;
- T0 = ret;
+ ret |= ctpop8((t0 >> i) & 0xFF) << i;
+ return ret;
}
#if defined(TARGET_PPC64)
-void do_popcntb_64 (void)
+target_ulong do_popcntb_64 (target_ulong t0)
{
uint64_t ret;
int i;
ret = 0;
for (i = 0; i < 64; i += 8)
- ret |= ctpop8((T0 >> i) & 0xFF) << i;
- T0 = ret;
+ ret |= ctpop8((t0 >> i) & 0xFF) << i;
+ return ret;
}
#endif
@@ -1404,15 +1404,23 @@ void do_fcmpo (void)
#if !defined (CONFIG_USER_ONLY)
void cpu_dump_rfi (target_ulong RA, target_ulong msr);
-void do_store_msr (void)
+void do_store_msr (target_ulong t0)
{
- T0 = hreg_store_msr(env, T0, 0);
- if (T0 != 0) {
+ t0 = hreg_store_msr(env, t0, 0);
+ if (t0 != 0) {
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
- do_raise_exception(T0);
+ do_raise_exception(t0);
}
}
+#if defined (TARGET_PPC64)
+void do_store_msr_32 (target_ulong t0)
+{
+ t0 = (env->msr & ~0xFFFFFFFFULL) | (t0 & 0xFFFFFFFF);
+ do_store_msr(t0);
+}
+#endif
+
static always_inline void __do_rfi (target_ulong nip, target_ulong msr,
target_ulong msrm, int keep_msrh)
{
diff --git a/target-ppc/op_helper.h b/target-ppc/op_helper.h
index 8c8c812051..b25db4a991 100644
--- a/target-ppc/op_helper.h
+++ b/target-ppc/op_helper.h
@@ -51,7 +51,6 @@ void glue(do_dcbz_64, MEMSUFFIX) (void);
void do_print_mem_EA (target_ulong EA);
/* Registers load and stores */
-void do_load_cr (void);
void do_store_cr (uint32_t mask);
#if defined(TARGET_PPC64)
void do_store_pri (int prio);
@@ -88,10 +87,6 @@ void do_subfmeo_64 (void);
void do_subfzeo_64 (void);
void do_srad (void);
#endif
-void do_popcntb (void);
-#if defined(TARGET_PPC64)
-void do_popcntb_64 (void);
-#endif
/* Floating-point arithmetic helpers */
void do_compute_fprf (int set_class);
@@ -138,7 +133,6 @@ void do_tw (int flags);
void do_td (int flags);
#endif
#if !defined(CONFIG_USER_ONLY)
-void do_store_msr (void);
void do_rfi (void);
#if defined(TARGET_PPC64)
void do_rfid (void);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index a7064f3032..a93459b9b8 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -26,6 +26,7 @@
#include "cpu.h"
#include "exec-all.h"
#include "disas.h"
+#include "helper.h"
#include "tcg-op.h"
#include "qemu-common.h"
@@ -65,9 +66,24 @@ void ppc_translate_init(void)
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");
#endif
+
+ /* register helpers */
+#undef DEF_HELPER
+#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
+#include "helper.h"
+
done_init = 1;
}
+static inline void tcg_gen_helper_0_i(void *func, TCGv arg)
+{
+ TCGv tmp = tcg_const_i32(arg);
+
+ tcg_gen_helper_0_1(func, tmp);
+ tcg_temp_free(tmp);
+}
+
+
#if defined(OPTIMIZE_FPRF_UPDATE)
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
static uint16_t **gen_fprf_ptr;
@@ -249,12 +265,16 @@ static always_inline void gen_optimize_fprf (void)
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
{
+ TCGv tmp;
#if defined(TARGET_PPC64)
if (ctx->sf_mode)
- gen_op_update_nip_64(nip >> 32, nip);
+ tmp = tcg_const_i64(nip);
else
#endif
- gen_op_update_nip(nip);
+ tmp = tcg_const_i32((uint32_t)nip);
+
+ tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUState, nip));
+ tcg_temp_free(tmp);
}
#define GEN_EXCP(ctx, excp, error) \
@@ -1305,7 +1325,7 @@ GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
gen_op_load_gpr_T1(rB(ctx->opcode));
gen_op_xor();
} else {
- gen_op_reset_T0();
+ tcg_gen_movi_tl(cpu_T[0], 0);
}
gen_op_store_T0_gpr(rA(ctx->opcode));
if (unlikely(Rc(ctx->opcode) != 0))
@@ -1376,10 +1396,10 @@ GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
gen_op_load_gpr_T0(rS(ctx->opcode));
#if defined(TARGET_PPC64)
if (ctx->sf_mode)
- gen_op_popcntb_64();
+ tcg_gen_helper_1_1(do_popcntb_64, cpu_T[0], cpu_T[0]);
else
#endif
- gen_op_popcntb();
+ tcg_gen_helper_1_1(do_popcntb, cpu_T[0], cpu_T[0]);
gen_op_store_T0_gpr(rA(ctx->opcode));
}
@@ -2100,7 +2120,7 @@ static always_inline void gen_addr_imm_index (DisasContext *ctx,
gen_op_addi(simm);
}
#ifdef DEBUG_MEMORY_ACCESSES
- gen_op_print_mem_EA();
+ tcg_gen_helper_0_0(do_print_mem_EA);
#endif
}
@@ -2114,19 +2134,19 @@ static always_inline void gen_addr_reg_index (DisasContext *ctx)
gen_op_add();
}
#ifdef DEBUG_MEMORY_ACCESSES
- gen_op_print_mem_EA();
+ tcg_gen_helper_0_0(do_print_mem_EA);
#endif
}
static always_inline void gen_addr_register (DisasContext *ctx)
{
if (rA(ctx->opcode) == 0) {
- gen_op_reset_T0();
+ tcg_gen_movi_tl(cpu_T[0], 0);
} else {
gen_op_load_gpr_T0(rA(ctx->opcode));
}
#ifdef DEBUG_MEMORY_ACCESSES
- gen_op_print_mem_EA();
+ tcg_gen_helper_0_0(do_print_mem_EA);
#endif
}
@@ -3225,10 +3245,10 @@ GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
crm = CRM(ctx->opcode);
if (likely((crm ^ (crm - 1)) == 0)) {
crn = ffs(crm);
- gen_op_load_cro(7 - crn);
+ tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUState, crf[7 - crn]));
}
} else {
- gen_op_load_cr();
+ tcg_gen_helper_1_0(do_load_cr, cpu_T[0]);
}
gen_op_store_T0_gpr(rD(ctx->opcode));
}
@@ -3243,7 +3263,7 @@ GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
GEN_EXCP_PRIVREG(ctx);
return;
}
- gen_op_load_msr();
+ tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, msr));
gen_op_store_T0_gpr(rD(ctx->opcode));
#endif
}
@@ -3327,10 +3347,10 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
crn = ffs(crm);
gen_op_srli_T0(crn * 4);
- gen_op_andi_T0(0xF);
- gen_op_store_cro(7 - crn);
+ tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xF);
+ tcg_gen_st8_tl(cpu_T[0], cpu_env, offsetof(CPUState, crf[7 - crn]));
} else {
- gen_op_store_cr(crm);
+ tcg_gen_helper_0_i(do_store_cr, crm);
}
}
@@ -3355,7 +3375,7 @@ GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
* directly from ppc_store_msr
*/
gen_update_nip(ctx, ctx->nip);
- gen_op_store_msr();
+ tcg_gen_helper_0_1(do_store_msr, cpu_T[0]);
/* Must stop the translation as machine state (may have) changed */
/* Note that mtmsr is not always defined as context-synchronizing */
ctx->exception = POWERPC_EXCP_STOP;
@@ -3385,10 +3405,10 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
gen_update_nip(ctx, ctx->nip);
#if defined(TARGET_PPC64)
if (!ctx->sf_mode)
- gen_op_store_msr_32();
+ tcg_gen_helper_0_1(do_store_msr_32, cpu_T[0]);
else
#endif
- gen_op_store_msr();
+ tcg_gen_helper_0_1(do_store_msr, cpu_T[0]);
/* Must stop the translation as machine state (may have) changed */
/* Note that mtmsrd is not always defined as context-synchronizing */
ctx->exception = POWERPC_EXCP_STOP;