Revision: 11381
Author:   [email protected]
Date:     Thu Apr 19 00:19:33 2012
Log:      Fixed type transitions for mod on ia32.

Previously we got stuck in the int32 state, because this handled everything
without a type transition. Note that other platforms do not have this bug.

Review URL: https://chromiumcodereview.appspot.com/10083044
http://code.google.com/p/v8/source/detail?r=11381

Modified:
 /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc

=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Tue Apr 17 03:49:15 2012 +++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Apr 19 00:19:33 2012
@@ -1681,6 +1681,11 @@
 }


+// Input:
+//    edx: left operand (tagged)
+//    eax: right operand (tagged)
+// Output:
+//    eax: result (tagged)
 void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
   Label call_runtime;
   ASSERT(operands_type_ == BinaryOpIC::INT32);
@@ -1690,31 +1695,37 @@
     case Token::ADD:
     case Token::SUB:
     case Token::MUL:
-    case Token::DIV: {
+    case Token::DIV:
+    case Token::MOD: {
       Label not_floats;
       Label not_int32;
       if (CpuFeatures::IsSupported(SSE2)) {
         CpuFeatures::Scope use_sse2(SSE2);
         FloatingPointHelper::LoadSSE2Operands(masm, &not_floats);
FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, &not_int32, ecx);
-        switch (op_) {
-          case Token::ADD: __ addsd(xmm0, xmm1); break;
-          case Token::SUB: __ subsd(xmm0, xmm1); break;
-          case Token::MUL: __ mulsd(xmm0, xmm1); break;
-          case Token::DIV: __ divsd(xmm0, xmm1); break;
-          default: UNREACHABLE();
-        }
-        // Check result type if it is currently Int32.
-        if (result_type_ <= BinaryOpIC::INT32) {
-          __ cvttsd2si(ecx, Operand(xmm0));
-          __ cvtsi2sd(xmm2, ecx);
-          __ ucomisd(xmm0, xmm2);
-          __ j(not_zero, &not_int32);
-          __ j(carry, &not_int32);
-        }
-        GenerateHeapResultAllocation(masm, &call_runtime);
-        __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
-        __ ret(0);
+        if (op_ == Token::MOD) {
+          GenerateRegisterArgsPush(masm);
+          __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
+        } else {
+          switch (op_) {
+            case Token::ADD: __ addsd(xmm0, xmm1); break;
+            case Token::SUB: __ subsd(xmm0, xmm1); break;
+            case Token::MUL: __ mulsd(xmm0, xmm1); break;
+            case Token::DIV: __ divsd(xmm0, xmm1); break;
+            default: UNREACHABLE();
+          }
+          // Check result type if it is currently Int32.
+          if (result_type_ <= BinaryOpIC::INT32) {
+            __ cvttsd2si(ecx, Operand(xmm0));
+            __ cvtsi2sd(xmm2, ecx);
+            __ ucomisd(xmm0, xmm2);
+            __ j(not_zero, &not_int32);
+            __ j(carry, &not_int32);
+          }
+          GenerateHeapResultAllocation(masm, &call_runtime);
+          __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
+          __ ret(0);
+        }
       } else {  // SSE2 not available, use FPU.
         FloatingPointHelper::CheckFloatOperands(masm, &not_floats, ebx);
         FloatingPointHelper::LoadFloatOperands(
@@ -1722,20 +1733,25 @@
             ecx,
             FloatingPointHelper::ARGS_IN_REGISTERS);
         FloatingPointHelper::CheckFloatOperandsAreInt32(masm, &not_int32);
-        switch (op_) {
-          case Token::ADD: __ faddp(1); break;
-          case Token::SUB: __ fsubp(1); break;
-          case Token::MUL: __ fmulp(1); break;
-          case Token::DIV: __ fdivp(1); break;
-          default: UNREACHABLE();
-        }
-        Label after_alloc_failure;
-        GenerateHeapResultAllocation(masm, &after_alloc_failure);
-        __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
-        __ ret(0);
-        __ bind(&after_alloc_failure);
-        __ fstp(0);  // Pop FPU stack before calling runtime.
-        __ jmp(&call_runtime);
+        if (op_ == Token::MOD) {
+          GenerateRegisterArgsPush(masm);
+          __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
+        } else {
+          switch (op_) {
+            case Token::ADD: __ faddp(1); break;
+            case Token::SUB: __ fsubp(1); break;
+            case Token::MUL: __ fmulp(1); break;
+            case Token::DIV: __ fdivp(1); break;
+            default: UNREACHABLE();
+          }
+          Label after_alloc_failure;
+          GenerateHeapResultAllocation(masm, &after_alloc_failure);
+          __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
+          __ ret(0);
+          __ bind(&after_alloc_failure);
+          __ fstp(0);  // Pop FPU stack before calling runtime.
+          __ jmp(&call_runtime);
+        }
       }

       __ bind(&not_floats);
@@ -1744,10 +1760,6 @@
       break;
     }

-    case Token::MOD: {
-      // For MOD we go directly to runtime in the non-smi case.
-      break;
-    }
     case Token::BIT_OR:
     case Token::BIT_AND:
     case Token::BIT_XOR:
@@ -1758,11 +1770,6 @@
       Label not_floats;
       Label not_int32;
       Label non_smi_result;
-      /*  {
-        CpuFeatures::Scope use_sse2(SSE2);
-        FloatingPointHelper::LoadSSE2Operands(masm, &not_floats);
- FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, &not_int32, ecx);
-        }*/
       FloatingPointHelper::LoadUnknownsAsIntegers(masm,
                                                   use_sse3_,
                                                   &not_floats);
@@ -1833,8 +1840,8 @@
     default: UNREACHABLE(); break;
   }

-  // If an allocation fails, or SHR or MOD hit a hard case,
-  // use the runtime system to get the correct result.
+ // If an allocation fails, or SHR hits a hard case, use the runtime system to
+  // get the correct result.
   __ bind(&call_runtime);

   switch (op_) {
@@ -1855,8 +1862,6 @@
       __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION);
       break;
     case Token::MOD:
-      GenerateRegisterArgsPush(masm);
-      __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
       break;
     case Token::BIT_OR:
       __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION);

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to