Chromium Code Reviews| Index: src/x64/lithium-codegen-x64.cc |
| =================================================================== |
| --- src/x64/lithium-codegen-x64.cc (revision 6849) |
| +++ src/x64/lithium-codegen-x64.cc (working copy) |
| @@ -2081,22 +2081,77 @@ |
| void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
| - Abort("Unimplemented: %s", "DoMathFloor"); |
| + XMMRegister xmm_scratch = xmm0; |
| + Register output_reg = ToRegister(instr->result()); |
| + XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
| + __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. |
| + __ ucomisd(input_reg, xmm_scratch); |
| + |
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| + DeoptimizeIf(below_equal, instr->environment()); |
| + } else { |
| + DeoptimizeIf(below, instr->environment()); |
| + } |
| + |
| + // Use truncating instruction (OK because input is positive). |
| + __ cvttsd2si(output_reg, input_reg); |
|
Lasse Reichstein
2011/02/18 14:13:47
Use the "q" version, so you can properly handle mi
William Hesse
2011/02/18 14:33:28
But then we have much more complicated tests, beca
|
| + |
| + // Overflow is signalled with minint. |
| + __ cmpl(output_reg, Immediate(0x80000000)); |
| + DeoptimizeIf(equal, instr->environment()); |
| } |
| void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
| - Abort("Unimplemented: %s", "DoMathRound"); |
| + const XMMRegister xmm_scratch = xmm0; |
| + Register output_reg = ToRegister(instr->result()); |
| + XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
| + |
| + // xmm_scratch = 0.5 |
| + ExternalReference one_half = ExternalReference::address_of_one_half(); |
| + __ movq(kScratchRegister, one_half); |
| + __ movsd(xmm_scratch, Operand(kScratchRegister, 0)); |
|
Lasse Reichstein
2011/02/18 14:13:47
Why load from memory when we have 64-bit immediate
William Hesse
2011/02/18 14:33:28
Done.
|
| + |
| + // input = input + 0.5 |
| + __ addsd(input_reg, xmm_scratch); |
| + |
| + // We need to return -0 for the input range [-0.5, 0[, otherwise |
| + // compute Math.floor(value + 0.5). |
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| + __ ucomisd(input_reg, xmm_scratch); |
| + DeoptimizeIf(below_equal, instr->environment()); |
| + } else { |
| + // If we don't need to bailout on -0, we check only bailout |
| + // on negative inputs. |
| + __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. |
| + __ ucomisd(input_reg, xmm_scratch); |
| + DeoptimizeIf(below, instr->environment()); |
| + } |
| + |
| + // Compute Math.floor(value + 0.5). |
| + // Use truncating instruction (OK because input is positive). |
| + __ cvttsd2si(output_reg, input_reg); |
| + |
| + // Overflow is signalled with minint. |
| + __ cmpl(output_reg, Immediate(0x80000000)); |
| + DeoptimizeIf(equal, instr->environment()); |
| } |
| void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { |
| - Abort("Unimplemented: %s", "DoMathSqrt"); |
| + XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
| + ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); |
| + __ sqrtsd(input_reg, input_reg); |
| } |
| void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { |
| - Abort("Unimplemented: %s", "DoMathPowHalf"); |
| + XMMRegister xmm_scratch = xmm0; |
| + XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
| + ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); |
| + __ xorpd(xmm_scratch, xmm_scratch); |
| + __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. |
| + __ sqrtsd(input_reg, input_reg); |
| } |
| @@ -2121,7 +2176,35 @@ |
| void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { |
| - Abort("Unimplemented: %s", "DoUnaryMathOperation"); |
| + switch (instr->op()) { |
| + case kMathAbs: |
| + DoMathAbs(instr); |
| + break; |
| + case kMathFloor: |
| + DoMathFloor(instr); |
| + break; |
| + case kMathRound: |
| + DoMathRound(instr); |
| + break; |
| + case kMathSqrt: |
| + DoMathSqrt(instr); |
| + break; |
| + case kMathPowHalf: |
| + DoMathPowHalf(instr); |
| + break; |
| + case kMathCos: |
| + DoMathCos(instr); |
| + break; |
| + case kMathSin: |
| + DoMathSin(instr); |
| + break; |
| + case kMathLog: |
| + DoMathLog(instr); |
| + break; |
| + |
| + default: |
| + UNREACHABLE(); |
| + } |
| } |