Revert "Inline long shift code"
This reverts commit 09895ebf2d98783e65930a820e9288703bb1a50b.
Change-Id: I7544022d896ef4353bc2cdf4b036403ed20c956d
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 0403af1..07cc41a 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -2311,9 +2311,12 @@
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:
@@ -2361,54 +2364,24 @@
break;
}
case Primitive::kPrimLong: {
- Register o_h = out.AsRegisterPairHigh<Register>();
- Register o_l = out.AsRegisterPairLow<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>());
- Register high = first.AsRegisterPairHigh<Register>();
- Register low = first.AsRegisterPairLow<Register>();
-
- Register second_reg = second.AsRegister<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: