summaryrefslogtreecommitdiffstats
path: root/compiler/utils/arm/assembler_arm.cc
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2015-01-20 16:06:43 +0100
committerNicolas Geoffray <ngeoffray@google.com>2015-03-03 11:22:00 +0000
commit7cde48c56df5b57aed524cce44c902bc720f2d6c (patch)
treeb9b9e33b29f46bfe0c2da89c7e3e87c8ee419ccc /compiler/utils/arm/assembler_arm.cc
parent4b39eeea67b0fecf21588d7b00e92eb844014c24 (diff)
downloadart-7cde48c56df5b57aed524cce44c902bc720f2d6c.zip
art-7cde48c56df5b57aed524cce44c902bc720f2d6c.tar.gz
art-7cde48c56df5b57aed524cce44c902bc720f2d6c.tar.bz2
Stack support for Optimizing compiler
Allows to read/write DEX registers from physical register or stack location when the method is compiled with the Optimizing compiler. Required fixing arm and arm64 JNI compiler by saving floating point registers. Bug: 18547544 Change-Id: I401579f251d1c0a130f6cf4a93a960cdcd7518f5
Diffstat (limited to 'compiler/utils/arm/assembler_arm.cc')
-rw-r--r--compiler/utils/arm/assembler_arm.cc40
1 files changed, 34 insertions, 6 deletions
diff --git a/compiler/utils/arm/assembler_arm.cc b/compiler/utils/arm/assembler_arm.cc
index a52e6eb..a02191b 100644
--- a/compiler/utils/arm/assembler_arm.cc
+++ b/compiler/utils/arm/assembler_arm.cc
@@ -385,12 +385,24 @@ void ArmAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
// Push callee saves and link register.
RegList push_list = 1 << LR;
size_t pushed_values = 1;
+ int32_t min_s = kNumberOfSRegisters;
+ int32_t max_s = -1;
for (size_t i = 0; i < callee_save_regs.size(); i++) {
- Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister();
- push_list |= 1 << reg;
- pushed_values++;
+ if (callee_save_regs.at(i).AsArm().IsCoreRegister()) {
+ Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister();
+ push_list |= 1 << reg;
+ pushed_values++;
+ } else {
+ CHECK(callee_save_regs.at(i).AsArm().IsSRegister());
+ min_s = std::min(static_cast<int>(callee_save_regs.at(i).AsArm().AsSRegister()), min_s);
+ max_s = std::max(static_cast<int>(callee_save_regs.at(i).AsArm().AsSRegister()), max_s);
+ }
}
PushList(push_list);
+ if (max_s != -1) {
+ pushed_values += 1 + max_s - min_s;
+ vpushs(static_cast<SRegister>(min_s), 1 + max_s - min_s);
+ }
// Increase frame to required size.
CHECK_GT(frame_size, pushed_values * kFramePointerSize); // Must at least have space for Method*.
@@ -427,10 +439,22 @@ void ArmAssembler::RemoveFrame(size_t frame_size,
// Compute callee saves to pop and PC.
RegList pop_list = 1 << PC;
size_t pop_values = 1;
+ int32_t min_s = kNumberOfSRegisters;
+ int32_t max_s = -1;
for (size_t i = 0; i < callee_save_regs.size(); i++) {
- Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister();
- pop_list |= 1 << reg;
- pop_values++;
+ if (callee_save_regs.at(i).AsArm().IsCoreRegister()) {
+ Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister();
+ pop_list |= 1 << reg;
+ pop_values++;
+ } else {
+ CHECK(callee_save_regs.at(i).AsArm().IsSRegister());
+ min_s = std::min(static_cast<int>(callee_save_regs.at(i).AsArm().AsSRegister()), min_s);
+ max_s = std::max(static_cast<int>(callee_save_regs.at(i).AsArm().AsSRegister()), max_s);
+ }
+ }
+
+ if (max_s != -1) {
+ pop_values += 1 + max_s - min_s;
}
// Decrease frame to start of callee saves.
@@ -438,6 +462,10 @@ void ArmAssembler::RemoveFrame(size_t frame_size,
size_t adjust = frame_size - (pop_values * kFramePointerSize);
DecreaseFrameSize(adjust);
+ if (max_s != -1) {
+ vpops(static_cast<SRegister>(min_s), 1 + max_s - min_s);
+ }
+
// Pop callee saves and PC.
PopList(pop_list);
}