summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
author buzbee <buzbee@google.com> 2014-03-19 12:28:16 -0700
committer buzbee <buzbee@google.com> 2014-03-19 15:21:25 -0700
commit40bbb39b85c063cd6a9f4ab00ff70372370e08cf (patch)
tree1fbcbe2c7f257729c5280dee511c02bed471a9af /compiler
parent0d9c02e661813abdf18b4e7544e204d2da719d20 (diff)
Fix Quick compiler "out of registers"
There are a few places in the Arm backend that expect to be able to survive on a single temp register - in particular entry code generation and argument passing. However, in the case of a very large frame and floating point ld/st, the existing code could end up using 2 temps. In short, if there is a displacement overflow we try to use indexed load/store instructions (slightly more efficient). However, there are none for floating point - so we ended up burning yet another register to construct a direct pointer. This CL detects this case and doesn't try to use the indexed load/store mechanism for floats. Fix for https://code.google.com/p/android/issues/detail?id=67349 Change-Id: I1ea596ea660e4add89fd4fddb8cbf99a54fbd343
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/quick/arm/utility_arm.cc16
1 files changed, 14 insertions, 2 deletions
diff --git a/compiler/dex/quick/arm/utility_arm.cc b/compiler/dex/quick/arm/utility_arm.cc
index 882a3bb941..1a7f2fcb66 100644
--- a/compiler/dex/quick/arm/utility_arm.cc
+++ b/compiler/dex/quick/arm/utility_arm.cc
@@ -923,7 +923,13 @@ LIR* ArmMir2Lir::LoadBaseDispBody(int rBase, int displacement, int r_dest,
} else {
int reg_offset = AllocTemp();
LoadConstant(reg_offset, encoded_disp);
- load = LoadBaseIndexed(rBase, reg_offset, r_dest, 0, size);
+ if (ARM_FPREG(r_dest)) {
+ // No index ops - must use a long sequence. Turn the offset into a direct pointer.
+ OpRegReg(kOpAdd, reg_offset, rBase);
+ load = LoadBaseDispBody(reg_offset, 0, r_dest, r_dest_hi, size, s_reg);
+ } else {
+ load = LoadBaseIndexed(rBase, reg_offset, r_dest, 0, size);
+ }
FreeTemp(reg_offset);
}
}
@@ -1037,7 +1043,13 @@ LIR* ArmMir2Lir::StoreBaseDispBody(int rBase, int displacement,
} else {
int r_scratch = AllocTemp();
LoadConstant(r_scratch, encoded_disp);
- store = StoreBaseIndexed(rBase, r_scratch, r_src, 0, size);
+ if (ARM_FPREG(r_src)) {
+ // No index ops - must use a long sequence. Turn the offset into a direct pointer.
+ OpRegReg(kOpAdd, r_scratch, rBase);
+ store = StoreBaseDispBody(r_scratch, 0, r_src, r_src_hi, size);
+ } else {
+ store = StoreBaseIndexed(rBase, r_scratch, r_src, 0, size);
+ }
FreeTemp(r_scratch);
}
}