summaryrefslogtreecommitdiff
path: root/target-mips
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-05-09 09:33:33 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-05-09 09:33:33 +0000
commita6763a588127d8b0f7e64312e9153c6c6bae822f (patch)
treebca17b21adf269ef2552351f9b4af2f3dd7cd6b6 /target-mips
parent204a1b8d5ec12af7f0e4757f51802672fc2e6681 (diff)
downloadqemu-a6763a588127d8b0f7e64312e9153c6c6bae822f.tar.gz
Fix MIPS64 address computation specialcase, by Aurelien Jarno.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2793 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-mips')
-rw-r--r--target-mips/op.c16
-rw-r--r--target-mips/translate.c4
2 files changed, 18 insertions, 2 deletions
diff --git a/target-mips/op.c b/target-mips/op.c
index aedd7bd84e..9b0cee0e35 100644
--- a/target-mips/op.c
+++ b/target-mips/op.c
@@ -289,6 +289,22 @@ void op_store_LO (void)
#undef MEMSUFFIX
#endif
+/* Addresses computation */
+void op_addr_add (void)
+{
+/* For compatibility with 32-bit code, data reference in user mode
+ with Status_UX = 0 should be casted to 32-bit and sign extended.
+ See the MIPS64 PRA manual, section 4.10. */
+#ifdef TARGET_MIPS64
+ if ((env->CP0_Status & (1 << CP0St_UM)) &&
+ !(env->CP0_Status & (1 << CP0St_UX)))
+ T0 = (int64_t)(int32_t)(T0 + T1);
+ else
+#endif
+ T0 += T1;
+ RETURN();
+}
+
/* Arithmetic */
void op_add (void)
{
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 6098b2a10b..debe17d7c6 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -719,7 +719,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
} else {
gen_op_load_gpr_T0(base);
gen_op_set_T1(offset);
- gen_op_add();
+ gen_op_addr_add();
}
/* Don't do NOP if destination is zero: we must perform the actual
* memory access
@@ -868,7 +868,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
} else {
gen_op_load_gpr_T0(base);
gen_op_set_T1(offset);
- gen_op_add();
+ gen_op_addr_add();
}
/* Don't do NOP if destination is zero: we must perform the actual
* memory access