[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/7] target-ppc: add exceptions for conditional stor
From: |
Nathan Froyd |
Subject: |
[Qemu-devel] [PATCH 5/7] target-ppc: add exceptions for conditional stores |
Date: |
Thu, 4 Jun 2009 11:52:00 -0700 |
Signed-off-by: Nathan Froyd <address@hidden>
---
target-ppc/cpu.h | 5 +++
target-ppc/translate.c | 71 ++++++++++++++++++++++++++++++++++-------------
2 files changed, 56 insertions(+), 20 deletions(-)
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 8d62218..1733a45 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -220,6 +220,7 @@ enum {
/* Qemu exceptions: special cases we want to stop translation */
POWERPC_EXCP_SYNC = 0x202, /* context synchronizing instruction */
POWERPC_EXCP_SYSCALL_USER = 0x203, /* System call in user mode only */
+ POWERPC_EXCP_STCX = 0x204 /* Conditional stores in user mode */
};
/* Exceptions error codes */
@@ -566,6 +567,10 @@ struct CPUPPCState {
target_ulong reserve_addr;
/* Reservation value */
target_ulong reserve_val;
+ /* Reservation store address */
+ target_ulong reserve_ea;
+ /* Reserved store source register and size */
+ target_ulong reserve_info;
/* Those ones are used in supervisor mode only */
/* machine state register */
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 5401434..78094c7 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3148,24 +3148,49 @@ GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001,
PPC_RES)
tcg_temp_free(t0);
}
+#if defined(CONFIG_USER_ONLY)
+static void gen_conditional_store (DisasContext *ctx, TCGv EA,
+ int reg, int size)
+{
+ TCGv t0 = tcg_temp_new();
+ uint32_t save_exception = ctx->exception;
+
+ tcg_gen_st_tl(EA, cpu_env, offsetof(CPUState, reserve_ea));
+ tcg_gen_movi_tl(t0, (size << 5) | reg);
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, reserve_info));
+ tcg_temp_free(t0);
+ gen_update_nip(ctx, ctx->nip-4);
+ ctx->exception = POWERPC_EXCP_BRANCH;
+ gen_exception(ctx, POWERPC_EXCP_STCX);
+ ctx->exception = save_exception;
+}
+#endif
+
/* stwcx. */
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
{
- int l1;
TCGv t0;
gen_set_access_type(ctx, ACCESS_RES);
t0 = tcg_temp_local_new();
gen_addr_reg_index(ctx, t0);
gen_check_align(ctx, t0, 0x03);
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
- tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
- tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
- l1 = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
- tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
- gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_reserve, -1);
+#if defined(CONFIG_USER_ONLY)
+ gen_conditional_store(ctx, t0, rS(ctx->opcode), 4);
+#else
+ {
+ int l1;
+
+ tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
+ tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
+ tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
+ l1 = gen_new_label();
+ tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
+ tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
+ gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
+ gen_set_label(l1);
+ tcg_gen_movi_tl(cpu_reserve, -1);
+ }
+#endif
tcg_temp_free(t0);
}
@@ -3188,21 +3213,27 @@ GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001,
PPC_64B)
/* stdcx. */
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
{
- int l1;
TCGv t0;
gen_set_access_type(ctx, ACCESS_RES);
t0 = tcg_temp_local_new();
gen_addr_reg_index(ctx, t0);
gen_check_align(ctx, t0, 0x07);
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
- tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
- tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
- l1 = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
- tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
- gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_reserve, -1);
+#if defined(CONFIG_USER_ONLY)
+ gen_conditional_store(ctx, t0, rS(ctx->opcode), 8);
+#else
+ {
+ int l1;
+ tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
+ tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
+ tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
+ l1 = gen_new_label();
+ tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
+ tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
+ gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
+ gen_set_label(l1);
+ tcg_gen_movi_tl(cpu_reserve, -1);
+ }
+#endif
tcg_temp_free(t0);
}
#endif /* defined(TARGET_PPC64) */
--
1.6.3.2
- [Qemu-devel] [PATCH 0/7] target-ppc/linux-user: NPTL support, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 7/7] enable NPTL for ppc-linux-user targets in configure, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 2/7] target-ppc: fix cpu_clone_regs, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 1/7] linux-user: initialize mmap_mutex properly, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 5/7] target-ppc: add exceptions for conditional stores,
Nathan Froyd <=
- [Qemu-devel] [PATCH 3/7] target-ppc: add cpu_set_tls, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 6/7] linux-user: handle POWERPC_EXCP_STCX, Nathan Froyd, 2009/06/04
- [Qemu-devel] [PATCH 4/7] target-ppc: retain l{w,d}arx loaded value, Nathan Froyd, 2009/06/04
- Re: [Qemu-devel] [PATCH 0/7] target-ppc/linux-user: NPTL support, malc, 2009/06/05
- Re: [Qemu-devel] [PATCH 0/7] target-ppc/linux-user: NPTL support, Miklos Vajna, 2009/06/09