Index: src/mips/lithium-codegen-mips.cc |
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc |
index 7ccde79ac637c5d846385a485e67a3457b476997..c160db4a27172ba6da8ce4b28aee6b989a7117ae 100644 |
--- a/src/mips/lithium-codegen-mips.cc |
+++ b/src/mips/lithium-codegen-mips.cc |
@@ -3024,58 +3024,32 @@ 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); |
+ // 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(f4)); |
+ ASSERT(!instr->InputAt(1)->IsRegister() || |
+ ToRegister(instr->InputAt(1)).is(a2)); |
+ ASSERT(ToDoubleRegister(instr->InputAt(0)).is(f2)); |
+ ASSERT(ToDoubleRegister(instr->result()).is(f0)); |
+ |
+ if (exponent_type.IsTagged()) { |
+ Label no_deopt; |
+ __ JumpIfSmi(a2, &no_deopt); |
+ __ lw(t3, FieldMemOperand(a2, HeapObject::kMapOffset)); |
+ DeoptimizeIf(ne, instr->environment(), t3, Operand(at)); |
+ __ bind(&no_deopt); |
+ MathPowStub stub(MathPowStub::TAGGED); |
+ __ CallStub(&stub); |
} else if (exponent_type.IsInteger32()) { |
- ASSERT(ToRegister(right).is(a0)); |
- // Prepare arguments and call C function. |
- __ PrepareCallCFunction(1, 1, scratch); |
- __ SetCallCDoubleArguments(ToDoubleRegister(left), ToRegister(right)); |
- __ CallCFunction( |
- ExternalReference::power_double_int_function(isolate()), 1, 1); |
+ MathPowStub stub(MathPowStub::INTEGER); |
+ __ CallStub(&stub); |
} 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); |
- FPURegister single_scratch = double_scratch0(); |
- __ mtc1(right_reg, single_scratch); |
- __ cvt_d_w(result_reg, single_scratch); |
- __ Branch(&call); |
- |
- // Heap number map check. |
- __ bind(&non_smi); |
- __ lw(scratch, FieldMemOperand(right_reg, HeapObject::kMapOffset)); |
- __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
- DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); |
- __ ldc1(result_reg, FieldMemOperand(right_reg, HeapNumber::kValueOffset)); |
- |
- // 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); |
+ ASSERT(exponent_type.IsDouble()); |
+ MathPowStub stub(MathPowStub::DOUBLE); |
+ __ CallStub(&stub); |
} |
- // Store the result in the result register. |
- __ GetCFunctionDoubleResult(result_reg); |
} |