|
From: <sv...@va...> - 2014-03-09 09:40:38
|
Author: sewardj
Date: Sun Mar 9 09:40:23 2014
New Revision: 2835
Log:
Do early writeback of the base register for the following instruction
forms, to stop Memcheck complaining about writes below the stack
pointer:
str x3, [sp,#-16]!
stp q0, q1, [sp,#-512]!
Modified:
trunk/priv/guest_arm64_toIR.c
Modified: trunk/priv/guest_arm64_toIR.c
==============================================================================
--- trunk/priv/guest_arm64_toIR.c (original)
+++ trunk/priv/guest_arm64_toIR.c Sun Mar 9 09:40:23 2014
@@ -3152,13 +3152,31 @@
vassert(0); /* NOTREACHED */
}
+ /* Normally rN would be updated after the transfer. However, in
+ the special case typifed by
+ str x30, [sp,#-16]!
+ it is necessary to update SP before the transfer, (1)
+ because Memcheck will otherwise complain about a write
+ below the stack pointer, and (2) because the segfault
+ stack extension mechanism will otherwise extend the stack
+ only down to SP before the instruction, which might not be
+ far enough, if the -16 bit takes the actual access
+ address to the next page.
+ */
+ Bool earlyWBack
+ = wBack && simm9 < 0 && szB == 8
+ && how == BITS2(1,1) && nn == 31 && !isLoad && tt != nn;
+
+ if (wBack && earlyWBack)
+ putIReg64orSP(nn, mkexpr(tEA));
+
if (isLoad) {
putIReg64orZR(tt, mkexpr(gen_zwidening_load(szB, tTA)));
} else {
gen_narrowing_store(szB, tTA, getIReg64orZR(tt));
}
- if (wBack)
+ if (wBack && !earlyWBack)
putIReg64orSP(nn, mkexpr(tEA));
const HChar* ld_name[4] = { "ldurb", "ldurh", "ldur", "ldur" };
@@ -3683,6 +3701,24 @@
default: vassert(0);
}
+ /* Normally rN would be updated after the transfer. However, in
+ the special case typifed by
+ stp q0, q1, [sp,#-512]!
+ it is necessary to update SP before the transfer, (1)
+ because Memcheck will otherwise complain about a write
+ below the stack pointer, and (2) because the segfault
+ stack extension mechanism will otherwise extend the stack
+ only down to SP before the instruction, which might not be
+ far enough, if the -512 bit takes the actual access
+ address to the next page.
+ */
+ Bool earlyWBack
+ = wBack && simm7 < 0 && szB == 16
+ && INSN(24,23) == BITS2(1,1) && nn == 31 && !isLD;
+
+ if (wBack && earlyWBack)
+ putIReg64orSP(nn, mkexpr(tEA));
+
if (isLD) {
if (szB < 16) {
putQReg128(tt1, mkV128(0x0000));
@@ -3701,7 +3737,7 @@
getQRegLO(tt2, ty));
}
- if (wBack)
+ if (wBack && !earlyWBack)
putIReg64orSP(nn, mkexpr(tEA));
const HChar* fmt_str = NULL;
|