From patchwork Fri Feb 15 14:18:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 14921 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 22E2523FC2 for ; Fri, 15 Feb 2013 14:18:42 +0000 (UTC) Received: from mail-vc0-f171.google.com (mail-vc0-f171.google.com [209.85.220.171]) by fiordland.canonical.com (Postfix) with ESMTP id B3BA7A1841D for ; Fri, 15 Feb 2013 14:18:41 +0000 (UTC) Received: by mail-vc0-f171.google.com with SMTP id p1so2219724vcq.30 for ; Fri, 15 Feb 2013 06:18:41 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state; bh=4ItwpoOMKjgeLqWRq2DrqspBD3M9konfFPe4MQvveTI=; b=S3TciAtiUHDLNE8mGSb3tUjS2hNjYJGDJXthQRhSFywlwUIXuflEh8abLvTzOufAQe 3TwA029t9mlH0ZTmijyzLw4eejsuRTYeqj2PSnjZfKR/3kupe5qyBdW4HAFnlrfhA41C U+Tq5S0IzXQDxLe7PmZWAvdjZh7h2GhB1e4cBx4O7dwKHRkK8gPoBv01ZYnu77LMxUG5 mr5NmNeDFvZOFG8SECX+jgA290dmXpvFH3O2gP3zab3ycwJWoAJFyzcDa1FHQOej9i2y 1ean+k2kgtF4E6GjI4aXFqnqvExqh49qhiDHLElygX/XGQmSn+pBJvLw6GC6Y+lv6odC JBDA== X-Received: by 10.58.40.9 with SMTP id t9mr3499672vek.10.1360937921152; Fri, 15 Feb 2013 06:18:41 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.221.4.5 with SMTP id oa5csp15575vcb; Fri, 15 Feb 2013 06:18:40 -0800 (PST) X-Received: by 10.194.88.202 with SMTP id bi10mr4669203wjb.5.1360937919923; Fri, 15 Feb 2013 06:18:39 -0800 (PST) Received: from mnementh.archaic.org.uk (1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id cs10si19472144wjc.83.2013.02.15.06.18.39 (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 15 Feb 2013 06:18:39 -0800 (PST) Received-SPF: neutral (google.com: 2001:8b0:1d0::1 is neither permitted nor denied by best guess record for domain of pm215@archaic.org.uk) client-ip=2001:8b0:1d0::1; Authentication-Results: mx.google.com; spf=neutral (google.com: 2001:8b0:1d0::1 is neither permitted nor denied by best guess record for domain of pm215@archaic.org.uk) smtp.mail=pm215@archaic.org.uk Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1U6M7a-0003S5-Ci; Fri, 15 Feb 2013 14:18:38 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 1/2] target-arm: Factor out handling of SRS instruction Date: Fri, 15 Feb 2013 14:18:37 +0000 Message-Id: <1360937918-13244-2-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1360937918-13244-1-git-send-email-peter.maydell@linaro.org> References: <1360937918-13244-1-git-send-email-peter.maydell@linaro.org> X-Gm-Message-State: ALoCoQmXrjO5R/yPdK0R8MyDVKzvzKbSBacXE8I3rlqClt7hPDpNMi/5Mia8pJkG9u7BDBwJSBto Factor out the handling of the SRS instruction rather than duplicating it between the Thumb and ARM decoders. This in passing fixes two bugs in the Thumb decoder's SRS handling which didn't exist in the ARM decoder: * (LP:1079080) storing CPSR rather than SPSR (fixed in the ARM decoder in commit c67b6b71 in 2009) * failing to free the 'addr' TCG temp in the writeback case Signed-off-by: Peter Maydell --- target-arm/translate.c | 136 ++++++++++++++++++++++++------------------------ 1 file changed, 69 insertions(+), 67 deletions(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index a8893f7..62a4c15 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -6561,6 +6561,70 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, } #endif +/* gen_srs: + * @env: CPUARMState + * @s: DisasContext + * @mode: mode field from insn (which stack to store to) + * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn + * @writeback: true if writeback bit set + * + * Generate code for the SRS (Store Return State) insn. + */ +static void gen_srs(DisasContext *s, + uint32_t mode, uint32_t amode, bool writeback) +{ + int32_t offset; + TCGv_i32 addr = tcg_temp_new_i32(); + TCGv_i32 tmp = tcg_const_i32(mode); + gen_helper_get_r13_banked(addr, cpu_env, tmp); + tcg_temp_free_i32(tmp); + switch (amode) { + case 0: /* DA */ + offset = -4; + break; + case 1: /* IA */ + offset = 0; + break; + case 2: /* DB */ + offset = -8; + break; + case 3: /* IB */ + offset = 4; + break; + default: + abort(); + } + tcg_gen_addi_i32(addr, addr, offset); + tmp = load_reg(s, 14); + gen_st32(tmp, addr, 0); + tmp = load_cpu_field(spsr); + tcg_gen_addi_i32(addr, addr, 4); + gen_st32(tmp, addr, 0); + if (writeback) { + switch (amode) { + case 0: + offset = -8; + break; + case 1: + offset = 4; + break; + case 2: + offset = -4; + break; + case 3: + offset = 0; + break; + default: + abort(); + } + tcg_gen_addi_i32(addr, addr, offset); + tmp = tcg_const_i32(mode); + gen_helper_set_r13_banked(cpu_env, tmp, addr); + tcg_temp_free_i32(tmp); + } + tcg_temp_free_i32(addr); +} + static void disas_arm_insn(CPUARMState * env, DisasContext *s) { unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh; @@ -6653,49 +6717,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s) } } else if ((insn & 0x0e5fffe0) == 0x084d0500) { /* srs */ - int32_t offset; - if (IS_USER(s)) + if (IS_USER(s)) { goto illegal_op; - ARCH(6); - op1 = (insn & 0x1f); - addr = tcg_temp_new_i32(); - tmp = tcg_const_i32(op1); - gen_helper_get_r13_banked(addr, cpu_env, tmp); - tcg_temp_free_i32(tmp); - i = (insn >> 23) & 3; - switch (i) { - case 0: offset = -4; break; /* DA */ - case 1: offset = 0; break; /* IA */ - case 2: offset = -8; break; /* DB */ - case 3: offset = 4; break; /* IB */ - default: abort(); } - if (offset) - tcg_gen_addi_i32(addr, addr, offset); - tmp = load_reg(s, 14); - gen_st32(tmp, addr, 0); - tmp = load_cpu_field(spsr); - tcg_gen_addi_i32(addr, addr, 4); - gen_st32(tmp, addr, 0); - if (insn & (1 << 21)) { - /* Base writeback. */ - switch (i) { - case 0: offset = -8; break; - case 1: offset = 4; break; - case 2: offset = -4; break; - case 3: offset = 0; break; - default: abort(); - } - if (offset) - tcg_gen_addi_i32(addr, addr, offset); - tmp = tcg_const_i32(op1); - gen_helper_set_r13_banked(cpu_env, tmp, addr); - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(addr); - } else { - tcg_temp_free_i32(addr); - } - return; + ARCH(6); + gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21)); } else if ((insn & 0x0e50ffe0) == 0x08100a00) { /* rfe */ int32_t offset; @@ -8135,32 +8161,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw gen_rfe(s, tmp, tmp2); } else { /* srs */ - op = (insn & 0x1f); - addr = tcg_temp_new_i32(); - tmp = tcg_const_i32(op); - gen_helper_get_r13_banked(addr, cpu_env, tmp); - tcg_temp_free_i32(tmp); - if ((insn & (1 << 24)) == 0) { - tcg_gen_addi_i32(addr, addr, -8); - } - tmp = load_reg(s, 14); - gen_st32(tmp, addr, 0); - tcg_gen_addi_i32(addr, addr, 4); - tmp = tcg_temp_new_i32(); - gen_helper_cpsr_read(tmp, cpu_env); - gen_st32(tmp, addr, 0); - if (insn & (1 << 21)) { - if ((insn & (1 << 24)) == 0) { - tcg_gen_addi_i32(addr, addr, -4); - } else { - tcg_gen_addi_i32(addr, addr, 4); - } - tmp = tcg_const_i32(op); - gen_helper_set_r13_banked(cpu_env, tmp, addr); - tcg_temp_free_i32(tmp); - } else { - tcg_temp_free_i32(addr); - } + gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2, + insn & (1 << 21)); } } else { int i, loaded_base = 0;