diff options
author | Calin Juravle <calin@google.com> | 2014-11-11 19:07:44 +0000 |
---|---|---|
committer | Calin Juravle <calin@google.com> | 2014-11-12 19:43:32 +0000 |
commit | d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13 (patch) | |
tree | 2f8192e49c9debeba18e73e28b9c789adf8d2eef /compiler/optimizing/code_generator_arm.cc | |
parent | f97f9fbfdf7f2e23c662f21081fadee6af37809d (diff) | |
download | art-d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13.tar.gz art-d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13.tar.bz2 art-d6fb6cfb6f2d0d9595f55e8cc18d2753be5d9a13.zip |
[optimizing compiler] Add DIV_LONG
- for backends: arm, x86, x86_64
- added cqo, idivq, testq assembly for x64_64
- small cleanups
Change-Id: I762ef37880749038ed25d6014370be9a61795200
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 87955ebae5..4d86732cc7 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[] = { }; @@ -1700,8 +1700,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()); @@ -1710,7 +1713,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: @@ -1739,7 +1748,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; } @@ -1763,7 +1780,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()); } @@ -1776,9 +1793,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) { |