diff options
| author | 2016-07-22 09:46:43 +0200 | |
|---|---|---|
| committer | 2016-07-26 12:58:40 +0200 | |
| commit | cdd822f4dc8414ac78374d06fa1a0c6be2507bc4 (patch) | |
| tree | 60ec68f992a1a7c3382f0d4e611faa76cada5665 /compiler/optimizing | |
| parent | e92730cbc5e05b8057cf103af876927c9c361b73 (diff) | |
MIPS32: Block callee save fp registers in debuggable
This fixes tests 454-get-vreg and 457-regs in debuggable.
Additional changes in LocationsBuilderMIPS::HandleFieldGet/Set
to prevent situations when running out of available fp registers.
Test: mma -j2 ART_TEST_RUN_TEST_DEBUGGABLE=true test-art-target-run-test
Change-Id: Iaad6a6e414ff747b39209780c21aeddc225a04c1
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 63 |
1 files changed, 52 insertions, 11 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 39248aa430..91b431b0b5 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -1067,6 +1067,15 @@ void CodeGeneratorMIPS::SetupBlockedRegisters() const { blocked_fpu_registers_[i] = true; } + if (GetGraph()->IsDebuggable()) { + // Stubs do not save callee-save floating point registers. If the graph + // is debuggable, we need to deal with these registers differently. For + // now, just block them. + for (size_t i = 0; i < arraysize(kFpuCalleeSaves); ++i) { + blocked_fpu_registers_[kFpuCalleeSaves[i]] = true; + } + } + UpdateBlockedPairRegisters(); } @@ -3440,7 +3449,8 @@ void LocationsBuilderMIPS::HandleFieldGet(HInstruction* instruction, const Field if (field_type == Primitive::kPrimLong) { locations->SetOut(calling_convention.GetReturnLocation(Primitive::kPrimLong)); } else { - locations->SetOut(Location::RequiresFpuRegister()); + // Use Location::Any() to prevent situations when running out of available fp registers. + locations->SetOut(Location::Any()); // Need some temp core regs since FP results are returned in core registers Location reg = calling_convention.GetReturnLocation(Primitive::kPrimLong); locations->AddTemp(Location::RegisterLocation(reg.AsRegisterPairLow<Register>())); @@ -3505,11 +3515,23 @@ void InstructionCodeGeneratorMIPS::HandleFieldGet(HInstruction* instruction, IsDirectEntrypoint(kQuickA64Load)); CheckEntrypointTypes<kQuickA64Load, int64_t, volatile const int64_t*>(); if (type == Primitive::kPrimDouble) { - // Need to move to FP regs since FP results are returned in core registers. - __ Mtc1(locations->GetTemp(1).AsRegister<Register>(), - locations->Out().AsFpuRegister<FRegister>()); - __ MoveToFpuHigh(locations->GetTemp(2).AsRegister<Register>(), - locations->Out().AsFpuRegister<FRegister>()); + // FP results are returned in core registers. Need to move them. + Location out = locations->Out(); + if (out.IsFpuRegister()) { + __ Mtc1(locations->GetTemp(1).AsRegister<Register>(), out.AsFpuRegister<FRegister>()); + __ MoveToFpuHigh(locations->GetTemp(2).AsRegister<Register>(), + out.AsFpuRegister<FRegister>()); + } else { + DCHECK(out.IsDoubleStackSlot()); + __ StoreToOffset(kStoreWord, + locations->GetTemp(1).AsRegister<Register>(), + SP, + out.GetStackIndex()); + __ StoreToOffset(kStoreWord, + locations->GetTemp(2).AsRegister<Register>(), + SP, + out.GetStackIndex() + 4); + } } } else { if (!Primitive::IsFloatingPointType(type)) { @@ -3568,7 +3590,8 @@ void LocationsBuilderMIPS::HandleFieldSet(HInstruction* instruction, const Field locations->SetInAt(1, Location::RegisterPairLocation( calling_convention.GetRegisterAt(2), calling_convention.GetRegisterAt(3))); } else { - locations->SetInAt(1, Location::RequiresFpuRegister()); + // Use Location::Any() to prevent situations when running out of available fp registers. + locations->SetInAt(1, Location::Any()); // Pass FP parameters in core registers. locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(2))); locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(3))); @@ -3627,10 +3650,28 @@ void InstructionCodeGeneratorMIPS::HandleFieldSet(HInstruction* instruction, codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); if (type == Primitive::kPrimDouble) { // Pass FP parameters in core registers. - __ Mfc1(locations->GetTemp(1).AsRegister<Register>(), - locations->InAt(1).AsFpuRegister<FRegister>()); - __ MoveFromFpuHigh(locations->GetTemp(2).AsRegister<Register>(), - locations->InAt(1).AsFpuRegister<FRegister>()); + Location in = locations->InAt(1); + if (in.IsFpuRegister()) { + __ Mfc1(locations->GetTemp(1).AsRegister<Register>(), in.AsFpuRegister<FRegister>()); + __ MoveFromFpuHigh(locations->GetTemp(2).AsRegister<Register>(), + in.AsFpuRegister<FRegister>()); + } else if (in.IsDoubleStackSlot()) { + __ LoadFromOffset(kLoadWord, + locations->GetTemp(1).AsRegister<Register>(), + SP, + in.GetStackIndex()); + __ LoadFromOffset(kLoadWord, + locations->GetTemp(2).AsRegister<Register>(), + SP, + in.GetStackIndex() + 4); + } else { + DCHECK(in.IsConstant()); + DCHECK(in.GetConstant()->IsDoubleConstant()); + int64_t value = bit_cast<int64_t, double>(in.GetConstant()->AsDoubleConstant()->GetValue()); + __ LoadConst64(locations->GetTemp(2).AsRegister<Register>(), + locations->GetTemp(1).AsRegister<Register>(), + value); + } } codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pA64Store), instruction, |