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,73 @@ |
} |
+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); |
+ |
+ 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); |
+ |
+ __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
+ __ cvttsd2siq(input_reg, xmm0); |
+ __ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000)); |
+ __ cmpl(input_reg, kScratchRegister); |
+ DeoptimizeIf(equal, instr->environment()); |
+ } 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 +2277,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); |