diff options
author | Alexey Frunze <Alexey.Frunze@imgtec.com> | 2016-08-30 21:40:46 -0700 |
---|---|---|
committer | Alexey Frunze <Alexey.Frunze@imgtec.com> | 2016-09-01 16:36:54 -0700 |
commit | 58320ce35715f2814700707a9d35ad5055fff9ce (patch) | |
tree | f691e4d824213ecadb0bf4f858ad63b5a2584467 /compiler/optimizing/code_generator_mips.cc | |
parent | 370e6e412bb8361fec0f0788c396621bccfb6e2a (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.cc | 17 |
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); } |