summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_mips.cc
diff options
context:
space:
mode:
authorAlexey Frunze <Alexey.Frunze@imgtec.com>2016-08-30 21:40:46 -0700
committerAlexey Frunze <Alexey.Frunze@imgtec.com>2016-09-01 16:36:54 -0700
commit58320ce35715f2814700707a9d35ad5055fff9ce (patch)
treef691e4d824213ecadb0bf4f858ad63b5a2584467 /compiler/optimizing/code_generator_mips.cc
parent370e6e412bb8361fec0f0788c396621bccfb6e2a (diff)
MIPS32: Ensure preservation of RA in leaf methods if it's clobbered
Test: booted MIPS32 in QEMU Test: test-art-host-gtest Test: test-art-target-gtest-codegen_test in QEMU Test: test-art-target-run-test-optimizing on CI20 Change-Id: Ia3da5902d967cd7af313f03ebf414320b0063619
Diffstat (limited to 'compiler/optimizing/code_generator_mips.cc')
-rw-r--r--compiler/optimizing/code_generator_mips.cc17
1 files changed, 11 insertions, 6 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index e0de03bf8f..1e6251351c 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -697,16 +697,17 @@ void CodeGeneratorMIPS::ComputeSpillMask() {
if ((fpu_spill_mask_ != 0) && (POPCOUNT(core_spill_mask_) % 2 != 0)) {
core_spill_mask_ |= (1 << ZERO);
}
+}
+
+bool CodeGeneratorMIPS::HasAllocatedCalleeSaveRegisters() const {
// If RA is clobbered by PC-relative operations on R2 and it's the only spilled register
- // (this can happen in leaf methods), artificially spill the ZERO register in order to
- // force explicit saving and restoring of RA. RA isn't saved/restored when it's the only
- // spilled register.
+ // (this can happen in leaf methods), force CodeGenerator::InitializeCodeGeneration()
+ // into the path that creates a stack frame so that RA can be explicitly saved and restored.
+ // RA can't otherwise be saved/restored when it's the only spilled register.
// TODO: Can this be improved? It causes creation of a stack frame (while RA might be
// saved in an unused temporary register) and saving of RA and the current method pointer
// in the frame.
- if (clobbered_ra_ && core_spill_mask_ == (1u << RA) && fpu_spill_mask_ == 0) {
- core_spill_mask_ |= (1 << ZERO);
- }
+ return CodeGenerator::HasAllocatedCalleeSaveRegisters() || clobbered_ra_;
}
static dwarf::Reg DWARFReg(Register reg) {
@@ -729,6 +730,9 @@ void CodeGeneratorMIPS::GenerateFrameEntry() {
}
if (HasEmptyFrame()) {
+ CHECK_EQ(fpu_spill_mask_, 0u);
+ CHECK_EQ(core_spill_mask_, 1u << RA);
+ CHECK(!clobbered_ra_);
return;
}
@@ -762,6 +766,7 @@ void CodeGeneratorMIPS::GenerateFrameEntry() {
}
// Store the current method pointer.
+ // TODO: can we not do this if RequiresCurrentMethod() returns false?
__ StoreToOffset(kStoreWord, kMethodRegisterArgument, SP, kCurrentMethodStackOffset);
}