Revert "Revert "[MIPS] Use hard float calling convention for managed code""
This reverts commit 7fee84c087e0f903e7d43bef180df047db1c8051.
Fixed issue with temporary registers on Mips32r6.
Change-Id: I93018927e6a6036cff2d55e6cda66d3212a4316b
diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h
index 43fbcbd..2173253 100644
--- a/compiler/dex/quick/mips/codegen_mips.h
+++ b/compiler/dex/quick/mips/codegen_mips.h
@@ -29,15 +29,18 @@
protected:
class InToRegStorageMipsMapper : public InToRegStorageMapper {
public:
- explicit InToRegStorageMipsMapper(Mir2Lir* m2l) : m2l_(m2l), cur_core_reg_(0) {}
+ explicit InToRegStorageMipsMapper(Mir2Lir* m2l) : m2l_(m2l), cur_core_reg_(0), cur_fpu_reg_(0)
+ {}
virtual RegStorage GetNextReg(ShortyArg arg);
virtual void Reset() OVERRIDE {
cur_core_reg_ = 0;
+ cur_fpu_reg_ = 0;
}
protected:
Mir2Lir* m2l_;
private:
size_t cur_core_reg_;
+ size_t cur_fpu_reg_;
};
class InToRegStorageMips64Mapper : public InToRegStorageMapper {
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc
index ec4bad7..09d37f8 100644
--- a/compiler/dex/quick/mips/target_mips.cc
+++ b/compiler/dex/quick/mips/target_mips.cc
@@ -195,7 +195,7 @@
// Return a target-dependent special register.
RegStorage MipsMir2Lir::TargetReg(SpecialTargetRegister reg, WideKind wide_kind) {
if (!cu_->target64 && wide_kind == kWide) {
- DCHECK((kArg0 <= reg && reg < kArg7) || (kFArg0 <= reg && reg < kFArg15) || (kRet0 == reg));
+ DCHECK((kArg0 <= reg && reg < kArg7) || (kFArg0 == reg) || (kFArg2 == reg) || (kRet0 == reg));
RegStorage ret_reg = RegStorage::MakeRegPair(TargetReg(reg),
TargetReg(static_cast<SpecialTargetRegister>(reg + 1)));
if (!fpuIs32Bit_ && ret_reg.IsFloat()) {
@@ -250,14 +250,27 @@
RegStorage MipsMir2Lir::InToRegStorageMipsMapper::GetNextReg(ShortyArg arg) {
const SpecialTargetRegister coreArgMappingToPhysicalReg[] = {kArg1, kArg2, kArg3};
const size_t coreArgMappingToPhysicalRegSize = arraysize(coreArgMappingToPhysicalReg);
+ const SpecialTargetRegister fpuArgMappingToPhysicalReg[] = {kFArg0, kFArg2};
+ const size_t fpuArgMappingToPhysicalRegSize = arraysize(fpuArgMappingToPhysicalReg);
RegStorage result = RegStorage::InvalidReg();
- if (cur_core_reg_ < coreArgMappingToPhysicalRegSize) {
- result = m2l_->TargetReg(coreArgMappingToPhysicalReg[cur_core_reg_++],
- arg.IsRef() ? kRef : kNotWide);
- if (arg.IsWide() && cur_core_reg_ < coreArgMappingToPhysicalRegSize) {
- result = RegStorage::MakeRegPair(
- result, m2l_->TargetReg(coreArgMappingToPhysicalReg[cur_core_reg_++], kNotWide));
+ if (arg.IsFP()) {
+ if (cur_fpu_reg_ < fpuArgMappingToPhysicalRegSize) {
+ result = m2l_->TargetReg(fpuArgMappingToPhysicalReg[cur_fpu_reg_++],
+ arg.IsWide() ? kWide : kNotWide);
+ }
+ } else {
+ if (cur_core_reg_ < coreArgMappingToPhysicalRegSize) {
+ if (arg.IsWide() && cur_core_reg_ == 0) {
+ // Don't use a1-a2 as a register pair, move to a2-a3 instead.
+ cur_core_reg_++;
+ }
+ result = m2l_->TargetReg(coreArgMappingToPhysicalReg[cur_core_reg_++],
+ arg.IsRef() ? kRef : kNotWide);
+ if (arg.IsWide() && cur_core_reg_ < coreArgMappingToPhysicalRegSize) {
+ result = RegStorage::MakeRegPair(
+ result, m2l_->TargetReg(coreArgMappingToPhysicalReg[cur_core_reg_++], kNotWide));
+ }
}
}
return result;
@@ -654,6 +667,20 @@
LockTemp(TargetReg(kArg5));
LockTemp(TargetReg(kArg6));
LockTemp(TargetReg(kArg7));
+ } else {
+ if (fpuIs32Bit_) {
+ LockTemp(TargetReg(kFArg0));
+ LockTemp(TargetReg(kFArg1));
+ LockTemp(TargetReg(kFArg2));
+ LockTemp(TargetReg(kFArg3));
+ LockTemp(rs_rD6_fr0);
+ LockTemp(rs_rD7_fr0);
+ } else {
+ LockTemp(TargetReg(kFArg0));
+ LockTemp(TargetReg(kFArg2));
+ LockTemp(rs_rD6_fr1);
+ LockTemp(rs_rD7_fr1);
+ }
}
}
@@ -668,6 +695,20 @@
FreeTemp(TargetReg(kArg5));
FreeTemp(TargetReg(kArg6));
FreeTemp(TargetReg(kArg7));
+ } else {
+ if (fpuIs32Bit_) {
+ FreeTemp(TargetReg(kFArg0));
+ FreeTemp(TargetReg(kFArg1));
+ FreeTemp(TargetReg(kFArg2));
+ FreeTemp(TargetReg(kFArg3));
+ FreeTemp(rs_rD6_fr0);
+ FreeTemp(rs_rD7_fr0);
+ } else {
+ FreeTemp(TargetReg(kFArg0));
+ FreeTemp(TargetReg(kFArg2));
+ FreeTemp(rs_rD6_fr1);
+ FreeTemp(rs_rD7_fr1);
+ }
}
FreeTemp(TargetReg(kHiddenArg));
}