diff options
author | Sebastien Hertz <shertz@google.com> | 2015-01-20 16:06:43 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2015-03-03 11:22:00 +0000 |
commit | 7cde48c56df5b57aed524cce44c902bc720f2d6c (patch) | |
tree | b9b9e33b29f46bfe0c2da89c7e3e87c8ee419ccc /compiler/utils/arm/assembler_arm.cc | |
parent | 4b39eeea67b0fecf21588d7b00e92eb844014c24 (diff) | |
download | art-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.cc | 40 |
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); } |