ARM: Add subtract to the type recording binary operation stub.
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 26 Jan 2011 07:41:02 +0000 (07:41 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 26 Jan 2011 07:41:02 +0000 (07:41 +0000)
Review URL: http://codereview.chromium.org/6324013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6476 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/code-stubs-arm.cc
src/arm/code-stubs-arm.h
src/arm/full-codegen-arm.cc

index b32bc1425cfbd62794d2709c994e6746f8b990d5..b3d1652b97ae81f2b2761dc6b349796aefd22a0d 100644 (file)
@@ -2433,6 +2433,46 @@ const char* TypeRecordingBinaryOpStub::GetName() {
 }
 
 
+void TypeRecordingBinaryOpStub::GenerateOptimisticSmiOperation(
+    MacroAssembler* masm) {
+  Register left = r1;
+  Register right = r0;
+
+  ASSERT(right.is(r0));
+
+  switch (op_) {
+    case Token::ADD:
+      __ add(right, left, Operand(right), SetCC); // Add optimistically.
+      __ Ret(vc);
+      __ sub(right, right, Operand(left));  // Revert optimistic add.
+      break;
+    case Token::SUB:
+      __ sub(right, left, Operand(right), SetCC);  // Subtract optimistically.
+      __ Ret(vc);
+      __ sub(right, left, Operand(right));  // Revert optimistic subtract.
+      break;
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+void TypeRecordingBinaryOpStub::GenerateVFPOperation(
+    MacroAssembler* masm) {
+  switch (op_) {
+    case Token::ADD:
+      __ vadd(d5, d6, d7);
+      break;
+    case Token::SUB:
+      __ vsub(d5, d6, d7);
+      break;
+    default:
+      UNREACHABLE();
+  }
+
+}
+
+
 // Generate the smi code. If the operation on smis are successful this return is
 // generated. If the result is not a smi and heap number allocation is not
 // requested the code falls through. If number allocation is requested but a
@@ -2442,7 +2482,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
     SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
   Label not_smis;
 
-  ASSERT(op_ == Token::ADD);
+  ASSERT(op_ == Token::ADD || op_ == Token::SUB);
 
   Register left = r1;
   Register right = r0;
@@ -2455,14 +2495,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
   __ tst(scratch1, Operand(kSmiTagMask));
   __ b(ne, &not_smis);
 
-  __ add(right, right, Operand(left), SetCC);  // Add optimistically.
-
-  // Return smi result if no overflow (r0 is the result).
-  ASSERT(right.is(r0));
-  __ Ret(vc);
-
-  // Result is not a smi. Revert the optimistic add.
-  __ sub(right, right, Operand(left));
+  GenerateOptimisticSmiOperation(masm);
 
   // If heap number results are possible generate the result in an allocated
   // heap number.
@@ -2489,7 +2522,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
       // d6: Left value
       // d7: Right value
       CpuFeatures::Scope scope(VFP3);
-      __ vadd(d5, d6, d7);
+      GenerateVFPOperation(masm);
 
       __ sub(r0, heap_number, Operand(kHeapObjectTag));
       __ vstr(d5, r0, HeapNumber::kValueOffset);
@@ -2530,7 +2563,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
 void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
   Label not_smis, call_runtime;
 
-  ASSERT(op_ == Token::ADD);
+  ASSERT(op_ == Token::ADD || op_ == Token::SUB);
 
   if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
       result_type_ == TRBinaryOpIC::SMI) {
@@ -2562,7 +2595,7 @@ void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
 
 
 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
-  ASSERT(op_ == Token::ADD);
+  ASSERT(op_ == Token::ADD || op_ == Token::SUB);
 
   ASSERT(operands_type_ == TRBinaryOpIC::INT32);
 
@@ -2571,7 +2604,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
 
 
 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
-  ASSERT(op_ == Token::ADD);
+  ASSERT(op_ == Token::ADD || op_ == Token::SUB);
 
   Register scratch1 = r7;
   Register scratch2 = r9;
@@ -2597,7 +2630,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
   if (destination == FloatingPointHelper::kVFPRegisters) {
     // Use floating point instructions for the binary operation.
     CpuFeatures::Scope scope(VFP3);
-    __ vadd(d5, d6, d7);
+    GenerateVFPOperation(masm);
 
     // Get a heap number object for the result - might be left or right if one
     // of these are overwritable.
@@ -2651,7 +2684,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
 
 
 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
-  ASSERT(op_ == Token::ADD);
+  ASSERT(op_ == Token::ADD || op_ == Token::SUB);
 
   Label call_runtime;
 
@@ -2695,11 +2728,14 @@ void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
 
 
 void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
+  GenerateRegisterArgsPush(masm);
   switch (op_) {
     case Token::ADD:
-      GenerateRegisterArgsPush(masm);
       __ InvokeBuiltin(Builtins::ADD, JUMP_JS);
       break;
+    case Token::SUB:
+      __ InvokeBuiltin(Builtins::SUB, JUMP_JS);
+      break;
     default:
       UNREACHABLE();
   }
index 785cbbc8685ad58a00e222076f2dd5943ad48b0c..4954e79a6898ae728bf7e9b731dc030429465dbb 100644 (file)
@@ -288,6 +288,8 @@ class TypeRecordingBinaryOpStub: public CodeStub {
 
   void Generate(MacroAssembler* masm);
   void GenerateGeneric(MacroAssembler* masm);
+  void GenerateOptimisticSmiOperation(MacroAssembler* masm);
+  void GenerateVFPOperation(MacroAssembler* masm);
   void GenerateSmiCode(MacroAssembler* masm,
                        Label* gc_required,
                        SmiCodeGenerateHeapNumberResults heapnumber_results);
index 8d4d0cea60de5c9c5963c3c4e12c3ae570aaf8ba..79fb9887584b946ed39e9441fe68f50b897c67d9 100644 (file)
@@ -1548,7 +1548,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,
 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
                                      OverwriteMode mode) {
   __ pop(r1);
-  if (op == Token::ADD) {
+  if (op == Token::ADD || op == Token::SUB) {
     TypeRecordingBinaryOpStub stub(op, mode);
     __ CallStub(&stub);
   } else {