Commit 6fdf50c0 authored by yangguo@chromium.org's avatar yangguo@chromium.org

MIPS: Port Math.pow inlining to ARM.

Port r10210 (6b15398) and r10226 (cdc75a453).

BUG=
TEST=

Review URL: http://codereview.chromium.org/8896021
Patch from Daniel Kalmar <kalmard@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10234 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 42a85ce5
This diff is collapsed.
...@@ -2958,8 +2958,12 @@ void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { ...@@ -2958,8 +2958,12 @@ void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
ASSERT(args->length() == 2); ASSERT(args->length() == 2);
VisitForStackValue(args->at(0)); VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1)); VisitForStackValue(args->at(1));
MathPowStub stub(MathPowStub::ON_STACK); if (CpuFeatures::IsSupported(FPU)) {
__ CallStub(&stub); MathPowStub stub(MathPowStub::ON_STACK);
__ CallStub(&stub);
} else {
__ CallRuntime(Runtime::kMath_pow, 2);
}
context()->Plug(v0); context()->Plug(v0);
} }
......
...@@ -3024,58 +3024,32 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { ...@@ -3024,58 +3024,32 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
void LCodeGen::DoPower(LPower* 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(); Representation exponent_type = instr->hydrogen()->right()->representation();
if (exponent_type.IsDouble()) { // Having marked this as a call, we can use any registers.
// Prepare arguments and call C function. // Just make sure that the input/output registers are the expected ones.
__ PrepareCallCFunction(0, 2, scratch); ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
__ SetCallCDoubleArguments(ToDoubleRegister(left), ToDoubleRegister(instr->InputAt(1)).is(f4));
ToDoubleRegister(right)); ASSERT(!instr->InputAt(1)->IsRegister() ||
__ CallCFunction( ToRegister(instr->InputAt(1)).is(a2));
ExternalReference::power_double_double_function(isolate()), 0, 2); 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()) { } else if (exponent_type.IsInteger32()) {
ASSERT(ToRegister(right).is(a0)); MathPowStub stub(MathPowStub::INTEGER);
// Prepare arguments and call C function. __ CallStub(&stub);
__ PrepareCallCFunction(1, 1, scratch);
__ SetCallCDoubleArguments(ToDoubleRegister(left), ToRegister(right));
__ CallCFunction(
ExternalReference::power_double_int_function(isolate()), 1, 1);
} else { } else {
ASSERT(exponent_type.IsTagged()); ASSERT(exponent_type.IsDouble());
ASSERT(instr->hydrogen()->left()->representation().IsDouble()); MathPowStub stub(MathPowStub::DOUBLE);
__ CallStub(&stub);
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);
} }
// Store the result in the result register.
__ GetCFunctionDoubleResult(result_reg);
} }
......
...@@ -1406,9 +1406,9 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) { ...@@ -1406,9 +1406,9 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
LOperand* left = UseFixedDouble(instr->left(), f2); LOperand* left = UseFixedDouble(instr->left(), f2);
LOperand* right = exponent_type.IsDouble() ? LOperand* right = exponent_type.IsDouble() ?
UseFixedDouble(instr->right(), f4) : UseFixedDouble(instr->right(), f4) :
UseFixed(instr->right(), a0); UseFixed(instr->right(), a2);
LPower* result = new LPower(left, right); LPower* result = new LPower(left, right);
return MarkAsCall(DefineFixedDouble(result, f6), return MarkAsCall(DefineFixedDouble(result, f0),
instr, instr,
CAN_DEOPTIMIZE_EAGERLY); CAN_DEOPTIMIZE_EAGERLY);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment