aboutsummaryrefslogtreecommitdiff
path: root/target-arm/translate.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-10-17 19:41:23 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-10-17 19:41:23 +0100
commit2d02ac10b6644d71c88cc7943e74d7ad6674fff1 (patch)
tree28f11b0787b3fd3fb4b85881feead80f9ad76c81 /target-arm/translate.c
parent0975b8b823a888d474fa33821dfe84e6904db197 (diff)
parent041ac05672993ff33a15f8017c0f729ca6dfad73 (diff)
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20161017' into staging
target-arm: * target-arm: kvm: use AddressSpace-specific listener * aspeed: add SMC controllers * hw/arm/boot: allow using a command line specified dtb without a kernel * hw/dma/pl080: Fix bad bit mask * hw/intc/arm_gic_kvm: Fix build on aarch64 with some compilers * hw/arm/virt: fix ACPI tables for ITS * tests: add a m25p80 test * tests: cleanup ptimer-test * pxa2xx: Auto-assign name for i2c bus in i2c_init_bus * target-arm: handle tagged addresses in A64 code * target-arm: Fix masking of PC lower bits when doing exception returns * target-arm: Implement dummy MDCCINT_EL1 * target-arm: Add trace events for the generic timers * hw/intc/arm_gicv3: Fix ICC register tracepoints * hw/char/pl011: Add trace events # gpg: Signature made Mon 17 Oct 2016 19:39:42 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-20161017: (25 commits) hw/char/pl011: Add trace events hw/intc/arm_gicv3: Fix ICC register tracepoints target-arm: Add trace events for the generic timers target-arm: Implement dummy MDCCINT_EL1 Fix masking of PC lower bits when doing exception returns target-arm: Comments added to identify cases in a switch target-arm: Code changes to implement overwrite of tag field on PC load target-arm: Infrastucture changes to enable handling of tagged address loading into PC pxa2xx: Auto-assign name for i2c bus in i2c_init_bus. tests: cleanup ptimer-test tests: add a m25p80 test hw/arm/virt: no ITS on older machine types hw/arm/virt-acpi-build: fix MADT generation hw/intc/arm_gic_kvm: Fix build on aarch64 hw/dma/pl080: Fix bad bit mask (PL080_CONF_M1 | PL080_CONF_M1) hw/arm/boot: allow using a command line specified dtb without a kernel aspeed: add support for the SMC segment registers aspeed: create mapping regions for the maximum number of slaves aspeed: add support for the AST2500 SoC SMC controllers aspeed: extend the number of host SPI controllers ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm/translate.c')
-rw-r--r--target-arm/translate.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 8df24bf35a..164b52a0d0 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4363,26 +4363,35 @@ static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
s->is_jmp = DISAS_UPDATE;
}
-/* Generate an old-style exception return. Marks pc as dead. */
-static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
+/* Store value to PC as for an exception return (ie don't
+ * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
+ * will do the masking based on the new value of the Thumb bit.
+ */
+static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
{
- TCGv_i32 tmp;
- store_reg(s, 15, pc);
- tmp = load_cpu_field(spsr);
- gen_helper_cpsr_write_eret(cpu_env, tmp);
- tcg_temp_free_i32(tmp);
- s->is_jmp = DISAS_JUMP;
+ tcg_gen_mov_i32(cpu_R[15], pc);
+ tcg_temp_free_i32(pc);
}
/* Generate a v6 exception return. Marks both values as dead. */
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
{
+ store_pc_exc_ret(s, pc);
+ /* The cpsr_write_eret helper will mask the low bits of PC
+ * appropriately depending on the new Thumb bit, so it must
+ * be called after storing the new PC.
+ */
gen_helper_cpsr_write_eret(cpu_env, cpsr);
tcg_temp_free_i32(cpsr);
- store_reg(s, 15, pc);
s->is_jmp = DISAS_JUMP;
}
+/* Generate an old-style exception return. Marks pc as dead. */
+static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
+{
+ gen_rfe(s, pc, load_cpu_field(spsr));
+}
+
static void gen_nop_hint(DisasContext *s, int val)
{
switch (val) {
@@ -9366,6 +9375,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
} else if (i == rn) {
loaded_var = tmp;
loaded_base = 1;
+ } else if (rn == 15 && exc_return) {
+ store_pc_exc_ret(s, tmp);
} else {
store_reg_from_load(s, i, tmp);
}