aboutsummaryrefslogtreecommitdiff
path: root/vm/compiler/codegen/arm/RallocUtil.c
diff options
context:
space:
mode:
authorBill Buzbee <buzbee@google.com>2010-03-25 10:38:34 -0700
committerBill Buzbee <buzbee@google.com>2010-03-25 10:38:34 -0700
commit80cef8675b2ce54faa31e837b79db9f66d8e652c (patch)
treea5c29bdb4496cc2138b656a2f42b4a7237ff63f7 /vm/compiler/codegen/arm/RallocUtil.c
parentf87ab9616697b8bae08c5e8007cbdd0039a1f8ce (diff)
Jit: Fix for 2542488 JIT codegen bug with overlapping wide operands
Change-Id: I7b922e223fe1f5242d1f3db1fa18f54aaed725af
Diffstat (limited to 'vm/compiler/codegen/arm/RallocUtil.c')
-rw-r--r--vm/compiler/codegen/arm/RallocUtil.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/vm/compiler/codegen/arm/RallocUtil.c b/vm/compiler/codegen/arm/RallocUtil.c
index 6d83e73e0..e357ba672 100644
--- a/vm/compiler/codegen/arm/RallocUtil.c
+++ b/vm/compiler/codegen/arm/RallocUtil.c
@@ -771,18 +771,28 @@ extern RegLocation dvmCompilerUpdateLocWide(CompilationUnit *cUnit,
{
assert(loc.wide);
if (loc.location == kLocDalvikFrame) {
+ // Are the dalvik regs already live in physical registers?
RegisterInfo *infoLo = allocLive(cUnit, loc.sRegLow, kAnyReg);
RegisterInfo *infoHi = allocLive(cUnit,
dvmCompilerSRegHi(loc.sRegLow), kAnyReg);
bool match = true;
match = match && (infoLo != NULL);
match = match && (infoHi != NULL);
+ // Are they both core or both FP?
match = match && (FPREG(infoLo->reg) == FPREG(infoHi->reg));
+ // If a pair of floating point singles, are they properly aligned?
if (match && FPREG(infoLo->reg)) {
match &= ((infoLo->reg & 0x1) == 0);
match &= ((infoHi->reg - infoLo->reg) == 1);
}
+ // If previously used as a pair, it is the same pair?
+ if (match && (infoLo->pair || infoHi->pair)) {
+ match = (infoLo->pair == infoHi->pair);
+ match &= ((infoLo->reg == infoHi->partner) &&
+ (infoHi->reg == infoLo->partner));
+ }
if (match) {
+ // Can reuse - update the register usage info
loc.lowReg = infoLo->reg;
loc.highReg = infoHi->reg;
loc.location = kLocPhysReg;
@@ -790,7 +800,7 @@ extern RegLocation dvmCompilerUpdateLocWide(CompilationUnit *cUnit,
assert(!FPREG(loc.lowReg) || ((loc.lowReg & 0x1) == 0));
return loc;
}
- /* Can't easily reuse - just clobber any overlaps */
+ // Can't easily reuse - clobber any overlaps
if (infoLo) {
dvmCompilerClobber(cUnit, infoLo->reg);
if (infoLo->pair)