diff options
author | Calin Juravle <calin@google.com> | 2014-11-13 11:16:37 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-11-13 11:16:37 +0000 |
commit | d94a0a1d2868baaab49f4d2835bca086d98cf763 (patch) | |
tree | 48d0701d17445c9ae09ee521c6ac1fb9f614d3b0 /compiler/optimizing/code_generator_arm.cc | |
parent | d77ae8a11e6493ac738864eae073ca4909e4d847 (diff) | |
parent | d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13 (diff) | |
download | art-d94a0a1d2868baaab49f4d2835bca086d98cf763.tar.gz art-d94a0a1d2868baaab49f4d2835bca086d98cf763.tar.bz2 art-d94a0a1d2868baaab49f4d2835bca086d98cf763.zip |
Merge "[optimizing compiler] Add DIV_LONG"
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index c5d6246134..be326dcece 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -41,7 +41,7 @@ static constexpr bool kExplicitStackOverflowCheck = false; static constexpr int kNumberOfPushedRegistersAtEntry = 1 + 2; // LR, R6, R7 static constexpr int kCurrentMethodStackOffset = 0; -static constexpr Register kRuntimeParameterCoreRegisters[] = { R0, R1, R2 }; +static constexpr Register kRuntimeParameterCoreRegisters[] = { R0, R1, R2, R3 }; static constexpr size_t kRuntimeParameterCoreRegistersLength = arraysize(kRuntimeParameterCoreRegisters); static constexpr SRegister kRuntimeParameterFpuRegisters[] = { }; @@ -1698,8 +1698,11 @@ void InstructionCodeGeneratorARM::VisitMul(HMul* mul) { } void LocationsBuilderARM::VisitDiv(HDiv* div) { - LocationSummary* locations = - new (GetGraph()->GetArena()) LocationSummary(div, LocationSummary::kNoCall); + LocationSummary::CallKind call_kind = div->GetResultType() == Primitive::kPrimLong + ? LocationSummary::kCall + : LocationSummary::kNoCall; + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(div, call_kind); + switch (div->GetResultType()) { case Primitive::kPrimInt: { locations->SetInAt(0, Location::RequiresRegister()); @@ -1708,7 +1711,13 @@ void LocationsBuilderARM::VisitDiv(HDiv* div) { break; } case Primitive::kPrimLong: { - LOG(FATAL) << "Not implemented div type" << div->GetResultType(); + InvokeRuntimeCallingConvention calling_convention; + locations->SetInAt(0, Location::RegisterPairLocation( + calling_convention.GetRegisterAt(0), calling_convention.GetRegisterAt(1))); + locations->SetInAt(1, Location::RegisterPairLocation( + calling_convention.GetRegisterAt(2), calling_convention.GetRegisterAt(3))); + // The runtime helper puts the output in R0,R2. + locations->SetOut(Location::RegisterPairLocation(R0, R2)); break; } case Primitive::kPrimFloat: @@ -1737,7 +1746,15 @@ void InstructionCodeGeneratorARM::VisitDiv(HDiv* div) { } case Primitive::kPrimLong: { - LOG(FATAL) << "Not implemented div type" << div->GetResultType(); + InvokeRuntimeCallingConvention calling_convention; + DCHECK_EQ(calling_convention.GetRegisterAt(0), first.AsRegisterPairLow<Register>()); + DCHECK_EQ(calling_convention.GetRegisterAt(1), first.AsRegisterPairHigh<Register>()); + DCHECK_EQ(calling_convention.GetRegisterAt(2), second.AsRegisterPairLow<Register>()); + DCHECK_EQ(calling_convention.GetRegisterAt(3), second.AsRegisterPairHigh<Register>()); + DCHECK_EQ(R0, out.AsRegisterPairLow<Register>()); + DCHECK_EQ(R2, out.AsRegisterPairHigh<Register>()); + + codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLdiv), div, div->GetDexPc()); break; } @@ -1761,7 +1778,7 @@ void InstructionCodeGeneratorARM::VisitDiv(HDiv* div) { void LocationsBuilderARM::VisitDivZeroCheck(HDivZeroCheck* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); - locations->SetInAt(0, Location::RequiresRegister()); + locations->SetInAt(0, Location::RegisterOrConstant(instruction->InputAt(0))); if (instruction->HasUses()) { locations->SetOut(Location::SameAsFirstInput()); } @@ -1774,9 +1791,36 @@ void InstructionCodeGeneratorARM::VisitDivZeroCheck(HDivZeroCheck* instruction) LocationSummary* locations = instruction->GetLocations(); Location value = locations->InAt(0); - DCHECK(value.IsRegister()) << value; - __ cmp(value.As<Register>(), ShifterOperand(0)); - __ b(slow_path->GetEntryLabel(), EQ); + switch (instruction->GetType()) { + case Primitive::kPrimInt: { + if (value.IsRegister()) { + __ cmp(value.As<Register>(), ShifterOperand(0)); + __ b(slow_path->GetEntryLabel(), EQ); + } else { + DCHECK(value.IsConstant()) << value; + if (value.GetConstant()->AsIntConstant()->GetValue() == 0) { + __ b(slow_path->GetEntryLabel()); + } + } + break; + } + case Primitive::kPrimLong: { + if (value.IsRegisterPair()) { + __ orrs(IP, + value.AsRegisterPairLow<Register>(), + ShifterOperand(value.AsRegisterPairHigh<Register>())); + __ b(slow_path->GetEntryLabel(), EQ); + } else { + DCHECK(value.IsConstant()) << value; + if (value.GetConstant()->AsLongConstant()->GetValue() == 0) { + __ b(slow_path->GetEntryLabel()); + } + } + break; + default: + LOG(FATAL) << "Unexpected type for HDivZeroCheck " << instruction->GetType(); + } + } } void LocationsBuilderARM::VisitNewInstance(HNewInstance* instruction) { |