summaryrefslogtreecommitdiffstats
path: root/target/arm/translate-a64.c
diff options
context:
space:
mode:
authorPeter Maydell2017-09-04 18:21:24 +0200
committerPeter Maydell2017-09-04 18:21:24 +0200
commit2b483739791b33c46e6084b51edcf62107058ae1 (patch)
treefab8d4164ff9c0a73fdaad41ee06815d6163e504 /target/arm/translate-a64.c
parentMerge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2017-09-01-v3' in... (diff)
parentarm_gicv3_kvm: Fix compile warning (diff)
downloadqemu-2b483739791b33c46e6084b51edcf62107058ae1.tar.gz
qemu-2b483739791b33c46e6084b51edcf62107058ae1.tar.xz
qemu-2b483739791b33c46e6084b51edcf62107058ae1.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20170904-2' into staging
target-arm: * collection of M profile cleanups and minor bugfixes * loader: handle ELF files with overlapping zero-init data * virt: allow PMU instantiation with userspace irqchip * wdt_aspeed: Add support for the reset width register * cpu: Define new cpu_transaction_failed() hook * Mark some SoC devices as not user-creatable * arm: Fix aa64 ldp register writeback * arm_gicv3_kvm: Fix compile warning # gpg: Signature made Mon 04 Sep 2017 17:20:40 BST # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20170904-2: (33 commits) arm_gicv3_kvm: Fix compile warning target/arm: Fix aa64 ldp register writeback hw/arm/digic: Mark device with user_creatable = false hw/arm/aspeed_soc: Mark devices as user_creatable = false target/arm: Allow deliver_fault() caller to specify EA bit target/arm: Factor out fault delivery code cputlb: Support generating CPU exceptions on memory transaction failures cpu: Define new cpu_transaction_failed() hook memory.h: Move MemTxResult type to memattrs.h aspeed_soc: Propagate silicon-rev to watchdog watchdog: wdt_aspeed: Add support for the reset width register target/arm/kvm: pmu: improve error handling hw/arm/virt: allow pmu instantiation with userspace irqchip target/arm/kvm: pmu: split init and set-irq stages hw/arm/virt: add pmu interrupt state hw/arm: use defined type name instead of hard-coded string loader: Ignore zero-sized ELF segments loader: Handle ELF files with overlapping zero-initialized data nvic: Implement "user accesses BusFault" SCS region behaviour armv7m_nvic.h: Move from include/hw/arm to include/hw/intc ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/translate-a64.c')
-rw-r--r--target/arm/translate-a64.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 2200e25be0..cb44632d16 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -2217,29 +2217,34 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
} else {
do_fp_st(s, rt, tcg_addr, size);
}
- } else {
- TCGv_i64 tcg_rt = cpu_reg(s, rt);
- if (is_load) {
- do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false,
- false, 0, false, false);
- } else {
- do_gpr_st(s, tcg_rt, tcg_addr, size,
- false, 0, false, false);
- }
- }
- tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
- if (is_vector) {
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
if (is_load) {
do_fp_ld(s, rt2, tcg_addr, size);
} else {
do_fp_st(s, rt2, tcg_addr, size);
}
} else {
+ TCGv_i64 tcg_rt = cpu_reg(s, rt);
TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
+
if (is_load) {
+ TCGv_i64 tmp = tcg_temp_new_i64();
+
+ /* Do not modify tcg_rt before recognizing any exception
+ * from the second load.
+ */
+ do_gpr_ld(s, tmp, tcg_addr, size, is_signed, false,
+ false, 0, false, false);
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false,
false, 0, false, false);
+
+ tcg_gen_mov_i64(tcg_rt, tmp);
+ tcg_temp_free_i64(tmp);
} else {
+ do_gpr_st(s, tcg_rt, tcg_addr, size,
+ false, 0, false, false);
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
do_gpr_st(s, tcg_rt2, tcg_addr, size,
false, 0, false, false);
}