 Chromium Code Reviews
 Chromium Code Reviews Issue 6532020:
  ARM: Implement DoPower in the lithium code generator.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/src
    
  
    Issue 6532020:
  ARM: Implement DoPower in the lithium code generator.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/src| 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: |