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); |
} |