From: Peter Maydell <peter.maydell@linaro.org>
To: Aurelien Jarno <aurelien@aurel32.net>, Blue Swirl <blauwirbel@gmail.com>
Cc: Anthony Liguori <aliguori@us.ibm.com>,
qemu-devel@nongnu.org, Paul Brook <paul@codesourcery.com>
Subject: [Qemu-devel] [PATCH 01/13] target-arm: Factor out handling of SRS instruction
Date: Tue, 5 Mar 2013 01:11:59 +0000 [thread overview]
Message-ID: <1362445931-4383-2-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1362445931-4383-1-git-send-email-peter.maydell@linaro.org>
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
Reported-by: Cesson Vincent <vcesson@stmi.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
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 db63c6e..e16c113 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6601,6 +6601,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;
@@ -6693,49 +6757,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;
@@ -8180,32 +8206,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;
--
1.7.9.5
next prev parent reply other threads:[~2013-03-05 1:49 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-05 1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
2013-03-05 1:11 ` Peter Maydell [this message]
2013-03-05 1:12 ` [Qemu-devel] [PATCH 02/13] target-arm: Don't decode RFE or SRS on M profile cores Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 03/13] oslib-posix: Align to permit transparent hugepages on ARM Linux Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 04/13] linux-headers: resync from mainline to add ARM KVM headers Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 05/13] target-arm: Drop CPUARMState* argument from bank_number() Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 06/13] ARM: KVM: Add support for KVM on ARM architecture Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 07/13] ARM KVM: save and load VFP registers from kernel Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 08/13] hw/arm_gic: Add presave/postload hooks Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 09/13] hw/arm_gic: Convert ARM GIC classes to use init/realize Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 10/13] target-arm: Use MemoryListener to identify GIC base address for KVM Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 11/13] hw/kvm/arm_gic: Implement support for KVM in-kernel ARM GIC Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 12/13] configure: Enable KVM on ARM Peter Maydell
2013-03-05 1:12 ` [Qemu-devel] [PATCH 13/13] MAINTAINERS: add entry for ARM KVM guest cores Peter Maydell
2013-03-05 14:19 ` [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Aurelien Jarno
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1362445931-4383-2-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=aliguori@us.ibm.com \
--cc=aurelien@aurel32.net \
--cc=blauwirbel@gmail.com \
--cc=paul@codesourcery.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).