Revision: 6504
Author: [email protected]
Date: Wed Jan 26 12:25:33 2011
Log: ARM: Add multiplication to the type recording binary operation stub
Review URL: http://codereview.chromium.org/6391004
http://code.google.com/p/v8/source/detail?r=6504

Modified:
 /branches/bleeding_edge/src/arm/code-stubs-arm.cc
 /branches/bleeding_edge/src/arm/code-stubs-arm.h
 /branches/bleeding_edge/src/arm/full-codegen-arm.cc

=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Wed Jan 26 04:31:35 2011 +++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Wed Jan 26 12:25:33 2011
@@ -2434,13 +2434,17 @@
 }


-void TypeRecordingBinaryOpStub::GenerateOptimisticSmiOperation(
+void TypeRecordingBinaryOpStub::GenerateSmiSmiOperation(
     MacroAssembler* masm) {
   Register left = r1;
   Register right = r0;
+  Register scratch1 = r7;
+  Register scratch2 = r9;

   ASSERT(right.is(r0));
-
+  STATIC_ASSERT(kSmiTag == 0);
+
+  Label not_smi_result;
   switch (op_) {
     case Token::ADD:
       __ add(right, left, Operand(right), SetCC);  // Add optimistically.
@@ -2452,9 +2456,35 @@
       __ Ret(vc);
       __ sub(right, left, Operand(right));  // Revert optimistic subtract.
       break;
+    case Token::MUL:
+ // Remove tag from one of the operands. This way the multiplication result
+      // will be a smi if it fits the smi range.
+      __ SmiUntag(ip, right);
+      // Do multiplication
+      // scratch1 = lower 32 bits of ip * left.
+      // scratch2 = higher 32 bits of ip * left.
+      __ smull(scratch1, scratch2, left, ip);
+ // Check for overflowing the smi range - no overflow if higher 33 bits of
+      // the result are identical.
+      __ mov(ip, Operand(scratch1, ASR, 31));
+      __ cmp(ip, Operand(scratch2));
+      __ b(ne, &not_smi_result);
+      // Go slow on zero result to handle -0.
+      __ tst(scratch1, Operand(scratch1));
+      __ mov(right, Operand(scratch1), LeaveCC, ne);
+      __ Ret(ne);
+ // We need -0 if we were multiplying a negative number with 0 to get 0.
+      // We know one of them was zero.
+      __ add(scratch2, right, Operand(left), SetCC);
+      __ mov(right, Operand(Smi::FromInt(0)), LeaveCC, pl);
+      __ Ret(pl);  // Return smi 0 if the non-zero one was positive.
+ // We fall through here if we multiplied a negative number with 0, because
+      // that would mean we should produce -0.
+      break;
     default:
       UNREACHABLE();
   }
+  __ bind(&not_smi_result);
 }


@@ -2467,6 +2497,9 @@
     case Token::SUB:
       __ vsub(d5, d6, d7);
       break;
+    case Token::MUL:
+      __ vmul(d5, d6, d7);
+      break;
     default:
       UNREACHABLE();
   }
@@ -2482,7 +2515,7 @@
     SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
   Label not_smis;

-  ASSERT(op_ == Token::ADD || op_ == Token::SUB);
+  ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);

   Register left = r1;
   Register right = r0;
@@ -2495,7 +2528,7 @@
   __ tst(scratch1, Operand(kSmiTagMask));
   __ b(ne, &not_smis);

-  GenerateOptimisticSmiOperation(masm);
+  GenerateSmiSmiOperation(masm);

// If heap number results are possible generate the result in an allocated
   // heap number.
@@ -2563,7 +2596,7 @@
 void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
   Label not_smis, call_runtime;

-  ASSERT(op_ == Token::ADD || op_ == Token::SUB);
+  ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);

   if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
       result_type_ == TRBinaryOpIC::SMI) {
@@ -2595,7 +2628,7 @@


 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
-  ASSERT(op_ == Token::ADD || op_ == Token::SUB);
+  ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::SUB);

   ASSERT(operands_type_ == TRBinaryOpIC::INT32);

@@ -2604,7 +2637,7 @@


void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
-  ASSERT(op_ == Token::ADD || op_ == Token::SUB);
+  ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);

   Register scratch1 = r7;
   Register scratch2 = r9;
@@ -2684,7 +2717,7 @@


 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
-  ASSERT(op_ == Token::ADD || op_ == Token::SUB);
+  ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);

   Label call_runtime;

=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.h Tue Jan 25 23:41:02 2011 +++ /branches/bleeding_edge/src/arm/code-stubs-arm.h Wed Jan 26 12:25:33 2011
@@ -288,7 +288,7 @@

   void Generate(MacroAssembler* masm);
   void GenerateGeneric(MacroAssembler* masm);
-  void GenerateOptimisticSmiOperation(MacroAssembler* masm);
+  void GenerateSmiSmiOperation(MacroAssembler* masm);
   void GenerateVFPOperation(MacroAssembler* masm);
   void GenerateSmiCode(MacroAssembler* masm,
                        Label* gc_required,
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Jan 26 07:28:17 2011 +++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Jan 26 12:25:33 2011
@@ -1550,7 +1550,7 @@
 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
                                      OverwriteMode mode) {
   __ pop(r1);
-  if (op == Token::ADD || op == Token::SUB) {
+  if (op == Token::ADD || op == Token::SUB || op == Token::MUL) {
     TypeRecordingBinaryOpStub stub(op, mode);
     __ CallStub(&stub);
   } else {

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

Reply via email to