From patchwork Mon Aug 3 15:43:26 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Froyd X-Patchwork-Id: 30646 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by bilbo.ozlabs.org (Postfix) with ESMTPS id 46659B6F1F for ; Tue, 4 Aug 2009 04:36:57 +1000 (EST) Received: from localhost ([127.0.0.1]:60185 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MY2Oz-0005oZ-SG for incoming@patchwork.ozlabs.org; Mon, 03 Aug 2009 14:36:53 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MXzhO-0005P9-MI for qemu-devel@nongnu.org; Mon, 03 Aug 2009 11:43:42 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MXzhJ-0005KE-8V for qemu-devel@nongnu.org; Mon, 03 Aug 2009 11:43:41 -0400 Received: from [199.232.76.173] (port=58821 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MXzhI-0005K2-Dw for qemu-devel@nongnu.org; Mon, 03 Aug 2009 11:43:36 -0400 Received: from mx20.gnu.org ([199.232.41.8]:50173) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MXzhH-0005kO-Ju for qemu-devel@nongnu.org; Mon, 03 Aug 2009 11:43:35 -0400 Received: from mail.codesourcery.com ([65.74.133.4]) by mx20.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MXzhD-0004NS-5K for qemu-devel@nongnu.org; Mon, 03 Aug 2009 11:43:31 -0400 Received: (qmail 20657 invoked from network); 3 Aug 2009 15:43:30 -0000 Received: from unknown (HELO localhost) (froydnj@127.0.0.2) by mail.codesourcery.com with ESMTPA; 3 Aug 2009 15:43:30 -0000 From: Nathan Froyd To: qemu-devel@nongnu.org Date: Mon, 3 Aug 2009 08:43:26 -0700 Message-Id: <1249314209-10230-5-git-send-email-froydnj@codesourcery.com> X-Mailer: git-send-email 1.6.3.2 In-Reply-To: <1249314209-10230-1-git-send-email-froydnj@codesourcery.com> References: <1249314209-10230-1-git-send-email-froydnj@codesourcery.com> X-Detected-Operating-System: by mx20.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Cc: Subject: [Qemu-devel] [PATCH 4/7] target-ppc: add exceptions for conditional stores X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Nathan Froyd --- 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 7935fcd..8c1029e 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -218,6 +218,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 */ @@ -564,6 +565,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 06282b6..f82c6e5 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -3018,24 +3018,49 @@ static void gen_lwarx(DisasContext *ctx) 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. */ static void gen_stwcx_(DisasContext *ctx) { - 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); } @@ -3058,21 +3083,27 @@ static void gen_ldarx(DisasContext *ctx) /* stdcx. */ static void gen_stdcx_(DisasContext *ctx) { - 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) */