aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-03-12 11:09:12 +0200
committerAvi Kivity <avi@redhat.com>2009-03-12 11:09:12 +0200
commit998e4d2f598ff44d00f64d528939bfd39ca11a6c (patch)
treedf1d8b88c98b269f434681d313dc6d58db2c4a3e /target-ppc
parentMerge branch 'qemu-cvs' (diff)
parentRevert r6404 (diff)
downloadqemu-kvm-998e4d2f598ff44d00f64d528939bfd39ca11a6c.tar.gz
qemu-kvm-998e4d2f598ff44d00f64d528939bfd39ca11a6c.tar.bz2
qemu-kvm-998e4d2f598ff44d00f64d528939bfd39ca11a6c.zip
Merge branch 'qemu-cvs'
* qemu-cvs: (37 commits) Revert r6404 Revert r6405 Revert r6406 Revert r6407 Revert r6408 tcg: move {not,neg}_i{32,64} definitions at the right place tcg: fix commit r6805 Clean build: Add bt-host.h tcg-arm: fix qemu_ld64 tcg: update TODO tcg/x86: add not/neg/extu/bswap/rot i32 ops tcg: optimize logical operations target-ppc: fix commit r6789 musicpal: Reorganize IO memory handling (Jan Kiszka) Fix tcg after commit 6800 target-mips: use nor instead of or + not tcg: use TCGV_EQUAL_I{32,64} tcg: define TCGV_EQUAL_I{32,64} tcg: optimize nor(X, Y, Y), used on PPC for not(X, Y) Implement TCG not ops for x86-64 ...
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/helper.h3
-rw-r--r--target-ppc/op_helper.c24
-rw-r--r--target-ppc/translate.c29
-rw-r--r--target-ppc/translate_init.c32
4 files changed, 50 insertions, 38 deletions
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 85cdd23c5..5a04bee70 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -30,9 +30,6 @@ DEF_HELPER_1(dcbz_970, void, tl)
DEF_HELPER_1(icbi, void, tl)
DEF_HELPER_4(lscbx, tl, tl, i32, i32, i32)
-DEF_HELPER_0(load_cr, tl)
-DEF_HELPER_2(store_cr, void, tl, i32)
-
#if defined(TARGET_PPC64)
DEF_HELPER_2(mulhd, i64, i64, i64)
DEF_HELPER_2(mulhdu, i64, i64, i64)
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index f21f695db..2c6a27fcb 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -54,30 +54,6 @@ void helper_raise_exception (uint32_t exception)
}
/*****************************************************************************/
-/* Registers load and stores */
-target_ulong helper_load_cr (void)
-{
- 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 helper_store_cr (target_ulong val, uint32_t mask)
-{
- int i, sh;
-
- for (i = 0, sh = 7; i < 8; i++, sh--) {
- if (mask & (1 << sh))
- env->crf[i] = (val >> (sh * 4)) & 0xFUL;
- }
-}
-
-/*****************************************************************************/
/* SPR accesses */
void helper_load_dump_spr (uint32_t sprn)
{
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index e400cf2da..0368c3743 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3859,7 +3859,24 @@ GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
cpu_gpr[rD(ctx->opcode)], crn * 4);
}
} else {
- gen_helper_load_cr(cpu_gpr[rD(ctx->opcode)]);
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ tcg_gen_mov_i32(t0, cpu_crf[0]);
+ tcg_gen_shli_i32(t0, t0, 4);
+ tcg_gen_or_i32(t0, t0, cpu_crf[1]);
+ tcg_gen_shli_i32(t0, t0, 4);
+ tcg_gen_or_i32(t0, t0, cpu_crf[2]);
+ tcg_gen_shli_i32(t0, t0, 4);
+ tcg_gen_or_i32(t0, t0, cpu_crf[3]);
+ tcg_gen_shli_i32(t0, t0, 4);
+ tcg_gen_or_i32(t0, t0, cpu_crf[4]);
+ tcg_gen_shli_i32(t0, t0, 4);
+ tcg_gen_or_i32(t0, t0, cpu_crf[5]);
+ tcg_gen_shli_i32(t0, t0, 4);
+ tcg_gen_or_i32(t0, t0, cpu_crf[6]);
+ tcg_gen_shli_i32(t0, t0, 4);
+ tcg_gen_or_i32(t0, t0, cpu_crf[7]);
+ tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
+ tcg_temp_free_i32(t0);
}
}
@@ -3956,8 +3973,14 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
tcg_temp_free_i32(temp);
}
} else {
- TCGv_i32 temp = tcg_const_i32(crm);
- gen_helper_store_cr(cpu_gpr[rS(ctx->opcode)], temp);
+ TCGv_i32 temp = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
+ for (crn = 0 ; crn < 8 ; crn++) {
+ if (crm & (1 << crn)) {
+ 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);
}
}
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index d02a0dd50..56d8d93e6 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -448,6 +448,23 @@ static void spr_write_pir (void *opaque, int sprn, int gprn)
}
#endif
+/* SPE specific registers */
+static void spr_read_spefscr (void *opaque, int gprn, int sprn)
+{
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUState, spe_fscr));
+ tcg_gen_extu_i32_tl(cpu_gpr[gprn], t0);
+ tcg_temp_free_i32(t0);
+}
+
+static void spr_write_spefscr (void *opaque, int sprn, int gprn)
+{
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]);
+ tcg_gen_st_i32(t0, cpu_env, offsetof(CPUState, spe_fscr));
+ tcg_temp_free_i32(t0);
+}
+
#if !defined(CONFIG_USER_ONLY)
/* Callback used to write the exception vector base */
static void spr_write_excp_prefix (void *opaque, int sprn, int gprn)
@@ -457,6 +474,7 @@ static void spr_write_excp_prefix (void *opaque, int sprn, int gprn)
tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, excp_prefix));
gen_store_spr(sprn, t0);
+ tcg_temp_free(t0);
}
static void spr_write_excp_vector (void *opaque, int sprn, int gprn)
@@ -2565,7 +2583,6 @@ static void gen_spr_8xx (CPUPPCState *env)
* HSRR1 => SPR 315 (Power 2.04 hypv)
* LPCR => SPR 316 (970)
* LPIDR => SPR 317 (970)
- * SPEFSCR => SPR 512 (Power 2.04 emb)
* EPR => SPR 702 (Power 2.04 emb)
* perf => 768-783 (Power 2.04)
* perf => 784-799 (Power 2.04)
@@ -4021,8 +4038,8 @@ static void init_proc_e200 (CPUPPCState *env)
gen_spr_BookE(env, 0x000000070000FFFFULL);
/* XXX : not implemented */
spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_spefscr, &spr_write_spefscr,
+ &spr_read_spefscr, &spr_write_spefscr,
0x00000000);
/* Memory management */
gen_spr_BookE_FSL(env, 0x0000005D);
@@ -4210,8 +4227,8 @@ static void init_proc_e500 (CPUPPCState *env)
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_spefscr, &spr_write_spefscr,
+ &spr_read_spefscr, &spr_write_spefscr,
0x00000000);
/* Memory management */
#if !defined(CONFIG_USER_ONLY)
@@ -9428,8 +9445,7 @@ static int gdb_get_spe_reg(CPUState *env, uint8_t *mem_buf, int n)
return 8;
}
if (n == 33) {
- /* SPEFSCR not implemented */
- memset(mem_buf, 0, 4);
+ stl_p(mem_buf, env->spe_fscr);
return 4;
}
return 0;
@@ -9452,7 +9468,7 @@ static int gdb_set_spe_reg(CPUState *env, uint8_t *mem_buf, int n)
return 8;
}
if (n == 33) {
- /* SPEFSCR not implemented */
+ env->spe_fscr = ldl_p(mem_buf);
return 4;
}
return 0;