| Index: src/arm/lithium-codegen-arm.cc
|
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
|
| index 8b3c1a423614a3a719498fa21de4b62b6a345bb8..b35dc7c145d884c074bd6582419293f7015fd954 100644
|
| --- a/src/arm/lithium-codegen-arm.cc
|
| +++ b/src/arm/lithium-codegen-arm.cc
|
| @@ -3122,61 +3122,34 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
|
|
|
|
|
| void LCodeGen::DoPower(LPower* instr) {
|
| - LOperand* left = instr->InputAt(0);
|
| - LOperand* right = instr->InputAt(1);
|
| - Register scratch = scratch0();
|
| - DoubleRegister result_reg = ToDoubleRegister(instr->result());
|
| Representation exponent_type = instr->hydrogen()->right()->representation();
|
| - if (exponent_type.IsDouble()) {
|
| - // Prepare arguments and call C function.
|
| - __ PrepareCallCFunction(0, 2, scratch);
|
| - __ SetCallCDoubleArguments(ToDoubleRegister(left),
|
| - ToDoubleRegister(right));
|
| - __ CallCFunction(
|
| - ExternalReference::power_double_double_function(isolate()), 0, 2);
|
| - } else if (exponent_type.IsInteger32()) {
|
| - ASSERT(ToRegister(right).is(r0));
|
| - // Prepare arguments and call C function.
|
| - __ PrepareCallCFunction(1, 1, scratch);
|
| - __ SetCallCDoubleArguments(ToDoubleRegister(left), ToRegister(right));
|
| - __ CallCFunction(
|
| - ExternalReference::power_double_int_function(isolate()), 1, 1);
|
| - } else {
|
| - ASSERT(exponent_type.IsTagged());
|
| - ASSERT(instr->hydrogen()->left()->representation().IsDouble());
|
| -
|
| - Register right_reg = ToRegister(right);
|
| -
|
| - // Check for smi on the right hand side.
|
| - Label non_smi, call;
|
| - __ JumpIfNotSmi(right_reg, &non_smi);
|
| -
|
| - // Untag smi and convert it to a double.
|
| - __ SmiUntag(right_reg);
|
| - SwVfpRegister single_scratch = double_scratch0().low();
|
| - __ vmov(single_scratch, right_reg);
|
| - __ vcvt_f64_s32(result_reg, single_scratch);
|
| - __ jmp(&call);
|
| -
|
| - // Heap number map check.
|
| - __ bind(&non_smi);
|
| - __ ldr(scratch, FieldMemOperand(right_reg, HeapObject::kMapOffset));
|
| + // Having marked this as a call, we can use any registers.
|
| + // Just make sure that the input/output registers are the expected ones.
|
| + ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
|
| + ToDoubleRegister(instr->InputAt(1)).is(d2));
|
| + ASSERT(!instr->InputAt(1)->IsRegister() ||
|
| + ToRegister(instr->InputAt(1)).is(r2));
|
| + ASSERT(ToDoubleRegister(instr->InputAt(0)).is(d1));
|
| + ASSERT(ToDoubleRegister(instr->result()).is(d3));
|
| +
|
| + if (exponent_type.IsTagged()) {
|
| + Label no_deopt;
|
| + __ JumpIfSmi(r2, &no_deopt);
|
| + __ ldr(r7, FieldMemOperand(r2, HeapObject::kMapOffset));
|
| __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
|
| - __ cmp(scratch, Operand(ip));
|
| + __ cmp(r7, Operand(ip));
|
| DeoptimizeIf(ne, instr->environment());
|
| - int32_t value_offset = HeapNumber::kValueOffset - kHeapObjectTag;
|
| - __ add(scratch, right_reg, Operand(value_offset));
|
| - __ vldr(result_reg, scratch, 0);
|
| -
|
| - // Prepare arguments and call C function.
|
| - __ bind(&call);
|
| - __ PrepareCallCFunction(0, 2, scratch);
|
| - __ SetCallCDoubleArguments(ToDoubleRegister(left), result_reg);
|
| - __ CallCFunction(
|
| - ExternalReference::power_double_double_function(isolate()), 0, 2);
|
| + __ bind(&no_deopt);
|
| + MathPowStub stub(MathPowStub::TAGGED);
|
| + __ CallStub(&stub);
|
| + } else if (exponent_type.IsInteger32()) {
|
| + MathPowStub stub(MathPowStub::INTEGER);
|
| + __ CallStub(&stub);
|
| + } else {
|
| + ASSERT(exponent_type.IsDouble());
|
| + MathPowStub stub(MathPowStub::DOUBLE);
|
| + __ CallStub(&stub);
|
| }
|
| - // Store the result in the result register.
|
| - __ GetCFunctionDoubleResult(result_reg);
|
| }
|
|
|
|
|
|
|