Revision: 8397
Author:   [email protected]
Date:     Thu Jun 23 05:03:16 2011
Log:      Revert "ARM: Improve register allocation and constraints."

This reverts r8381.

It was causing Mozilla test mozilla/ecma/Date/15.9.3.8-5 to fail and Sputnik tests S15.9.3.1_A5_T5, S15.9.3.1_A5_T1, S15.9.3.1_A5_T2, S15.9.3.1_A5_T4, S15.9.3.1_A5_T3 and S15.9.3.1_A5_T6 to timeout.

[email protected]

BUG=none
TEST=mozilla/ecma/Date/15.9.3.8-5, S15.9.3.1_A5_T5, S15.9.3.1_A5_T1, S15.9.3.1_A5_T2, S15.9.3.1_A5_T4, S15.9.3.1_A5_T3 and S15.9.3.1_A5_T6

Review URL: http://codereview.chromium.org//7246004
http://code.google.com/p/v8/source/detail?r=8397

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

=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h     Wed Jun 22 12:49:31 2011
+++ /branches/bleeding_edge/src/arm/assembler-arm.h     Thu Jun 23 05:03:16 2011
@@ -167,14 +167,13 @@

 // Double word VFP register.
 struct DwVfpRegister {
+  // d0 has been excluded from allocation. This is following ia32
+  // where xmm0 is excluded. This should be revisited.
+  // Currently d0 is used as a scratch register.
+  // d1 has also been excluded from allocation to be used as a scratch
+  // register as well.
   static const int kNumRegisters = 16;
- // A few double registers are reserved: one as a scratch register and one to - // hold 0.0, that does not fit in the immediate field of vmov instructions.
-  //  d14: 0.0
-  //  d15: scratch register.
-  static const int kNumReservedRegisters = 2;
-  static const int kNumAllocatableRegisters = kNumRegisters -
-      kNumReservedRegisters;
+  static const int kNumAllocatableRegisters = 15;

   static int ToAllocationIndex(DwVfpRegister reg) {
     ASSERT(reg.code() != 0);
@@ -189,7 +188,6 @@
   static const char* AllocationIndexToString(int index) {
     ASSERT(index >= 0 && index < kNumAllocatableRegisters);
     const char* const names[] = {
-      "d0",
       "d1",
       "d2",
       "d3",
@@ -202,7 +200,9 @@
       "d10",
       "d11",
       "d12",
-      "d13"
+      "d13",
+      "d14",
+      "d15"
     };
     return names[index];
   }
@@ -306,7 +306,6 @@
 // Aliases for double registers.
 const DwVfpRegister kFirstCalleeSavedDoubleReg = d8;
 const DwVfpRegister kLastCalleeSavedDoubleReg = d15;
-const DwVfpRegister kDoubleRegZero = d14;


 // Coprocessor register
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Wed Jun 22 12:49:31 2011 +++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Thu Jun 23 05:03:16 2011
@@ -3541,8 +3541,6 @@
     CpuFeatures::Scope scope(VFP3);
     // Save callee-saved vfp registers.
__ vstm(db_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg);
-    // Set up the reserved register for 0.0.
-    __ vmov(kDoubleRegZero, 0.0);
   }

   // Get address of argv, see stm above.
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Wed Jun 22 12:49:31 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Thu Jun 23 05:03:16 2011
@@ -823,7 +823,7 @@

     LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
     LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
-    return DefineAsRegister(new LBitI(op, left, right));
+    return DefineSameAsFirst(new LBitI(op, left, right));
   } else {
     ASSERT(instr->representation().IsTagged());
     ASSERT(instr->left()->representation().IsTagged());
@@ -862,7 +862,7 @@
     right = chunk_->DefineConstantOperand(constant);
     constant_value = constant->Integer32Value() & 0x1f;
   } else {
-    right = UseRegisterAtStart(right_value);
+    right = UseRegister(right_value);
   }

   // Shift operations can only deoptimize if we do a logical shift
@@ -879,7 +879,7 @@
   }

   LInstruction* result =
-      DefineAsRegister(new LShiftI(op, left, right, does_deopt));
+      DefineSameAsFirst(new LShiftI(op, left, right, does_deopt));
   return does_deopt ? AssignEnvironment(result) : result;
 }

@@ -893,7 +893,7 @@
   LOperand* left = UseRegisterAtStart(instr->left());
   LOperand* right = UseRegisterAtStart(instr->right());
   LArithmeticD* result = new LArithmeticD(op, left, right);
-  return DefineAsRegister(result);
+  return DefineSameAsFirst(result);
 }


@@ -1237,15 +1237,15 @@
     LUnaryMathOperation* result = new LUnaryMathOperation(input, temp);
     switch (op) {
       case kMathAbs:
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); + return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
       case kMathFloor:
return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
       case kMathSqrt:
-        return DefineAsRegister(result);
+        return DefineSameAsFirst(result);
       case kMathRound:
         return AssignEnvironment(DefineAsRegister(result));
       case kMathPowHalf:
-        return DefineAsRegister(result);
+        return DefineSameAsFirst(result);
       default:
         UNREACHABLE();
         return NULL;
@@ -1323,7 +1323,7 @@
 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
   ASSERT(instr->value()->representation().IsInteger32());
   ASSERT(instr->representation().IsInteger32());
- return DefineAsRegister(new LBitNotI(UseRegisterAtStart(instr->value()))); + return DefineSameAsFirst(new LBitNotI(UseRegisterAtStart(instr->value())));
 }


@@ -1372,14 +1372,11 @@
       mod = new LModI(dividend,
                       divisor,
                       TempRegister(),
-                      FixedTemp(d10),
-                      FixedTemp(d11));
+                      FixedTemp(d1),
+                      FixedTemp(d2));
     }

-    bool needs_env = (instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
-                      instr->CheckFlag(HValue::kCanBeDivByZero));
-    return needs_env ? AssignEnvironment(DefineAsRegister(mod))
-                     : DefineAsRegister(mod);
+    return AssignEnvironment(DefineSameAsFirst(mod));
   } else if (instr->representation().IsTagged()) {
     return DoArithmeticT(Token::MOD, instr);
   } else {
@@ -1399,18 +1396,15 @@
   if (instr->representation().IsInteger32()) {
     ASSERT(instr->left()->representation().IsInteger32());
     ASSERT(instr->right()->representation().IsInteger32());
-    LOperand* left;
+    LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
     LOperand* right = UseOrConstant(instr->MostConstantOperand());
     LOperand* temp = NULL;
     if (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
         (instr->CheckFlag(HValue::kCanOverflow) ||
         !right->IsConstantOperand())) {
-      left = UseRegister(instr->LeastConstantOperand());
       temp = TempRegister();
-    } else {
-      left = UseRegisterAtStart(instr->LeastConstantOperand());
-    }
- return AssignEnvironment(DefineAsRegister(new LMulI(left, right, temp)));
+    }
+ return AssignEnvironment(DefineSameAsFirst(new LMulI(left, right, temp)));

   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::MUL, instr);
@@ -1428,7 +1422,7 @@
     LOperand* left = UseRegisterAtStart(instr->left());
     LOperand* right = UseOrConstantAtStart(instr->right());
     LSubI* sub = new LSubI(left, right);
-    LInstruction* result = DefineAsRegister(sub);
+    LInstruction* result = DefineSameAsFirst(sub);
     if (instr->CheckFlag(HValue::kCanOverflow)) {
       result = AssignEnvironment(result);
     }
@@ -1448,7 +1442,7 @@
     LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
     LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
     LAddI* add = new LAddI(left, right);
-    LInstruction* result = DefineAsRegister(add);
+    LInstruction* result = DefineSameAsFirst(add);
     if (instr->CheckFlag(HValue::kCanOverflow)) {
       result = AssignEnvironment(result);
     }
@@ -1614,7 +1608,7 @@
 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
   LOperand* object = UseRegister(instr->value());
   LValueOf* result = new LValueOf(object, TempRegister());
-  return AssignEnvironment(DefineAsRegister(result));
+  return AssignEnvironment(DefineSameAsFirst(result));
 }


@@ -1669,7 +1663,7 @@
         LOperand* temp1 = TempRegister();
         LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
                                                       : NULL;
-        LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d11)
+        LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d3)
                                                       : NULL;
res = DefineSameAsFirst(new LTaggedToI(value, temp1, temp2, temp3));
         res = AssignEnvironment(res);
@@ -1763,14 +1757,14 @@
   Representation input_rep = value->representation();
   LOperand* reg = UseRegister(value);
   if (input_rep.IsDouble()) {
-    return DefineAsRegister(new LClampDToUint8(reg, FixedTemp(d11)));
+    return DefineAsRegister(new LClampDToUint8(reg, FixedTemp(d1)));
   } else if (input_rep.IsInteger32()) {
     return DefineAsRegister(new LClampIToUint8(reg));
   } else {
     ASSERT(input_rep.IsTagged());
     // Register allocator doesn't (yet) support allocation of double
     // temps. Reserve d1 explicitly.
-    LClampTToUint8* result = new LClampTToUint8(reg, FixedTemp(d11));
+    LClampTToUint8* result = new LClampTToUint8(reg, FixedTemp(d1));
     return AssignEnvironment(DefineAsRegister(result));
   }
 }
@@ -1794,7 +1788,7 @@
     ASSERT(input_rep.IsTagged());
     LOperand* temp1 = TempRegister();
     LOperand* temp2 = TempRegister();
-    LOperand* temp3 = FixedTemp(d11);
+    LOperand* temp3 = FixedTemp(d3);
     LTaggedToI* res = new LTaggedToI(reg, temp1, temp2, temp3);
     return AssignEnvironment(DefineSameAsFirst(res));
   }
@@ -1932,7 +1926,7 @@
   LOperand* obj = UseRegisterAtStart(instr->object());
   LOperand* key = UseRegisterAtStart(instr->key());
   LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
-  return AssignEnvironment(DefineAsRegister(result));
+  return AssignEnvironment(DefineSameAsFirst(result));
 }


=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Jun 22 12:49:31 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Jun 23 05:03:16 2011
@@ -873,7 +873,6 @@
 void LCodeGen::DoModI(LModI* instr) {
   if (instr->hydrogen()->HasPowerOf2Divisor()) {
     Register dividend = ToRegister(instr->InputAt(0));
-    Register result = ToRegister(instr->result());

     int32_t divisor =
         HConstant::cast(instr->hydrogen()->right())->Integer32Value();
@@ -883,15 +882,17 @@
     Label positive_dividend, done;
     __ cmp(dividend, Operand(0));
     __ b(pl, &positive_dividend);
-    __ rsb(result, dividend, Operand(0));
-    __ and_(dividend, result, Operand(divisor - 1), SetCC);
+    __ rsb(dividend, dividend, Operand(0));
+    __ and_(dividend, dividend, Operand(divisor - 1));
+    __ rsb(dividend, dividend, Operand(0), SetCC);
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      DeoptimizeIf(eq, instr->environment());
-    }
-    __ rsb(result, dividend, Operand(0));
-    __ b(&done);
+      __ b(ne, &done);
+      DeoptimizeIf(al, instr->environment());
+    } else {
+      __ b(&done);
+    }
     __ bind(&positive_dividend);
-    __ and_(result, dividend, Operand(divisor - 1));
+    __ and_(dividend, dividend, Operand(divisor - 1));
     __ bind(&done);
     return;
   }
@@ -907,6 +908,8 @@
   DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2));
   DwVfpRegister quotient = double_scratch0();

+  ASSERT(result.is(left));
+
   ASSERT(!dividend.is(divisor));
   ASSERT(!dividend.is(quotient));
   ASSERT(!divisor.is(quotient));
@@ -921,8 +924,6 @@
     __ cmp(right, Operand(0));
     DeoptimizeIf(eq, instr->environment());
   }
-
-  __ Move(result, left);

   // (0 % x) must yield 0 (if x is finite, which is the case here).
   __ cmp(left, Operand(0));
@@ -1119,9 +1120,9 @@


 void LCodeGen::DoMulI(LMulI* instr) {
+  ASSERT(instr->result()->Equals(instr->InputAt(0)));
   Register scratch = scratch0();
   Register result = ToRegister(instr->result());
-  // Note that result may alias left.
   Register left = ToRegister(instr->InputAt(0));
   LOperand* right_op = instr->InputAt(1);

@@ -1154,7 +1155,7 @@
         __ mov(result, Operand(0));
         break;
       case 1:
-        __ Move(result, left);
+        // Nothing to do.
         break;
       default:
         // Multiplying by powers of two and powers of two plus or minus
@@ -1216,29 +1217,30 @@


 void LCodeGen::DoBitI(LBitI* instr) {
-  LOperand* left_op = instr->InputAt(0);
-  LOperand* right_op = instr->InputAt(1);
-  ASSERT(left_op->IsRegister());
-  Register left = ToRegister(left_op);
-  Register result = ToRegister(instr->result());
-  Operand right(no_reg);
-
-  if (right_op->IsStackSlot() || right_op->IsArgument()) {
-    right = Operand(EmitLoadRegister(right_op, ip));
+  LOperand* left = instr->InputAt(0);
+  LOperand* right = instr->InputAt(1);
+  ASSERT(left->Equals(instr->result()));
+  ASSERT(left->IsRegister());
+  Register result = ToRegister(left);
+  Operand right_operand(no_reg);
+
+  if (right->IsStackSlot() || right->IsArgument()) {
+    Register right_reg = EmitLoadRegister(right, ip);
+    right_operand = Operand(right_reg);
   } else {
-    ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
-    right = ToOperand(right_op);
+    ASSERT(right->IsRegister() || right->IsConstantOperand());
+    right_operand = ToOperand(right);
   }

   switch (instr->op()) {
     case Token::BIT_AND:
-      __ and_(result, left, right);
+      __ and_(result, ToRegister(left), right_operand);
       break;
     case Token::BIT_OR:
-      __ orr(result, left, right);
+      __ orr(result, ToRegister(left), right_operand);
       break;
     case Token::BIT_XOR:
-      __ eor(result, left, right);
+      __ eor(result, ToRegister(left), right_operand);
       break;
     default:
       UNREACHABLE();
@@ -1248,62 +1250,54 @@


 void LCodeGen::DoShiftI(LShiftI* instr) {
- // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so
-  // result may alias either of them.
-  LOperand* right_op = instr->InputAt(1);
-  Register left = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
   Register scratch = scratch0();
-  if (right_op->IsRegister()) {
-    // Mask the right_op operand.
-    __ and_(scratch, ToRegister(right_op), Operand(0x1F));
+  LOperand* left = instr->InputAt(0);
+  LOperand* right = instr->InputAt(1);
+  ASSERT(left->Equals(instr->result()));
+  ASSERT(left->IsRegister());
+  Register result = ToRegister(left);
+  if (right->IsRegister()) {
+    // Mask the right operand.
+    __ and_(scratch, ToRegister(right), Operand(0x1F));
     switch (instr->op()) {
       case Token::SAR:
-        __ mov(result, Operand(left, ASR, scratch));
+        __ mov(result, Operand(result, ASR, scratch));
         break;
       case Token::SHR:
         if (instr->can_deopt()) {
-          __ mov(result, Operand(left, LSR, scratch), SetCC);
+          __ mov(result, Operand(result, LSR, scratch), SetCC);
           DeoptimizeIf(mi, instr->environment());
         } else {
-          __ mov(result, Operand(left, LSR, scratch));
+          __ mov(result, Operand(result, LSR, scratch));
         }
         break;
       case Token::SHL:
-        __ mov(result, Operand(left, LSL, scratch));
+        __ mov(result, Operand(result, LSL, scratch));
         break;
       default:
         UNREACHABLE();
         break;
     }
   } else {
-    // Mask the right_op operand.
-    int value = ToInteger32(LConstantOperand::cast(right_op));
+    int value = ToInteger32(LConstantOperand::cast(right));
     uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
     switch (instr->op()) {
       case Token::SAR:
         if (shift_count != 0) {
-          __ mov(result, Operand(left, ASR, shift_count));
-        } else {
-          __ Move(result, left);
+          __ mov(result, Operand(result, ASR, shift_count));
         }
         break;
       case Token::SHR:
-        if (shift_count != 0) {
-          __ mov(result, Operand(left, LSR, shift_count));
+        if (shift_count == 0 && instr->can_deopt()) {
+          __ tst(result, Operand(0x80000000));
+          DeoptimizeIf(ne, instr->environment());
         } else {
-          if (instr->can_deopt()) {
-            __ tst(left, Operand(0x80000000));
-            DeoptimizeIf(ne, instr->environment());
-          }
-          __ Move(result, left);
+          __ mov(result, Operand(result, LSR, shift_count));
         }
         break;
       case Token::SHL:
         if (shift_count != 0) {
-          __ mov(result, Operand(left, LSL, shift_count));
-        } else {
-          __ Move(result, left);
+          __ mov(result, Operand(result, LSL, shift_count));
         }
         break;
       default:
@@ -1317,16 +1311,16 @@
 void LCodeGen::DoSubI(LSubI* instr) {
   LOperand* left = instr->InputAt(0);
   LOperand* right = instr->InputAt(1);
-  LOperand* result = instr->result();
+  ASSERT(left->Equals(instr->result()));
   bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
   SBit set_cond = can_overflow ? SetCC : LeaveCC;

   if (right->IsStackSlot() || right->IsArgument()) {
     Register right_reg = EmitLoadRegister(right, ip);
- __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); + __ sub(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond);
   } else {
     ASSERT(right->IsRegister() || right->IsConstantOperand());
- __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
+    __ sub(ToRegister(left), ToRegister(left), ToOperand(right), set_cond);
   }

   if (can_overflow) {
@@ -1345,7 +1339,7 @@
   ASSERT(instr->result()->IsDoubleRegister());
   DwVfpRegister result = ToDoubleRegister(instr->result());
   double v = instr->value();
-  __ Vmov(result, v);
+  __ vmov(result, v);
 }


@@ -1394,16 +1388,14 @@
   Register input = ToRegister(instr->InputAt(0));
   Register result = ToRegister(instr->result());
   Register map = ToRegister(instr->TempAt(0));
+  ASSERT(input.is(result));
   Label done;

   // If the object is a smi return the object.
-  __ tst(input, Operand(kSmiTagMask));
-  __ Move(result, input, eq);
-  __ b(eq, &done);
+  __ JumpIfSmi(input, &done);

   // If the object is not a value type, return the object.
   __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
-  __ Move(result, input, ne);
   __ b(ne, &done);
   __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset));

@@ -1412,9 +1404,9 @@


 void LCodeGen::DoBitNotI(LBitNotI* instr) {
-  Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
-  __ mvn(result, Operand(input));
+  LOperand* input = instr->InputAt(0);
+  ASSERT(input->Equals(instr->result()));
+  __ mvn(ToRegister(input), Operand(ToRegister(input)));
 }


@@ -1432,16 +1424,16 @@
 void LCodeGen::DoAddI(LAddI* instr) {
   LOperand* left = instr->InputAt(0);
   LOperand* right = instr->InputAt(1);
-  LOperand* result = instr->result();
+  ASSERT(left->Equals(instr->result()));
   bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
   SBit set_cond = can_overflow ? SetCC : LeaveCC;

   if (right->IsStackSlot() || right->IsArgument()) {
     Register right_reg = EmitLoadRegister(right, ip);
- __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); + __ add(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond);
   } else {
     ASSERT(right->IsRegister() || right->IsConstantOperand());
- __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond);
+    __ add(ToRegister(left), ToRegister(left), ToOperand(right), set_cond);
   }

   if (can_overflow) {
@@ -1453,19 +1445,18 @@
 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
   DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
   DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
-  DoubleRegister result = ToDoubleRegister(instr->result());
   switch (instr->op()) {
     case Token::ADD:
-      __ vadd(result, left, right);
+      __ vadd(left, left, right);
       break;
     case Token::SUB:
-      __ vsub(result, left, right);
+      __ vsub(left, left, right);
       break;
     case Token::MUL:
-      __ vmul(result, left, right);
+      __ vmul(left, left, right);
       break;
     case Token::DIV:
-      __ vdiv(result, left, right);
+      __ vdiv(left, left, right);
       break;
     case Token::MOD: {
       // Save r0-r3 on the stack.
@@ -1477,7 +1468,7 @@
           ExternalReference::double_fp_operation(Token::MOD, isolate()),
           0, 2);
       // Move the result in the double result register.
-      __ GetCFunctionDoubleResult(result);
+      __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result()));

       // Restore r0-r3.
       __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit());
@@ -1570,7 +1561,7 @@

       // Test double values. Zero and NaN are false.
       Label call_stub;
-      DoubleRegister dbl_scratch = double_scratch0();
+      DoubleRegister dbl_scratch = d0;
       Register scratch = scratch0();
       __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
       __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
@@ -2616,6 +2607,7 @@
   Register key = EmitLoadRegister(instr->key(), scratch0());
   Register result = ToRegister(instr->result());
   Register scratch = scratch0();
+  ASSERT(result.is(elements));

   // Load the result.
   __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
@@ -2935,8 +2927,8 @@


void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
+  ASSERT(instr->InputAt(0)->Equals(instr->result()));
   Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
   Register scratch = scratch0();

   // Deoptimize if not a heap number.
@@ -2950,10 +2942,10 @@
   scratch = no_reg;
   __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
   // Check the sign of the argument. If the argument is positive, just
-  // return it.
+  // return it. We do not need to patch the stack since |input| and
+  // |result| are the same register and |input| would be restored
+  // unchanged by popping safepoint registers.
   __ tst(exponent, Operand(HeapNumber::kSignMask));
-  // Move the input to the result if necessary.
-  __ Move(result, input);
   __ b(eq, &done);

   // Input is negative. Reverse its sign.
@@ -2993,7 +2985,7 @@
     __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
     __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));

-    __ StoreToSafepointRegisterSlot(tmp1, result);
+    __ StoreToSafepointRegisterSlot(tmp1, input);
   }

   __ bind(&done);
@@ -3002,13 +2994,11 @@

 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
   Register input = ToRegister(instr->InputAt(0));
-  Register result = ToRegister(instr->result());
   __ cmp(input, Operand(0));
-  __ Move(result, input, pl);
   // We can make rsb conditional because the previous cmp instruction
   // will clear the V (overflow) flag and rsb won't set this flag
   // if input is positive.
-  __ rsb(result, input, Operand(0), SetCC, mi);
+  __ rsb(input, input, Operand(0), SetCC, mi);
   // Deoptimize on overflow.
   DeoptimizeIf(vs, instr->environment());
 }
@@ -3028,11 +3018,11 @@
     LUnaryMathOperation* instr_;
   };

+  ASSERT(instr->InputAt(0)->Equals(instr->result()));
   Representation r = instr->hydrogen()->value()->representation();
   if (r.IsDouble()) {
     DwVfpRegister input = ToDoubleRegister(instr->InputAt(0));
-    DwVfpRegister result = ToDoubleRegister(instr->result());
-    __ vabs(result, input);
+    __ vabs(input, input);
   } else if (r.IsInteger32()) {
     EmitIntegerMathAbs(instr);
   } else {
@@ -3110,7 +3100,7 @@
   // Save the original sign for later comparison.
   __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask));

-  __ Vmov(double_scratch0(), 0.5);
+  __ vmov(double_scratch0(), 0.5);
   __ vadd(input, input, double_scratch0());

   // Check sign of the result: if the sign changed, the input
@@ -3147,17 +3137,24 @@

 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
   DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
-  DoubleRegister result = ToDoubleRegister(instr->result());
-  __ vsqrt(result, input);
+  ASSERT(ToDoubleRegister(instr->result()).is(input));
+  __ vsqrt(input, input);
 }


 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
   DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
-  DoubleRegister result = ToDoubleRegister(instr->result());
+  Register scratch = scratch0();
+  SwVfpRegister single_scratch = double_scratch0().low();
+  DoubleRegister double_scratch = double_scratch0();
+  ASSERT(ToDoubleRegister(instr->result()).is(input));
+
   // Add +0 to convert -0 to +0.
-  __ vadd(result, input, kDoubleRegZero);
-  __ vsqrt(result, result);
+  __ mov(scratch, Operand(0));
+  __ vmov(single_scratch, scratch);
+  __ vcvt_f64_s32(double_scratch, single_scratch);
+  __ vadd(input, input, double_scratch);
+  __ vsqrt(input, input);
 }


@@ -3756,8 +3753,8 @@
 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
   Label slow;
   Register reg = ToRegister(instr->InputAt(0));
-  DoubleRegister dbl_scratch = double_scratch0();
-  SwVfpRegister flt_scratch = dbl_scratch.low();
+  DoubleRegister dbl_scratch = d0;
+  SwVfpRegister flt_scratch = s0;

   // Preserve the value of all registers.
   PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
@@ -3866,8 +3863,8 @@
                                 bool deoptimize_on_undefined,
                                 LEnvironment* env) {
   Register scratch = scratch0();
-  SwVfpRegister flt_scratch = double_scratch0().low();
-  ASSERT(!result_reg.is(double_scratch0()));
+  SwVfpRegister flt_scratch = s0;
+  ASSERT(!result_reg.is(d0));

   Label load_smi, heap_number, done;

=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Wed Jun 22 12:49:31 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Thu Jun 23 05:03:16 2011
@@ -148,7 +148,7 @@
   HGraph* graph() const { return chunk_->graph(); }

   Register scratch0() { return r9; }
-  DwVfpRegister double_scratch0() { return d15; }
+  DwVfpRegister double_scratch0() { return d0; }

   int GetNextEmittedBlock(int block);
   LInstruction* GetNextInstruction();
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Wed Jun 22 12:49:31 2011 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Thu Jun 23 05:03:16 2011
@@ -309,9 +309,9 @@
 }


-void MacroAssembler::Move(Register dst, Register src, Condition cond) {
+void MacroAssembler::Move(Register dst, Register src) {
   if (!dst.is(src)) {
-    mov(dst, src, LeaveCC, cond);
+    mov(dst, src);
   }
 }

@@ -755,23 +755,6 @@
   vmrs(fpscr_flags, cond);
 }

-void MacroAssembler::Vmov(const DwVfpRegister dst,
-                          const double imm,
-                          const Condition cond) {
-  ASSERT(CpuFeatures::IsEnabled(VFP3));
-  static const DoubleRepresentation minus_zero(-0.0);
-  static const DoubleRepresentation zero(0.0);
-  DoubleRepresentation value(imm);
-  // Handle special values first.
-  if (value.bits == zero.bits) {
-    vmov(dst, kDoubleRegZero, cond);
-  } else if (value.bits == minus_zero.bits) {
-    vneg(dst, kDoubleRegZero, cond);
-  } else {
-    vmov(dst, imm, cond);
-  }
-}
-

 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   // r0-r3: preserved
@@ -3129,7 +3112,7 @@
   Label done;
   Label in_bounds;

-  Vmov(temp_double_reg, 0.0);
+  vmov(temp_double_reg, 0.0);
   VFPCompareAndSetFlags(input_reg, temp_double_reg);
   b(gt, &above_zero);

@@ -3139,7 +3122,7 @@

   // Double value is >= 255, return 255.
   bind(&above_zero);
-  Vmov(temp_double_reg, 255.0);
+  vmov(temp_double_reg, 255.0);
   VFPCompareAndSetFlags(input_reg, temp_double_reg);
   b(le, &in_bounds);
   mov(result_reg, Operand(255));
@@ -3147,7 +3130,7 @@

   // In 0-255 range, round and truncate.
   bind(&in_bounds);
-  Vmov(temp_double_reg, 0.5);
+  vmov(temp_double_reg, 0.5);
   vadd(temp_double_reg, input_reg, temp_double_reg);
   vcvt_u32_f64(s0, temp_double_reg);
   vmov(result_reg, s0);
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Wed Jun 22 12:49:31 2011 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Thu Jun 23 05:03:16 2011
@@ -143,7 +143,7 @@

   // Register move. May do nothing if the registers are identical.
   void Move(Register dst, Handle<Object> value);
-  void Move(Register dst, Register src, Condition cond = al);
+  void Move(Register dst, Register src);
   void Move(DoubleRegister dst, DoubleRegister src);

   // Load an object from the root table.
@@ -312,10 +312,6 @@
                               const Register fpscr_flags,
                               const Condition cond = al);

-  void Vmov(const DwVfpRegister dst,
-            const double imm,
-            const Condition cond = al);
-

// ---------------------------------------------------------------------------
   // Activation frames

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

Reply via email to