Revision: 16615
Author:   [email protected]
Date:     Tue Sep 10 12:37:30 2013 UTC
Log:      Move ToInt conversions to the MacroAssembler for x64

+ Prevent truncating TaggedToI from bailing out.

(This is a port of r16464)

BUG=
[email protected]

Review URL: https://codereview.chromium.org/23938003
http://code.google.com/p/v8/source/detail?r=16615

Modified:
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
 /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
 /branches/bleeding_edge/src/x64/code-stubs-x64.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.h
 /branches/bleeding_edge/src/x64/macro-assembler-x64.cc
 /branches/bleeding_edge/src/x64/macro-assembler-x64.h

=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Sep 9 16:57:35 2013 UTC +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Sep 10 12:37:30 2013 UTC
@@ -471,8 +471,8 @@
         Comment(";;; Deferred code");
       }
       code->Generate();
-      __ bind(code->done());
       if (NeedsDeferredFrame()) {
+        __ bind(code->done());
         Comment(";;; Destroy frame");
         ASSERT(frame_is_built_);
         frame_is_built_ = false;
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Mon Sep 9 16:34:40 2013 UTC +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Tue Sep 10 12:37:30 2013 UTC
@@ -551,7 +551,7 @@
   void SetExit(Label* exit) { external_exit_ = exit; }
   Label* entry() { return &entry_; }
Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
-  Label* done() { return &done_; }
+ Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); }
   int instruction_index() const { return instruction_index_; }
   const LCodeGen::X87Stack& x87_stack() const { return x87_stack_; }

=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Wed Sep 4 13:53:24 2013 UTC +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Tue Sep 10 12:37:30 2013 UTC
@@ -282,20 +282,25 @@
                                Label* conversion_failed,
                                Label::Distance dst) {
   ASSERT(!input_reg.is(scratch));
-  Label done;
   cvttsd2si(result_reg, Operand(input_reg));
   cvtsi2sd(scratch, Operand(result_reg));
   ucomisd(scratch, input_reg);
   j(not_equal, conversion_failed, dst);
   j(parity_even, conversion_failed, dst);  // NaN.
   if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
+    Label done;
+    // The integer converted back is equal to the original. We
+    // only have to test if we got -0 as an input.
     test(result_reg, Operand(result_reg));
     j(not_zero, &done, Label::kNear);
     movmskpd(result_reg, input_reg);
+    // Bit 0 contains the sign of the double in input_reg.
+    // If input was positive, we are ok and return 0, otherwise
+    // jump to conversion_failed.
     and_(result_reg, 1);
     j(not_zero, conversion_failed, dst);
+    bind(&done);
   }
-  bind(&done);
 }


=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Fri Aug 30 11:24:58 2013 UTC +++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Tue Sep 10 12:37:30 2013 UTC
@@ -1136,6 +1136,7 @@
   const bool tagged = (argument_type_ == TAGGED);
   if (tagged) {
     Label input_not_smi, loaded;
+
     // Test that rax is a number.
     StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
     __ movq(rax, args.GetArgumentOperand(0));
@@ -1153,14 +1154,7 @@
     __ jmp(&loaded, Label::kNear);

     __ bind(&input_not_smi);
-    // Check if input is a HeapNumber.
-    __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex);
-    __ cmpq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
-    __ j(not_equal, &runtime_call);
-    // Input is a HeapNumber. Push it on the FPU stack and load its
-    // bits into rbx.
-    __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset));
-    __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset));
+    __ TaggedToI(rbx, rax, xmm1, TREAT_MINUS_ZERO_AS_ZERO, &runtime_call);
     __ movq(rdx, rbx);

     __ bind(&loaded);
@@ -1446,10 +1440,8 @@
   __ bind(&arg1_is_object);
   __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), heap_number_map);
   __ j(not_equal, &check_undefined_arg1);
-  // Get the untagged integer version of the rdx heap number in rcx.
-  DoubleToIStub stub1(rdx, r8, HeapNumber::kValueOffset - kHeapObjectTag,
-                      true);
-  __ call(stub1.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+  // Get the untagged integer version of the rdx heap number in r8.
+  __ TruncateHeapNumberToI(r8, rdx);

   // Here r8 has the untagged integer, rax has a Smi or a heap number.
   __ bind(&load_arg2);
@@ -1469,9 +1461,7 @@
   __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), heap_number_map);
   __ j(not_equal, &check_undefined_arg2);
   // Get the untagged integer version of the rax heap number in rcx.
-  DoubleToIStub stub2(rax, rcx, HeapNumber::kValueOffset - kHeapObjectTag,
-                      true);
-  __ call(stub2.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
+  __ TruncateHeapNumberToI(rcx, rax);

   __ bind(&done);
   __ movl(rax, r8);
@@ -1648,16 +1638,17 @@
   }

   if (exponent_type_ != INTEGER) {
-    Label fast_power;
+    Label fast_power, try_arithmetic_simplification;
     // Detect integer exponents stored as double.
+    __ DoubleToI(exponent, double_exponent, double_scratch,
+                 TREAT_MINUS_ZERO_AS_ZERO, &try_arithmetic_simplification);
+    __ jmp(&int_exponent);
+
+    __ bind(&try_arithmetic_simplification);
     __ cvttsd2si(exponent, double_exponent);
// Skip to runtime if possibly NaN (indicated by the indefinite integer).
     __ cmpl(exponent, Immediate(0x80000000u));
     __ j(equal, &call_runtime);
-    __ cvtlsi2sd(double_scratch, exponent);
-    // Already ruled out NaNs for exponent.
-    __ ucomisd(double_exponent, double_scratch);
-    __ j(equal, &int_exponent);

     if (exponent_type_ == ON_STACK) {
       // Detect square root case.  Crankshaft detects constant +/-0.5 at
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Sep 9 16:34:40 2013 UTC +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Sep 10 12:37:30 2013 UTC
@@ -373,6 +373,7 @@
       }
       code->Generate();
       if (NeedsDeferredFrame()) {
+        __ bind(code->done());
         Comment(";;; Destroy frame");
         ASSERT(frame_is_built_);
         frame_is_built_ = false;
@@ -4698,50 +4699,35 @@
 }


-void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
-  Label done, heap_number;
+void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
+  Label heap_number;
   Register input_reg = ToRegister(instr->value());

-  // Heap number map check.
-  __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
-                 Heap::kHeapNumberMapRootIndex);

   if (instr->truncating()) {
+    // Heap number map check.
+    __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
+                   Heap::kHeapNumberMapRootIndex);
     __ j(equal, &heap_number, Label::kNear);
     // Check for undefined. Undefined is converted to zero for truncating
     // conversions.
     __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
     DeoptimizeIf(not_equal, instr->environment());
     __ Set(input_reg, 0);
-    __ jmp(&done, Label::kNear);
+    __ jmp(done);

     __ bind(&heap_number);
-
-    __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
-    __ cvttsd2siq(input_reg, xmm0);
-    __ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000));
-    __ cmpq(input_reg, kScratchRegister);
-    DeoptimizeIf(equal, instr->environment());
+    __ TruncateHeapNumberToI(input_reg, input_reg);
   } else {
-    // Deoptimize if we don't have a heap number.
-    DeoptimizeIf(not_equal, instr->environment());
+    Label bailout;
+    XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
+    __ TaggedToI(input_reg, input_reg, xmm_temp,
+        instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);

-    XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
-    __ 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());
-    }
+    __ jmp(done);
+    __ bind(&bailout);
+    DeoptimizeIf(no_condition, instr->environment());
   }
-  __ bind(&done);
 }


@@ -4751,7 +4737,7 @@
     DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
         : LDeferredCode(codegen), instr_(instr) { }
     virtual void Generate() V8_OVERRIDE {
-      codegen()->DoDeferredTaggedToI(instr_);
+      codegen()->DoDeferredTaggedToI(instr_, done());
     }
     virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
    private:
@@ -4801,34 +4787,16 @@
   Register result_reg = ToRegister(result);

   if (instr->truncating()) {
- // Performs a truncating conversion of a floating point number as used by
-    // the JS bitwise operations.
-    __ cvttsd2siq(result_reg, input_reg);
-    __ movq(kScratchRegister,
-            V8_INT64_C(0x8000000000000000),
-            RelocInfo::NONE64);
-    __ cmpq(result_reg, kScratchRegister);
-    DeoptimizeIf(equal, instr->environment());
+    __ TruncateDoubleToI(result_reg, input_reg);
   } else {
-    __ cvttsd2si(result_reg, input_reg);
-    __ cvtlsi2sd(xmm0, result_reg);
-    __ ucomisd(xmm0, input_reg);
-    DeoptimizeIf(not_equal, instr->environment());
-    DeoptimizeIf(parity_even, instr->environment());  // NaN.
-    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      Label done;
-      // The integer converted back is equal to the original. We
-      // only have to test if we got -0 as an input.
-      __ testl(result_reg, result_reg);
-      __ j(not_zero, &done, Label::kNear);
-      __ movmskpd(result_reg, input_reg);
-      // Bit 0 contains the sign of the double in input_reg.
-      // If input was positive, we are ok and return 0, otherwise
-      // deoptimize.
-      __ andl(result_reg, Immediate(1));
-      DeoptimizeIf(not_zero, instr->environment());
-      __ bind(&done);
-    }
+    Label bailout, done;
+    __ DoubleToI(result_reg, input_reg, xmm0,
+        instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
+
+    __ jmp(&done, Label::kNear);
+    __ bind(&bailout);
+    DeoptimizeIf(no_condition, instr->environment());
+    __ bind(&done);
   }
 }

@@ -4838,31 +4806,19 @@
   ASSERT(input->IsDoubleRegister());
   LOperand* result = instr->result();
   ASSERT(result->IsRegister());
-  CpuFeatureScope scope(masm(), SSE2);

   XMMRegister input_reg = ToDoubleRegister(input);
   Register result_reg = ToRegister(result);

-  Label done;
-  __ cvttsd2si(result_reg, input_reg);
-  __ cvtlsi2sd(xmm0, result_reg);
-  __ ucomisd(xmm0, input_reg);
-  DeoptimizeIf(not_equal, instr->environment());
-  DeoptimizeIf(parity_even, instr->environment());  // NaN.
+  Label bailout, done;
+  __ DoubleToI(result_reg, input_reg, xmm0,
+      instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);

-  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    // The integer converted back is equal to the original. We
-    // only have to test if we got -0 as an input.
-    __ testl(result_reg, result_reg);
-    __ j(not_zero, &done, Label::kNear);
-    __ movmskpd(result_reg, input_reg);
-    // Bit 0 contains the sign of the double in input_reg.
-    // If input was positive, we are ok and return 0, otherwise
-    // deoptimize.
-    __ andl(result_reg, Immediate(1));
-    DeoptimizeIf(not_zero, instr->environment());
-    __ bind(&done);
-  }
+  __ jmp(&done, Label::kNear);
+  __ bind(&bailout);
+  DeoptimizeIf(no_condition, instr->environment());
+  __ bind(&done);
+
   __ Integer32ToSmi(result_reg, result_reg);
   DeoptimizeIf(overflow, instr->environment());
 }
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Mon Sep 9 16:34:40 2013 UTC +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Tue Sep 10 12:37:30 2013 UTC
@@ -123,7 +123,7 @@
   // Deferred code support.
   void DoDeferredNumberTagD(LNumberTagD* instr);
   void DoDeferredNumberTagU(LNumberTagU* instr);
-  void DoDeferredTaggedToI(LTaggedToI* instr);
+  void DoDeferredTaggedToI(LTaggedToI* instr, Label* done);
   void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
   void DoDeferredStackCheck(LStackCheck* instr);
   void DoDeferredRandom(LRandom* instr);
@@ -430,6 +430,7 @@
   void SetExit(Label* exit) { external_exit_ = exit; }
   Label* entry() { return &entry_; }
Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; } + Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); }
   int instruction_index() const { return instruction_index_; }

  protected:
@@ -440,6 +441,7 @@
   LCodeGen* codegen_;
   Label entry_;
   Label exit_;
+  Label done_;
   Label* external_exit_;
   int instruction_index_;
 };
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu Aug 29 11:41:14 2013 UTC +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Tue Sep 10 12:37:30 2013 UTC
@@ -2990,6 +2990,117 @@
   }
   cvtqsi2sd(dst, src);
 }
+
+
+void MacroAssembler::SlowTruncateToI(Register result_reg,
+                                     Register input_reg,
+                                     int offset) {
+  DoubleToIStub stub(input_reg, result_reg, offset, true);
+  call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
+}
+
+
+void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
+                                           Register input_reg) {
+  Label done;
+  movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
+  cvttsd2siq(result_reg, xmm0);
+  Set(kScratchRegister, V8_UINT64_C(0x8000000000000000));
+  cmpq(result_reg, kScratchRegister);
+  j(not_equal, &done, Label::kNear);
+
+  // Slow case.
+  if (input_reg.is(result_reg)) {
+    subq(rsp, Immediate(kDoubleSize));
+    movsd(MemOperand(rsp, 0), xmm0);
+    SlowTruncateToI(result_reg, rsp, 0);
+    addq(rsp, Immediate(kDoubleSize));
+  } else {
+    SlowTruncateToI(result_reg, input_reg);
+  }
+
+  bind(&done);
+}
+
+
+void MacroAssembler::TruncateDoubleToI(Register result_reg,
+                                       XMMRegister input_reg) {
+  Label done;
+  cvttsd2siq(result_reg, input_reg);
+  movq(kScratchRegister,
+      V8_INT64_C(0x8000000000000000),
+      RelocInfo::NONE64);
+  cmpq(result_reg, kScratchRegister);
+  j(not_equal, &done, Label::kNear);
+
+  subq(rsp, Immediate(kDoubleSize));
+  movsd(MemOperand(rsp, 0), input_reg);
+  SlowTruncateToI(result_reg, rsp, 0);
+  addq(rsp, Immediate(kDoubleSize));
+
+  bind(&done);
+}
+
+
+void MacroAssembler::DoubleToI(Register result_reg,
+                               XMMRegister input_reg,
+                               XMMRegister scratch,
+                               MinusZeroMode minus_zero_mode,
+                               Label* conversion_failed,
+                               Label::Distance dst) {
+  cvttsd2si(result_reg, input_reg);
+  cvtlsi2sd(xmm0, result_reg);
+  ucomisd(xmm0, input_reg);
+  j(not_equal, conversion_failed, dst);
+  j(parity_even, conversion_failed, dst);  // NaN.
+  if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
+    Label done;
+    // The integer converted back is equal to the original. We
+    // only have to test if we got -0 as an input.
+    testl(result_reg, result_reg);
+    j(not_zero, &done, Label::kNear);
+    movmskpd(result_reg, input_reg);
+    // Bit 0 contains the sign of the double in input_reg.
+    // If input was positive, we are ok and return 0, otherwise
+    // jump to conversion_failed.
+    andl(result_reg, Immediate(1));
+    j(not_zero, conversion_failed, dst);
+    bind(&done);
+  }
+}
+
+
+void MacroAssembler::TaggedToI(Register result_reg,
+                               Register input_reg,
+                               XMMRegister temp,
+                               MinusZeroMode minus_zero_mode,
+                               Label* lost_precision,
+                               Label::Distance dst) {
+  Label done;
+  ASSERT(!temp.is(xmm0));
+
+  // Heap number map check.
+  CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
+              Heap::kHeapNumberMapRootIndex);
+  j(not_equal, lost_precision, dst);
+
+  movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
+  cvttsd2si(result_reg, xmm0);
+  cvtlsi2sd(temp, result_reg);
+  ucomisd(xmm0, temp);
+  RecordComment("Deferred TaggedToI: lost precision");
+  j(not_equal, lost_precision, dst);
+  RecordComment("Deferred TaggedToI: NaN");
+  j(parity_even, lost_precision, dst);  // NaN.
+  if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
+    testl(result_reg, result_reg);
+    j(not_zero, &done, Label::kNear);
+    movmskpd(result_reg, xmm0);
+    andl(result_reg, Immediate(1));
+    j(not_zero, lost_precision, dst);
+  }
+  bind(&done);
+}


 void MacroAssembler::LoadInstanceDescriptors(Register map,
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Thu Aug 29 11:41:14 2013 UTC +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Tue Sep 10 12:37:30 2013 UTC
@@ -975,6 +975,20 @@
                           XMMRegister temp_xmm_reg,
                           Register result_reg);

+  void SlowTruncateToI(Register result_reg, Register input_reg,
+      int offset = HeapNumber::kValueOffset - kHeapObjectTag);
+
+  void TruncateHeapNumberToI(Register result_reg, Register input_reg);
+  void TruncateDoubleToI(Register result_reg, XMMRegister input_reg);
+
+  void DoubleToI(Register result_reg, XMMRegister input_reg,
+      XMMRegister scratch, MinusZeroMode minus_zero_mode,
+      Label* conversion_failed, Label::Distance dst = Label::kFar);
+
+  void TaggedToI(Register result_reg, Register input_reg, XMMRegister temp,
+      MinusZeroMode minus_zero_mode, Label* lost_precision,
+      Label::Distance dst = Label::kFar);
+
   void LoadUint32(XMMRegister dst, Register src, XMMRegister scratch);

   void LoadInstanceDescriptors(Register map, Register descriptors);

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to