Chromium Code Reviews| Index: src/arm/lithium-codegen-arm.cc |
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
| index 2c916f6ad67b847376a3656a5189f25d1cb0c18c..02e22b22e6acac2570b3df9fa5fe8791b875747c 100644 |
| --- a/src/arm/lithium-codegen-arm.cc |
| +++ b/src/arm/lithium-codegen-arm.cc |
| @@ -2861,6 +2861,70 @@ void LCodeGen::DoMathSqrt(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()) { |
| + // Save r0-r3 on the stack, prepare arguments and call C function. |
| + __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); |
|
Søren Thygesen Gjesse
2011/02/17 09:59:56
As discussed off-line this saving is not needed.
Karl Klose
2011/02/21 13:34:59
Done.
|
| + __ PrepareCallCFunction(4, scratch); |
| + __ vmov(r0, r1, ToDoubleRegister(left)); |
| + __ vmov(r2, r3, ToDoubleRegister(right)); |
| + __ CallCFunction(ExternalReference::power_double_double_function(), 4); |
| + } else if (exponent_type.IsInteger32()) { |
| + ASSERT(ToRegister(right).is(r0)); |
| + // Save r0-r3 on the stack, prepare arguments and call C function. |
| + __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); |
|
Søren Thygesen Gjesse
2011/02/17 09:59:56
Ditto.
Karl Klose
2011/02/21 13:34:59
Done.
|
| + __ PrepareCallCFunction(4, scratch); |
| + __ mov(r2, ToRegister(right)); |
| + __ vmov(r0, r1, ToDoubleRegister(left)); |
| + __ CallCFunction(ExternalReference::power_double_int_function(), 4); |
| + } else { |
| + ASSERT(exponent_type.IsTagged()); |
| + ASSERT(instr->hydrogen()->left()->representation().IsDouble()); |
| + ASSERT(CpuFeatures::IsSupported(VFP3)); |
|
Søren Thygesen Gjesse
2011/02/17 09:59:56
Crankshaft implies VFP3, and we are already in a V
Karl Klose
2011/02/21 13:34:59
Done.
|
| + |
| + Register right_reg = ToRegister(right); |
| + |
| + // Check for smi on the right hand side. |
| + Label non_smi, call; |
|
Søren Thygesen Gjesse
2011/02/17 09:59:56
Please use JumpIfNotSmi.
Karl Klose
2011/02/21 13:34:59
Done.
|
| + __ tst(right_reg, Operand(kSmiTagMask)); |
| + __ b(ne, &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)); |
| + __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| + __ cmp(scratch, Operand(ip)); |
| + DeoptimizeIf(ne, instr->environment()); |
| + int32_t value_offset = HeapNumber::kValueOffset - kHeapObjectTag; |
| + __ add(scratch, right_reg, Operand(value_offset), LeaveCC); |
|
Søren Thygesen Gjesse
2011/02/17 09:59:56
LeaveCC is default for add.
Karl Klose
2011/02/21 13:34:59
Done.
|
| + __ vldr(result_reg, scratch, 0); |
| + |
| + // Save r0-r3 on the stack, prepare arguments and call C function. |
| + __ bind(&call); |
| + __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); |
| + __ PrepareCallCFunction(4, scratch); |
| + __ vmov(r0, r1, ToDoubleRegister(left)); |
| + __ vmov(r2, r3, result_reg); |
| + __ CallCFunction(ExternalReference::power_double_double_function(), 4); |
| + } |
| + // Store the result in the result register and restore r0-r3. |
|
Søren Thygesen Gjesse
2011/02/17 09:59:56
We need to support non USE_ARM_EABI, where fp resu
Karl Klose
2011/02/21 13:34:59
Implemented MacroAssembler::GetCFunctionDoubleResu
|
| + __ vmov(result_reg, r0, r1); |
| + __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); |
| +} |
| + |
| + |
| void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { |
| switch (instr->op()) { |
| case kMathAbs: |