aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2013-05-20 18:36:13 +0100
committerPeter Maydell <peter.maydell@linaro.org>2013-05-20 18:36:13 +0100
commit90d0379378fb6fa14425e4e80ba3171942bae8c9 (patch)
treeb8950b800f7e24ce3c2aaddbdd3e9785d6002198
parent0a2e5cc8ee93e175ce8549e8d2058424d108fb1b (diff)
downloadqemu-arm-90d0379378fb6fa14425e4e80ba3171942bae8c9.tar.gz
target-arm: Explicitly convert TCGv to/from TCGv_i32 for qemu_ld/st
The tcg_gen_qemu_{ld,st}* functions take a TCGv (whose type may change depending on TARGET_LONG_BITS) but the 32 bit ARM code generation always wants to work with 32 bit values. Rather than relying on TCGv and TCGv_i32 being the same type, convert explicitly if necessary. This will allow the code to continue to work when compiled into an AArch64 QEMU. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--target-arm/translate.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 75972cfb24..1dca0e86e5 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -841,12 +841,35 @@ static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
}
}
+/* TODO:
+ * consider macros!
+ * 64 bit will be different
+ * check if 32-to-64 addresses should be sign or zero extended
+ * or if we don't care...
+ */
+#if TARGET_LONG_BITS == 32
static inline TCGv_i32 gen_ld8s(TCGv_i32 addr, int index)
{
- TCGv_i32 tmp = tcg_temp_new_i32();
- tcg_gen_qemu_ld8s(tmp, addr, index);
- return tmp;
+ TCGv_i32 val = tcg_temp_new_i32();
+ tcg_gen_qemu_ld8s(val, addr, index);
+ return val;
}
+#else
+static inline TCGv_i32 gen_ld8s(TCGv_i32 addr32, int index)
+{
+ TCGv addr = tcg_temp_new();
+ TCGv val = tcg_temp_new();
+ TCGv_i32 val32;
+ tcg_gen_extu_i32_i64(addr, addr32);
+ tcg_gen_qemu_ld8s(val, addr, index);
+ tcg_temp_free(addr);
+ val32 = tcg_temp_new_i32();
+ tcg_gen_trunc_i64_i32(val32, val);
+ tcg_temp_free(val);
+ return val32;
+}
+#endif
+
static inline TCGv_i32 gen_ld8u(TCGv_i32 addr, int index)
{
TCGv_i32 tmp = tcg_temp_new_i32();
@@ -877,11 +900,27 @@ static inline TCGv_i64 gen_ld64(TCGv_i32 addr, int index)
tcg_gen_qemu_ld64(tmp, addr, index);
return tmp;
}
+
+#if TARGET_LONG_BITS == 32
static inline void gen_st8(TCGv_i32 val, TCGv_i32 addr, int index)
{
tcg_gen_qemu_st8(val, addr, index);
tcg_temp_free_i32(val);
}
+#else
+static inline void gen_st8(TCGv_i32 val32, TCGv_i32 addr32, int index)
+{
+ TCGv addr = tcg_temp_new();
+ TCGv val = tcg_temp_new();
+ tcg_gen_extu_i32_i64(addr, addr32);
+ tcg_gen_extu_i32_i64(val, val32);
+ tcg_temp_free_i32(val32);
+ tcg_gen_qemu_st8(val, addr, index);
+ tcg_temp_free(val);
+ tcg_temp_free(addr);
+}
+#endif
+
static inline void gen_st16(TCGv_i32 val, TCGv_i32 addr, int index)
{
tcg_gen_qemu_st16(val, addr, index);