Revision: 24862
Author:   [email protected]
Date:     Fri Oct 24 09:36:40 2014 UTC
Log:      [x86] Fix register constraints for multiply-high.

TEST=mjsunit/compiler,unittests
[email protected]

Review URL: https://codereview.chromium.org/671393002
https://code.google.com/p/v8/source/detail?r=24862

Added:
 /branches/bleeding_edge/test/mjsunit/compiler/regress-register-allocator.js
Modified:
 /branches/bleeding_edge/src/compiler/ia32/instruction-selector-ia32.cc
 /branches/bleeding_edge/src/compiler/instruction.h
 /branches/bleeding_edge/src/compiler/x64/instruction-selector-x64.cc
/branches/bleeding_edge/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc /branches/bleeding_edge/test/unittests/compiler/instruction-selector-unittest.cc /branches/bleeding_edge/test/unittests/compiler/instruction-selector-unittest.h /branches/bleeding_edge/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/compiler/regress-register-allocator.js Fri Oct 24 09:36:40 2014 UTC
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, buffer) {
+  "use asm";
+  var HEAP32 = new stdlib.Int32Array(buffer);
+  function g(a) {
+    HEAP32[a] = 9982 * 100;
+    return a;
+  }
+  function f(i1) {
+    i1 = i1 | 0;
+    var i2 = HEAP32[i1 >> 2] | 0;
+    g(i1);
+    L2909: {
+      L2: {
+        if (0) {
+          if (0) break L2;
+          g(i2);
+          break L2909;
+        }
+      }
+      var r = (HEAP32[1] | 0) / 100 | 0;
+      g(r);
+      return r;
+    }
+  }
+  return {f: f};
+}
+
+var f = Module(this, {}, new ArrayBuffer(64 * 1024)).f;
+assertEquals(9982, f(1));
=======================================
--- /branches/bleeding_edge/src/compiler/ia32/instruction-selector-ia32.cc Thu Oct 23 10:22:06 2014 UTC +++ /branches/bleeding_edge/src/compiler/ia32/instruction-selector-ia32.cc Fri Oct 24 09:36:40 2014 UTC
@@ -469,10 +469,9 @@
 void InstructionSelector::VisitInt32MulHigh(Node* node) {
   IA32OperandGenerator g(this);
   InstructionOperand* temps[] = {g.TempRegister(eax)};
-  size_t temp_count = arraysize(temps);
   Emit(kIA32ImulHigh, g.DefineAsFixed(node, edx),
-       g.UseFixed(node->InputAt(0), eax), g.UseRegister(node->InputAt(1)),
-       temp_count, temps);
+ g.UseFixed(node->InputAt(0), eax), g.UseUniqueRegister(node->InputAt(1)),
+       arraysize(temps), temps);
 }


=======================================
--- /branches/bleeding_edge/src/compiler/instruction.h Wed Oct 22 11:24:55 2014 UTC +++ /branches/bleeding_edge/src/compiler/instruction.h Fri Oct 24 09:36:40 2014 UTC
@@ -257,7 +257,7 @@
   }

   // [lifetime]: Only for non-FIXED_SLOT.
-  bool IsUsedAtStart() {
+  bool IsUsedAtStart() const {
     DCHECK(basic_policy() == EXTENDED_POLICY);
     return LifetimeField::decode(value_) == USED_AT_START;
   }
=======================================
--- /branches/bleeding_edge/src/compiler/x64/instruction-selector-x64.cc Thu Oct 23 10:22:06 2014 UTC +++ /branches/bleeding_edge/src/compiler/x64/instruction-selector-x64.cc Fri Oct 24 09:36:40 2014 UTC
@@ -560,10 +560,9 @@
 void InstructionSelector::VisitInt32MulHigh(Node* node) {
   X64OperandGenerator g(this);
   InstructionOperand* temps[] = {g.TempRegister(rax)};
-  size_t temp_count = arraysize(temps);
   Emit(kX64ImulHigh32, g.DefineAsFixed(node, rdx),
-       g.UseFixed(node->InputAt(0), rax), g.UseRegister(node->InputAt(1)),
-       temp_count, temps);
+ g.UseFixed(node->InputAt(0), rax), g.UseUniqueRegister(node->InputAt(1)),
+       arraysize(temps), temps);
 }


=======================================
--- /branches/bleeding_edge/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc Tue Oct 14 11:57:06 2014 UTC +++ /branches/bleeding_edge/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc Fri Oct 24 09:36:40 2014 UTC
@@ -593,9 +593,12 @@
   EXPECT_EQ(kIA32ImulHigh, s[0]->arch_opcode());
   ASSERT_EQ(2U, s[0]->InputCount());
   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), eax));
   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1)));
   ASSERT_EQ(1U, s[0]->OutputCount());
   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), edx));
 }

 }  // namespace compiler
=======================================
--- /branches/bleeding_edge/test/unittests/compiler/instruction-selector-unittest.cc Tue Oct 21 14:44:50 2014 UTC +++ /branches/bleeding_edge/test/unittests/compiler/instruction-selector-unittest.cc Fri Oct 24 09:36:40 2014 UTC
@@ -127,6 +127,24 @@
   CHECK(i != virtual_registers_.end());
   return i->second;
 }
+
+
+bool InstructionSelectorTest::Stream::IsFixed(const InstructionOperand* operand,
+                                              Register reg) const {
+  if (!operand->IsUnallocated()) return false;
+ const UnallocatedOperand* unallocated = UnallocatedOperand::cast(operand);
+  if (!unallocated->HasFixedRegisterPolicy()) return false;
+  const int index = Register::ToAllocationIndex(reg);
+  return unallocated->fixed_register_index() == index;
+}
+
+
+bool InstructionSelectorTest::Stream::IsUsedAtStart(
+    const InstructionOperand* operand) const {
+  if (!operand->IsUnallocated()) return false;
+ const UnallocatedOperand* unallocated = UnallocatedOperand::cast(operand);
+  return unallocated->IsUsedAtStart();
+}


// -----------------------------------------------------------------------------
=======================================
--- /branches/bleeding_edge/test/unittests/compiler/instruction-selector-unittest.h Wed Oct 8 08:47:29 2014 UTC +++ /branches/bleeding_edge/test/unittests/compiler/instruction-selector-unittest.h Fri Oct 24 09:36:40 2014 UTC
@@ -170,6 +170,9 @@

     int ToVreg(const Node* node) const;

+    bool IsFixed(const InstructionOperand* operand, Register reg) const;
+    bool IsUsedAtStart(const InstructionOperand* operand) const;
+
     FrameStateDescriptor* GetFrameStateDescriptor(int deoptimization_id) {
       EXPECT_LT(deoptimization_id, GetFrameStateDescriptorCount());
       return deoptimization_entries_[deoptimization_id];
=======================================
--- /branches/bleeding_edge/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc Tue Oct 14 11:57:06 2014 UTC +++ /branches/bleeding_edge/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc Fri Oct 24 09:36:40 2014 UTC
@@ -510,9 +510,12 @@
   EXPECT_EQ(kX64ImulHigh32, s[0]->arch_opcode());
   ASSERT_EQ(2U, s[0]->InputCount());
   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), rax));
   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1)));
   ASSERT_EQ(1U, s[0]->OutputCount());
   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), rdx));
 }

 }  // namespace compiler

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to