Revision: 3708
Author: [email protected]
Date: Tue Jan 26 02:27:27 2010
Log: Support register arguments in more cases.
1. MUL and DIV on SMIs.
2. When calling GenericBinaryOpStub from a virtual frame.
3. When generating code for a loop counter.
Overall performance gain is about 0.6%.
Review URL: http://codereview.chromium.org/555098
http://code.google.com/p/v8/source/detail?r=3708

Modified:
 /branches/bleeding_edge/src/ia32/codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/codegen-ia32.h
 /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc

=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Jan 25 09:47:53 2010 +++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Tue Jan 26 02:27:27 2010
@@ -763,10 +763,8 @@
                                 ArgLocation arg_location = ARGS_ON_STACK);

   // Similar to LoadFloatOperand but assumes that both operands are smis.
-  // Accepts operands on stack or in eax, ebx.
-  static void LoadFloatSmis(MacroAssembler* masm,
-                            Register scratch,
-                            ArgLocation arg_location);
+  // Accepts operands in eax, ebx.
+  static void LoadFloatSmis(MacroAssembler* masm, Register scratch);

   // Test if operands are smi or number objects (fp). Requirements:
   // operand_1 in eax, operand_2 in edx; falls through on float
@@ -786,10 +784,8 @@
   static void LoadSse2Operands(MacroAssembler* masm, Label* not_numbers);

   // Similar to LoadSse2Operands but assumes that both operands are smis.
-  // Accepts operands on stack or in eax, ebx.
-  static void LoadSse2Smis(MacroAssembler* masm,
-                           Register scratch,
-                           ArgLocation arg_location);
+  // Accepts operands in eax, ebx.
+  static void LoadSse2Smis(MacroAssembler* masm, Register scratch);
 };


@@ -978,10 +974,8 @@
   Result answer;
   if (left_is_non_smi || right_is_non_smi) {
     // Go straight to the slow case, with no smi code.
-    frame_->Push(&left);
-    frame_->Push(&right);
     GenericBinaryOpStub stub(op, overwrite_mode, NO_SMI_CODE_IN_STUB);
-    answer = frame_->CallStub(&stub, 2);
+    answer = stub.GenerateCall(masm_, frame_, &left, &right);
   } else if (right_is_smi) {
     answer = ConstantSmiBinaryOperation(op, &left, right.handle(),
                                         type, false, overwrite_mode);
@@ -997,10 +991,8 @@
if (loop_nesting() > 0 && (Token::IsBitOp(op) || type->IsLikelySmi())) {
       answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode);
     } else {
-      frame_->Push(&left);
-      frame_->Push(&right);
GenericBinaryOpStub stub(op, overwrite_mode, NO_GENERIC_BINARY_FLAGS);
-      answer = frame_->CallStub(&stub, 2);
+      answer = stub.GenerateCall(masm_, frame_, &left, &right);
     }
   }
   frame_->Push(&answer);
@@ -7074,6 +7066,21 @@
   // Call the stub.
   __ CallStub(this);
 }
+
+
+Result GenericBinaryOpStub::GenerateCall(MacroAssembler* masm,
+                                         VirtualFrame* frame,
+                                         Result* left,
+                                         Result* right) {
+  if (ArgsInRegistersSupported()) {
+    SetArgsInRegisters();
+    return frame->CallStub(this, left, right);
+  } else {
+    frame->Push(left);
+    frame->Push(right);
+    return frame->CallStub(this, 2);
+  }
+}


void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) {
@@ -7107,7 +7114,13 @@
       __ j(overflow, &not_smis_or_overflow, not_taken);
       break;

+    case Token::MUL:
+      __ mov(edi, eax);  // Backup the left operand.
+      break;
+
     case Token::DIV:
+      __ mov(edi, eax);  // Backup the left operand.
+      // Fall through.
     case Token::MOD:
       // Sign extend eax into edx:eax.
       __ cdq();
@@ -7243,28 +7256,18 @@
   __ bind(&use_fp_on_smis);
// Both operands are known to be SMIs but the result does not fit into a SMI.
   switch (op_) {
-    case Token::ADD:
-    case Token::SUB:
     case Token::MUL:
-    case Token::DIV: {
+    case Token::DIV:
+      __ mov(eax, edi);  // Restore the left operand.
+      // Fall through.
+    case Token::ADD:
+    case Token::SUB: {
       Label after_alloc_failure;
-
-      FloatingPointHelper::ArgLocation arg_location =
-          (op_ == Token::ADD || op_ == Token::SUB) ?
-          FloatingPointHelper::ARGS_IN_REGISTERS :
-          FloatingPointHelper::ARGS_ON_STACK;
-
-      __ AllocateHeapNumber(
-          edx,
-          ecx,
-          no_reg,
-          arg_location == FloatingPointHelper::ARGS_IN_REGISTERS ?
-              &after_alloc_failure :
-              slow);
+      __ AllocateHeapNumber(edx, ecx, no_reg, &after_alloc_failure);

       if (CpuFeatures::IsSupported(SSE2)) {
         CpuFeatures::Scope use_sse2(SSE2);
-        FloatingPointHelper::LoadSse2Smis(masm, ecx, arg_location);
+        FloatingPointHelper::LoadSse2Smis(masm, ecx);
         switch (op_) {
           case Token::ADD: __ addsd(xmm0, xmm1); break;
           case Token::SUB: __ subsd(xmm0, xmm1); break;
@@ -7274,7 +7277,7 @@
         }
         __ movdbl(FieldOperand(edx, HeapNumber::kValueOffset), xmm0);
       } else {  // SSE2 not available, use FPU.
-        FloatingPointHelper::LoadFloatSmis(masm, ecx, arg_location);
+        FloatingPointHelper::LoadFloatSmis(masm, ecx);
         switch (op_) {
           case Token::ADD: __ faddp(1); break;
           case Token::SUB: __ fsubp(1); break;
@@ -7287,12 +7290,10 @@
       __ mov(eax, edx);
       GenerateReturn(masm);

-      if (arg_location == FloatingPointHelper::ARGS_IN_REGISTERS) {
-        __ bind(&after_alloc_failure);
-        __ mov(edx, eax);
-        __ mov(eax, ebx);
-        __ jmp(slow);
-      }
+      __ bind(&after_alloc_failure);
+      __ mov(edx, eax);
+      __ mov(eax, ebx);
+      __ jmp(slow);
       break;
     }

@@ -7438,7 +7439,7 @@
         __ bind(&non_smi_result);
         // Allocate a heap number if needed.
         __ mov(ebx, Operand(eax));  // ebx: result
-       Label skip_allocation;
+        Label skip_allocation;
         switch (mode_) {
           case OVERWRITE_LEFT:
           case OVERWRITE_RIGHT:
@@ -7881,22 +7882,12 @@


 void FloatingPointHelper::LoadSse2Smis(MacroAssembler* masm,
-                                       Register scratch,
-                                       ArgLocation arg_location) {
-  if (arg_location == ARGS_IN_REGISTERS) {
-    __ mov(scratch, eax);
-  } else {
-    __ mov(scratch, Operand(esp, 2 * kPointerSize));
-  }
+                                       Register scratch) {
+  __ mov(scratch, eax);
   __ SmiUntag(scratch);  // Untag smi before converting to float.
   __ cvtsi2sd(xmm0, Operand(scratch));

-
-  if (arg_location == ARGS_IN_REGISTERS) {
-    __ mov(scratch, ebx);
-  } else {
-    __ mov(scratch, Operand(esp, 1 * kPointerSize));
-  }
+  __ mov(scratch, ebx);
   __ SmiUntag(scratch);  // Untag smi before converting to float.
   __ cvtsi2sd(xmm1, Operand(scratch));
 }
@@ -7944,23 +7935,14 @@


 void FloatingPointHelper::LoadFloatSmis(MacroAssembler* masm,
-                                        Register scratch,
-                                        ArgLocation arg_location) {
-  if (arg_location == ARGS_IN_REGISTERS) {
-    __ mov(scratch, eax);
-  } else {
-    __ mov(scratch, Operand(esp, 2 * kPointerSize));
-  }
+                                        Register scratch) {
+  __ mov(scratch, eax);
   __ SmiUntag(scratch);
   __ push(scratch);
   __ fild_s(Operand(esp, 0));
   __ pop(scratch);

-  if (arg_location == ARGS_IN_REGISTERS) {
-    __ mov(scratch, ebx);
-  } else {
-    __ mov(scratch, Operand(esp, 1 * kPointerSize));
-  }
+  __ mov(scratch, ebx);
   __ SmiUntag(scratch);
   __ push(scratch);
   __ fild_s(Operand(esp, 0));
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.h     Mon Jan 25 09:47:53 2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.h     Tue Jan 26 02:27:27 2010
@@ -652,6 +652,11 @@
   void GenerateCall(MacroAssembler* masm, Register left, Smi* right);
   void GenerateCall(MacroAssembler* masm, Smi* left, Register right);

+  Result GenerateCall(MacroAssembler* masm,
+                      VirtualFrame* frame,
+                      Result* left,
+                      Result* right);
+
  private:
   Token::Value op_;
   OverwriteMode mode_;
@@ -700,15 +705,9 @@
   void GenerateReturn(MacroAssembler* masm);
void GenerateHeapResultAllocation(MacroAssembler* masm, Label* alloc_failure);

- // Args in registers are always OK for ADD and SUB. Floating-point MUL and DIV - // are also OK. Though MUL and DIV on SMIs modify the original registers so
-  // we need to push args on stack anyway.
   bool ArgsInRegistersSupported() {
-    if (op_ == Token::ADD || op_ == Token::SUB) return true;
-    if (op_ == Token::MUL || op_ == Token::DIV) {
-      return flags_ == NO_SMI_CODE_IN_STUB;
-    }
-    return false;
+    return op_ == Token::ADD || op_ == Token::SUB
+        || op_ == Token::MUL || op_ == Token::DIV;
   }
   bool IsOperationCommutative() {
     return (op_ == Token::ADD) || (op_ == Token::MUL);
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Fri Jan 22 06:07:25 2010 +++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Tue Jan 26 02:27:27 2010
@@ -1560,12 +1560,10 @@
     }
   }
   // Call stub for +1/-1.
-  __ push(eax);
-  __ push(Immediate(Smi::FromInt(1)));
   GenericBinaryOpStub stub(expr->binary_op(),
                            NO_OVERWRITE,
                            NO_GENERIC_BINARY_FLAGS);
-  __ CallStub(&stub);
+  stub.GenerateCall(masm(), eax, Smi::FromInt(1));
   __ bind(&done);

   // Store the value returned in eax.

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

Reply via email to