diff options
author | Nathan Froyd <froydnj@codesourcery.com> | 2009-08-03 08:43:25 -0700 |
---|---|---|
committer | malc <av1474@comtv.ru> | 2009-08-03 20:33:41 +0400 |
commit | 18b21a2f83a26c3d6a9e7f0bdc4e8eb2b177e8f6 (patch) | |
tree | 7e7a3100d4e34f207748ff34ab1be97231b3e467 | |
parent | 174c80d51612ce33960965c75e40c922599a503e (diff) | |
download | hqemu-18b21a2f83a26c3d6a9e7f0bdc4e8eb2b177e8f6.zip hqemu-18b21a2f83a26c3d6a9e7f0bdc4e8eb2b177e8f6.tar.gz |
target-ppc: retain l{w,d}arx loaded value
We do this so we can check on the corresponding stc{w,d}x. whether the
value has changed. It's a poor man's form of implementing atomic
operations and is valid only for NPTL usermode Linux emulation.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: malc <av1474@comtv.ru>
-rw-r--r-- | target-ppc/cpu.h | 4 | ||||
-rw-r--r-- | target-ppc/helper.c | 2 | ||||
-rw-r--r-- | target-ppc/machine.c | 4 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 4 | ||||
-rw-r--r-- | target-ppc/translate.c | 13 |
5 files changed, 17 insertions, 10 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index fe2257d..7935fcd 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -561,7 +561,9 @@ struct CPUPPCState { /* XER */ target_ulong xer; /* Reservation address */ - target_ulong reserve; + target_ulong reserve_addr; + /* Reservation value */ + target_ulong reserve_val; /* Those ones are used in supervisor mode only */ /* machine state register */ diff --git a/target-ppc/helper.c b/target-ppc/helper.c index b7162df..6eca2e5 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2805,7 +2805,7 @@ void cpu_ppc_reset (void *opaque) env->msr |= (1ULL << MSR_SF); #endif hreg_compute_hflags(env); - env->reserve = (target_ulong)-1ULL; + env->reserve_addr = (target_ulong)-1ULL; /* Be sure no exception or interrupt is pending */ env->pending_interrupts = 0; env->exception_index = POWERPC_EXCP_NONE; diff --git a/target-ppc/machine.c b/target-ppc/machine.c index 99ba3eb..deb2e2d 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -20,7 +20,7 @@ void cpu_save(QEMUFile *f, void *opaque) for (i = 0; i < 8; i++) qemu_put_be32s(f, &env->crf[i]); qemu_put_betls(f, &env->xer); - qemu_put_betls(f, &env->reserve); + qemu_put_betls(f, &env->reserve_addr); qemu_put_betls(f, &env->msr); for (i = 0; i < 4; i++) qemu_put_betls(f, &env->tgpr[i]); @@ -107,7 +107,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) for (i = 0; i < 8; i++) qemu_get_be32s(f, &env->crf[i]); qemu_get_betls(f, &env->xer); - qemu_get_betls(f, &env->reserve); + qemu_get_betls(f, &env->reserve_addr); qemu_get_betls(f, &env->msr); for (i = 0; i < 4; i++) qemu_get_betls(f, &env->tgpr[i]); diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index ad6d8ee..812282c 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -329,8 +329,8 @@ static void do_dcbz(target_ulong addr, int dcache_line_size) for (i = 0 ; i < dcache_line_size ; i += 4) { stl(addr + i , 0); } - if (env->reserve == addr) - env->reserve = (target_ulong)-1ULL; + if (env->reserve_addr == addr) + env->reserve_addr = (target_ulong)-1ULL; } void helper_dcbz(target_ulong addr) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 58818c2..06282b6 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -158,7 +158,8 @@ void ppc_translate_init(void) offsetof(CPUState, xer), "xer"); cpu_reserve = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUState, reserve), "reserve"); + offsetof(CPUState, reserve_addr), + "reserve_addr"); cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, fpscr), "fpscr"); @@ -3006,12 +3007,14 @@ static void gen_isync(DisasContext *ctx) static void gen_lwarx(DisasContext *ctx) { TCGv t0; + TCGv gpr = cpu_gpr[rD(ctx->opcode)]; gen_set_access_type(ctx, ACCESS_RES); t0 = tcg_temp_local_new(); gen_addr_reg_index(ctx, t0); gen_check_align(ctx, t0, 0x03); - gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0); + gen_qemu_ld32u(ctx, gpr, t0); tcg_gen_mov_tl(cpu_reserve, t0); + tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUState, reserve_val)); tcg_temp_free(t0); } @@ -3041,12 +3044,14 @@ static void gen_stwcx_(DisasContext *ctx) static void gen_ldarx(DisasContext *ctx) { TCGv t0; + TCGv gpr = cpu_gpr[rD(ctx->opcode)]; gen_set_access_type(ctx, ACCESS_RES); t0 = tcg_temp_local_new(); gen_addr_reg_index(ctx, t0); gen_check_align(ctx, t0, 0x07); - gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], t0); + gen_qemu_ld64(ctx, gpr, t0); tcg_gen_mov_tl(cpu_reserve, t0); + tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUState, reserve_val)); tcg_temp_free(t0); } @@ -8834,7 +8839,7 @@ void cpu_dump_state (CPUState *env, FILE *f, a = 'E'; cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' '); } - cpu_fprintf(f, " ] RES " ADDRX "\n", env->reserve); + cpu_fprintf(f, " ] RES " ADDRX "\n", env->reserve_addr); for (i = 0; i < 32; i++) { if ((i & (RFPL - 1)) == 0) cpu_fprintf(f, "FPR%02d", i); |