diff options
author | Calin Juravle <calin@google.com> | 2015-03-17 21:18:07 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-03-17 21:18:08 +0000 |
commit | 202d164d97c1e0322188706c222911f8370dd194 (patch) | |
tree | b1f0e65127e4a9ca87f4843490a1993dd250e148 /compiler/optimizing/code_generator_arm.cc | |
parent | cadf090da2dc91a3d6b842324e85f12ea6fef2ef (diff) | |
parent | f3b4aebd0f5ce6c82bfd6284919a5c5e91955124 (diff) | |
download | art-202d164d97c1e0322188706c222911f8370dd194.tar.gz art-202d164d97c1e0322188706c222911f8370dd194.tar.bz2 art-202d164d97c1e0322188706c222911f8370dd194.zip |
Merge "Revert "Inline long shift code""
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 65 |
1 files changed, 19 insertions, 46 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 689f5357f4..0a069a75ef 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -2312,9 +2312,12 @@ void LocationsBuilderARM::HandleShift(HBinaryOperation* op) { break; } case Primitive::kPrimLong: { - locations->SetInAt(0, Location::RequiresRegister()); - locations->SetInAt(1, Location::RequiresRegister()); - locations->SetOut(Location::RequiresRegister()); + InvokeRuntimeCallingConvention calling_convention; + locations->SetInAt(0, Location::RegisterPairLocation( + calling_convention.GetRegisterAt(0), calling_convention.GetRegisterAt(1))); + locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(2))); + // The runtime helper puts the output in R0,R1. + locations->SetOut(Location::RegisterPairLocation(R0, R1)); break; } default: @@ -2362,54 +2365,24 @@ void InstructionCodeGeneratorARM::HandleShift(HBinaryOperation* op) { break; } case Primitive::kPrimLong: { - Register o_h = out.AsRegisterPairHigh<Register>(); - Register o_l = out.AsRegisterPairLow<Register>(); - - Register high = first.AsRegisterPairHigh<Register>(); - Register low = first.AsRegisterPairLow<Register>(); - - Register second_reg = second.AsRegister<Register>(); + // TODO: Inline the assembly instead of calling the runtime. + 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.AsRegister<Register>()); + DCHECK_EQ(R0, out.AsRegisterPairLow<Register>()); + DCHECK_EQ(R1, out.AsRegisterPairHigh<Register>()); + int32_t entry_point_offset; if (op->IsShl()) { - // Shift the high part - __ and_(second_reg, second_reg, ShifterOperand(63)); - __ Lsl(high, high, second_reg); - // Shift the low part and `or` what overflowed on the high part - __ rsb(IP, second_reg, ShifterOperand(32)); - __ Lsr(IP, low, IP); - __ orr(o_h, high, ShifterOperand(IP)); - // If the shift is > 32 bits, override the high part - __ subs(IP, second_reg, ShifterOperand(32)); - __ it(PL); - __ Lsl(o_h, low, IP, false, PL); - // Shift the low part - __ Lsl(o_l, low, second_reg); + entry_point_offset = QUICK_ENTRY_POINT(pShlLong); } else if (op->IsShr()) { - // Shift the low part - __ and_(second_reg, second_reg, ShifterOperand(63)); - __ Lsr(low, low, second_reg); - // Shift the high part and `or` what underflowed on the low part - __ rsb(IP, second_reg, ShifterOperand(32)); - __ Lsl(IP, high, IP); - __ orr(o_l, low, ShifterOperand(IP)); - // If the shift is > 32 bits, override the low part - __ subs(IP, second_reg, ShifterOperand(32)); - __ it(PL); - __ Asr(o_l, high, IP, false, PL); - // Shift the high part - __ Asr(o_h, high, second_reg); + entry_point_offset = QUICK_ENTRY_POINT(pShrLong); } else { - // same as Shr except we use `Lsr`s and not `Asr`s - __ and_(second_reg, second_reg, ShifterOperand(63)); - __ Lsr(low, low, second_reg); - __ rsb(IP, second_reg, ShifterOperand(32)); - __ Lsl(IP, high, IP); - __ orr(o_l, low, ShifterOperand(IP)); - __ subs(IP, second_reg, ShifterOperand(32)); - __ it(PL); - __ Lsr(o_l, high, IP, false, PL); - __ Lsr(o_h, high, second_reg); + entry_point_offset = QUICK_ENTRY_POINT(pUshrLong); } + __ LoadFromOffset(kLoadWord, LR, TR, entry_point_offset); + __ blx(LR); break; } default: |