Chromium Code Reviews| Index: src/x64/lithium-codegen-x64.cc |
| =================================================================== |
| --- src/x64/lithium-codegen-x64.cc (revision 6635) |
| +++ src/x64/lithium-codegen-x64.cc (working copy) |
| @@ -1954,13 +1954,108 @@ |
| } |
| +class DeferredTaggedToI: public LDeferredCode { |
| + public: |
| + DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) |
| + : LDeferredCode(codegen), instr_(instr) { } |
| + virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } |
| + private: |
| + LTaggedToI* instr_; |
| +}; |
| + |
| + |
| void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { |
| - Abort("Unimplemented: %s", "DoDeferredTaggedToI"); |
| + NearLabel done, heap_number; |
| + Register input_reg = ToRegister(instr->InputAt(0)); |
| + |
| + // Heap number map check. |
| + __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
| + Heap::kHeapNumberMapRootIndex); |
|
Lasse Reichstein
2011/02/04 12:57:55
indentation.
William Hesse
2011/02/04 13:16:39
Done.
|
| + |
| + if (instr->truncating()) { |
| + __ j(equal, &heap_number); |
| + // Check for undefined. Undefined is converted to zero for truncating |
| + // conversions. |
| + __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); |
| + DeoptimizeIf(not_equal, instr->environment()); |
| + __ movl(input_reg, Immediate(0)); |
| + __ jmp(&done); |
| + |
| + __ bind(&heap_number); |
| + if (CpuFeatures::IsSupported(SSE3)) { |
| + CpuFeatures::Scope scope(SSE3); |
|
Lasse Reichstein
2011/02/04 12:57:55
Fisttp isn't any "more powerful" than cvttsd2si in
William Hesse
2011/02/04 13:16:39
Done.
|
| + NearLabel convert; |
| + // Use more powerful conversion when sse3 is available. |
| + // Load x87 register with heap number. |
| + __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| + // Get exponent alone and check for too-big exponent. |
| + __ movl(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); |
| + __ andl(input_reg, Immediate(HeapNumber::kExponentMask)); |
| + const uint32_t kTooBigExponent = |
| + (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; |
| + __ cmpl(input_reg, Immediate(kTooBigExponent)); |
| + __ j(less, &convert); |
| + // Pop FPU stack before deoptimizing. |
| + __ ffree(0); |
| + __ fincstp(); |
|
Lasse Reichstein
2011/02/04 12:57:55
Use
__ fstp(0);
to drop the top of the FPU stack
William Hesse
2011/02/04 13:16:39
Entire block of code deleted.
On 2011/02/04 12:57:
|
| + DeoptimizeIf(no_condition, instr->environment()); |
| + |
| + // Reserve space for 64 bit answer. |
| + __ bind(&convert); |
| + __ subq(rsp, Immediate(kDoubleSize)); |
| + // Do conversion, which cannot fail because we checked the exponent. |
| + __ fisttp_d(Operand(rsp, 0)); |
| + __ movl(input_reg, Operand(rsp, 0)); // Low word of answer is the result. |
| + __ addq(rsp, Immediate(kDoubleSize)); |
| + } else { |
| + NearLabel deopt; |
| + XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); |
| + __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| + __ cvttsd2si(input_reg, xmm0); |
|
Lasse Reichstein
2011/02/04 12:57:55
Use the 64-bit version and compare to 0x8000000000
William Hesse
2011/02/04 13:16:39
Done.
|
| + __ cmpl(input_reg, Immediate(0x80000000u)); |
| + __ j(not_equal, &done); |
| + // Check if the input was 0x8000000 (kMinInt). |
| + // If no, then we got an overflow and we deoptimize. |
| + ExternalReference min_int = ExternalReference::address_of_min_int(); |
| + __ movq(kScratchRegister, min_int); |
| + __ movsd(xmm_temp, Operand(kScratchRegister, 0)); |
| + __ ucomisd(xmm_temp, xmm0); |
| + DeoptimizeIf(not_equal, instr->environment()); |
| + DeoptimizeIf(parity_even, instr->environment()); // NaN. |
| + } |
| + } else { |
| + // Deoptimize if we don't have a heap number. |
| + DeoptimizeIf(not_equal, instr->environment()); |
| + |
| + XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); |
| + __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| + __ cvttsd2si(input_reg, xmm0); |
| + __ cvtlsi2sd(xmm_temp, input_reg); |
| + __ ucomisd(xmm0, xmm_temp); |
| + DeoptimizeIf(not_equal, instr->environment()); |
| + DeoptimizeIf(parity_even, instr->environment()); // NaN. |
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| + __ testl(input_reg, input_reg); |
| + __ j(not_zero, &done); |
| + __ movmskpd(input_reg, xmm0); |
| + __ andl(input_reg, Immediate(1)); |
| + DeoptimizeIf(not_zero, instr->environment()); |
| + } |
| + } |
| + __ bind(&done); |
| } |
| void LCodeGen::DoTaggedToI(LTaggedToI* instr) { |
| - Abort("Unimplemented: %s", "DoTaggedToI"); |
| + LOperand* input = instr->InputAt(0); |
| + ASSERT(input->IsRegister()); |
| + ASSERT(input->Equals(instr->result())); |
| + |
| + Register input_reg = ToRegister(input); |
| + DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); |
| + __ JumpIfNotSmi(input_reg, deferred->entry()); |
| + __ SmiToInteger32(input_reg, input_reg); |
| + __ bind(deferred->exit()); |
| } |
| @@ -2217,7 +2312,6 @@ |
| void LCodeGen::DoStackCheck(LStackCheck* instr) { |
| // Perform stack overflow check. |
| NearLabel done; |
| - ExternalReference stack_limit = ExternalReference::address_of_stack_limit(); |
| __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
| __ j(above_equal, &done); |