diff options
author | Calin Juravle <calin@google.com> | 2014-12-08 14:24:46 +0000 |
---|---|---|
committer | Calin Juravle <calin@google.com> | 2014-12-08 17:02:11 +0000 |
commit | d2ec87d84057174d4884ee16f652cbcfd31362e9 (patch) | |
tree | 9456c5851f157566380c37895407dfce4749bb4d /compiler/optimizing/code_generator_arm.cc | |
parent | f551efff34c20e2f0cf962c3fc267204d5e7611f (diff) |
[optimizing compiler] Add REM_FLOAT and REM_DOUBLE
- for arm, x86, x86_64 backends
- reinstated fmod quick entry points for x86. This is a partial revert
of bd3682eada753de52975ae2b4a712bd87dc139a6 which added inline assembly
for floting point rem on x86. Note that Quick still uses the inline
version.
- fix rem tests for longs
Change-Id: I73be19a9f2f2bcf3f718d9ca636e67bdd72b5440
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 36af393e3b..cbe5f0cc6e 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -44,7 +44,7 @@ static constexpr int kCurrentMethodStackOffset = 0; static constexpr Register kRuntimeParameterCoreRegisters[] = { R0, R1, R2, R3 }; static constexpr size_t kRuntimeParameterCoreRegistersLength = arraysize(kRuntimeParameterCoreRegisters); -static constexpr SRegister kRuntimeParameterFpuRegisters[] = { S0, S1 }; +static constexpr SRegister kRuntimeParameterFpuRegisters[] = { S0, S1, S2, S3 }; static constexpr size_t kRuntimeParameterFpuRegistersLength = arraysize(kRuntimeParameterFpuRegisters); @@ -2132,12 +2132,13 @@ void InstructionCodeGeneratorARM::VisitDiv(HDiv* div) { } void LocationsBuilderARM::VisitRem(HRem* rem) { - LocationSummary::CallKind call_kind = rem->GetResultType() == Primitive::kPrimLong - ? LocationSummary::kCall - : LocationSummary::kNoCall; + Primitive::Type type = rem->GetResultType(); + LocationSummary::CallKind call_kind = type == Primitive::kPrimInt + ? LocationSummary::kNoCall + : LocationSummary::kCall; LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(rem, call_kind); - switch (rem->GetResultType()) { + switch (type) { case Primitive::kPrimInt: { locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::RequiresRegister()); @@ -2155,14 +2156,26 @@ void LocationsBuilderARM::VisitRem(HRem* rem) { locations->SetOut(Location::RegisterPairLocation(R2, R3)); break; } - case Primitive::kPrimFloat: + case Primitive::kPrimFloat: { + InvokeRuntimeCallingConvention calling_convention; + locations->SetInAt(0, Location::FpuRegisterLocation(calling_convention.GetFpuRegisterAt(0))); + locations->SetInAt(1, Location::FpuRegisterLocation(calling_convention.GetFpuRegisterAt(1))); + locations->SetOut(Location::FpuRegisterLocation(S0)); + break; + } + case Primitive::kPrimDouble: { - LOG(FATAL) << "Unimplemented rem type " << rem->GetResultType(); + InvokeRuntimeCallingConvention calling_convention; + locations->SetInAt(0, Location::FpuRegisterPairLocation( + calling_convention.GetFpuRegisterAt(0), calling_convention.GetFpuRegisterAt(1))); + locations->SetInAt(1, Location::FpuRegisterPairLocation( + calling_convention.GetFpuRegisterAt(2), calling_convention.GetFpuRegisterAt(3))); + locations->SetOut(Location::Location::FpuRegisterPairLocation(S0, S1)); break; } default: - LOG(FATAL) << "Unexpected rem type " << rem->GetResultType(); + LOG(FATAL) << "Unexpected rem type " << type; } } @@ -2172,7 +2185,8 @@ void InstructionCodeGeneratorARM::VisitRem(HRem* rem) { Location first = locations->InAt(0); Location second = locations->InAt(1); - switch (rem->GetResultType()) { + Primitive::Type type = rem->GetResultType(); + switch (type) { case Primitive::kPrimInt: { Register reg1 = first.AsRegister<Register>(); Register reg2 = second.AsRegister<Register>(); @@ -2188,26 +2202,22 @@ void InstructionCodeGeneratorARM::VisitRem(HRem* rem) { } case Primitive::kPrimLong: { - 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(R2, out.AsRegisterPairLow<Register>()); - DCHECK_EQ(R3, out.AsRegisterPairHigh<Register>()); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLmod), rem, rem->GetDexPc()); break; } - case Primitive::kPrimFloat: + case Primitive::kPrimFloat: { + codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pFmodf), rem, rem->GetDexPc()); + break; + } + case Primitive::kPrimDouble: { - LOG(FATAL) << "Unimplemented rem type " << rem->GetResultType(); + codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pFmod), rem, rem->GetDexPc()); break; } default: - LOG(FATAL) << "Unexpected rem type " << rem->GetResultType(); + LOG(FATAL) << "Unexpected rem type " << type; } } |