Chromium Code Reviews| Index: src/ia32/lithium-codegen-ia32.cc | 
| =================================================================== | 
| --- src/ia32/lithium-codegen-ia32.cc (revision 6029) | 
| +++ src/ia32/lithium-codegen-ia32.cc (working copy) | 
| @@ -2255,47 +2255,55 @@ | 
| void LCodeGen::DoPower(LPower* instr) { | 
| LOperand* left = instr->left(); | 
| LOperand* right = instr->right(); | 
| + DoubleRegister result_reg = ToDoubleRegister(instr->result()); | 
| Representation exponent_type = instr->hydrogen()->right()->representation(); | 
| if (exponent_type.IsDouble()) { | 
| - // Pass two doubles as arguments on the stack. | 
| - __ PrepareCallCFunction(4, eax); | 
| + // It is safe to use ebx directly since the instruction is marked | 
| + // as a call. | 
| + __ PrepareCallCFunction(4, ebx); | 
| __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); | 
| __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right)); | 
| __ CallCFunction(ExternalReference::power_double_double_function(), 4); | 
| } else if (exponent_type.IsInteger32()) { | 
| + // It is safe to use ebx directly since the instruction is marked | 
| + // as a call. | 
| + ASSERT(!ToRegister(right).is(ebx)); | 
| __ PrepareCallCFunction(4, ebx); | 
| __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); | 
| __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right)); | 
| __ CallCFunction(ExternalReference::power_double_int_function(), 4); | 
| } else { | 
| ASSERT(exponent_type.IsTagged()); | 
| - __ PrepareCallCFunction(4, ebx); | 
| - __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); | 
| + CpuFeatures::Scope scope(SSE2); | 
| Register right_reg = ToRegister(right); | 
| - Label non_smi; | 
| - Label done; | 
| + | 
| + Label non_smi, call; | 
| __ test(right_reg, Immediate(kSmiTagMask)); | 
| __ j(not_zero, &non_smi); | 
| __ SmiUntag(right_reg); | 
| - __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right)); | 
| - __ CallCFunction(ExternalReference::power_double_int_function(), 4); | 
| - __ jmp(&done); | 
| + __ cvtsi2sd(result_reg, Operand(right_reg)); | 
| + __ jmp(&call); | 
| 
 
William Hesse
2010/12/15 14:38:38
Calling power_double_double rather than power_doub
 
Mads Ager (chromium)
2010/12/15 14:43:20
Good point. I'll check performance. I didn't notic
 
 | 
| __ bind(&non_smi); | 
| + // It is safe to use ebx directly since the instruction is marked | 
| + // as a call. | 
| + ASSERT(!right_reg.is(ebx)); | 
| __ CmpObjectType(right_reg, HEAP_NUMBER_TYPE , ebx); | 
| DeoptimizeIf(not_equal, instr->environment()); | 
| - __ movdbl(xmm1, FieldOperand(right_reg, HeapNumber::kValueOffset)); | 
| - __ movdbl(Operand(esp, 1 * kDoubleSize), xmm1); | 
| + __ movdbl(result_reg, FieldOperand(right_reg, HeapNumber::kValueOffset)); | 
| + | 
| + __ bind(&call); | 
| + __ PrepareCallCFunction(4, ebx); | 
| + __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); | 
| + __ movdbl(Operand(esp, 1 * kDoubleSize), result_reg); | 
| __ CallCFunction(ExternalReference::power_double_double_function(), 4); | 
| - | 
| - __ bind(&done); | 
| } | 
| // Return value is in st(0) on ia32. | 
| // Store it into the (fixed) result register. | 
| __ sub(Operand(esp), Immediate(kDoubleSize)); | 
| __ fstp_d(Operand(esp, 0)); | 
| - __ movdbl(ToDoubleRegister(instr->result()), Operand(esp, 0)); | 
| + __ movdbl(result_reg, Operand(esp, 0)); | 
| __ add(Operand(esp), Immediate(kDoubleSize)); | 
| } |