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
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index e0de03b..1e62513 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -697,16 +697,17 @@
   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 @@
   }
 
   if (HasEmptyFrame()) {
+    CHECK_EQ(fpu_spill_mask_, 0u);
+    CHECK_EQ(core_spill_mask_, 1u << RA);
+    CHECK(!clobbered_ra_);
     return;
   }
 
@@ -762,6 +766,7 @@
   }
 
   // Store the current method pointer.
+  // TODO: can we not do this if RequiresCurrentMethod() returns false?
   __ StoreToOffset(kStoreWord, kMethodRegisterArgument, SP, kCurrentMethodStackOffset);
 }