[turbofan] Add Uint64LessThanOrEqual to 64-bit TurboFan backends.
authortitzer <titzer@chromium.org>
Fri, 3 Jul 2015 05:13:57 +0000 (22:13 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 3 Jul 2015 05:14:13 +0000 (05:14 +0000)
Also add control inputs to 64-bit integer divide and modulus operations.

R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/1223613002

Cr-Commit-Position: refs/heads/master@{#29460}

14 files changed:
src/compiler/arm64/instruction-selector-arm64.cc
src/compiler/instruction-selector.cc
src/compiler/machine-operator.cc
src/compiler/machine-operator.h
src/compiler/mips64/instruction-selector-mips64.cc
src/compiler/opcodes.h
src/compiler/ppc/instruction-selector-ppc.cc
src/compiler/typer.cc
src/compiler/verifier.cc
src/compiler/x64/instruction-selector-x64.cc
src/globals.h
test/cctest/compiler/test-run-machops.cc
test/unittests/compiler/machine-operator-unittest.cc
test/unittests/compiler/raw-machine-assembler.h

index b304abcc4915a10c17206ca256ec3c517d0da0a6..7c1c1d76fa768f76d83cf1e651d9ab81027a5fb8 100644 (file)
@@ -1722,6 +1722,10 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
         cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
         return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
                                 kArithmeticImm);
+      case IrOpcode::kUint64LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+                                kArithmeticImm);
       case IrOpcode::kFloat32Equal:
         cont.OverwriteAndNegateIfEqual(kEqual);
         return VisitFloat32Compare(this, value, &cont);
@@ -1958,6 +1962,12 @@ void InstructionSelector::VisitUint64LessThan(Node* node) {
 }
 
 
+void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
+}
+
+
 void InstructionSelector::VisitFloat32Equal(Node* node) {
   FlagsContinuation cont(kEqual, node);
   VisitFloat32Compare(this, node, &cont);
index 6ab063e5165275775c9fdce384941f9e7086884c..0a6f2371908edbfd4d877032eac4c5c1e861cf09 100644 (file)
@@ -674,6 +674,8 @@ void InstructionSelector::VisitNode(Node* node) {
       return MarkAsWord64(node), VisitUint64Div(node);
     case IrOpcode::kUint64LessThan:
       return VisitUint64LessThan(node);
+    case IrOpcode::kUint64LessThanOrEqual:
+      return VisitUint64LessThanOrEqual(node);
     case IrOpcode::kUint64Mod:
       return MarkAsWord64(node), VisitUint64Mod(node);
     case IrOpcode::kChangeFloat32ToFloat64:
@@ -835,7 +837,7 @@ void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw,
 #endif  // V8_TURBOFAN_BACKEND
 
 // 32 bit targets do not implement the following instructions.
-#if V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_X64 && V8_TURBOFAN_BACKEND
+#if !V8_TURBOFAN_BACKEND_64
 
 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
 
@@ -890,6 +892,11 @@ void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
 void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); }
 
 
+void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
 void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); }
 
 
index e850534923eea923d56d93d41c86b526079b5345..f34fc8673345893f93d749fa2999c3a0bb1692c1 100644 (file)
@@ -101,13 +101,14 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
   V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
   V(Int64Sub, Operator::kNoProperties, 2, 0, 1)                               \
   V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
-  V(Int64Div, Operator::kNoProperties, 2, 0, 1)                               \
-  V(Int64Mod, Operator::kNoProperties, 2, 0, 1)                               \
+  V(Int64Div, Operator::kNoProperties, 2, 1, 1)                               \
+  V(Int64Mod, Operator::kNoProperties, 2, 1, 1)                               \
   V(Int64LessThan, Operator::kNoProperties, 2, 0, 1)                          \
   V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                   \
-  V(Uint64Div, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Uint64Div, Operator::kNoProperties, 2, 1, 1)                              \
+  V(Uint64Mod, Operator::kNoProperties, 2, 1, 1)                              \
   V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1)                         \
-  V(Uint64Mod, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Uint64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                  \
   V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1)                 \
   V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                   \
   V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1)                  \
index 1df97278b0e03427a6bb420f13008eedf15a3612..288006c509e824328a886cef1c7cb70b81d11829 100644 (file)
@@ -156,6 +156,7 @@ class MachineOperatorBuilder final : public ZoneObject {
   const Operator* Int64LessThanOrEqual();
   const Operator* Uint64Div();
   const Operator* Uint64LessThan();
+  const Operator* Uint64LessThanOrEqual();
   const Operator* Uint64Mod();
 
   // These operators change the representation of numbers while preserving the
index d4dbfe03af4cbceebac1a36840989506b657721b..8db0113df3f8195841934e87c6f9667acdf3d6fd 100644 (file)
@@ -1044,6 +1044,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
       case IrOpcode::kUint64LessThan:
         cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
         return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kUint64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWord64Compare(selector, value, cont);
       case IrOpcode::kFloat32Equal:
         cont->OverwriteAndNegateIfEqual(kEqual);
         return VisitFloat32Compare(selector, value, cont);
@@ -1220,6 +1223,12 @@ void InstructionSelector::VisitUint64LessThan(Node* node) {
 }
 
 
+void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
 void InstructionSelector::VisitFloat32Equal(Node* node) {
   FlagsContinuation cont(kEqual, node);
   VisitFloat32Compare(this, node, &cont);
index 5772ddc535dfe1003d63931e6c1eb0b17719df86..5fe04501105675a67f7aca315dfcf520ac85a184 100644 (file)
   V(Int64LessThan)                    \
   V(Int64LessThanOrEqual)             \
   V(Uint64LessThan)                   \
+  V(Uint64LessThanOrEqual)            \
   V(Float32Equal)                     \
   V(Float32LessThan)                  \
   V(Float32LessThanOrEqual)           \
index 339184d193106270f2c22f965b4ff7edb867ed2c..ec9e43c0cacf659c920e1d534bfed819ea65b79b 100644 (file)
@@ -1185,6 +1185,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
       case IrOpcode::kUint64LessThan:
         cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
         return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kUint64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWord64Compare(selector, value, cont);
 #endif
       case IrOpcode::kFloat32Equal:
         cont->OverwriteAndNegateIfEqual(kEqual);
@@ -1383,8 +1386,8 @@ void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
 }
 
 
-void InstructionSelector::VisitUint64LessThan(Node* node) {
-  FlagsContinuation cont(kUnsignedLessThan, node);
+void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
   VisitWord64Compare(this, node, &cont);
 }
 #endif
index bab9f4f09bd24f463c5fa2a49b4087cd9059081c..10cfd05b9679b6664b5856b2bd867fc6863d5a77 100644 (file)
@@ -2052,6 +2052,11 @@ Bounds Typer::Visitor::TypeUint64LessThan(Node* node) {
 }
 
 
+Bounds Typer::Visitor::TypeUint64LessThanOrEqual(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
 Bounds Typer::Visitor::TypeUint64Mod(Node* node) {
   return Bounds(Type::Internal());
 }
index 9c6695a2abbf8873433234baad8222cf892af335..7272801c5e4cc971a23d94fdb1b96ff687f88b11 100644 (file)
@@ -825,6 +825,7 @@ void Verifier::Visitor::Check(Node* node) {
     case IrOpcode::kUint64Div:
     case IrOpcode::kUint64Mod:
     case IrOpcode::kUint64LessThan:
+    case IrOpcode::kUint64LessThanOrEqual:
     case IrOpcode::kFloat32Add:
     case IrOpcode::kFloat32Sub:
     case IrOpcode::kFloat32Mul:
index b245fa8f879ec77a174d27c9de37f184e864f070..a7331fdee252029777b9cb06b95d759403755705 100644 (file)
@@ -1360,6 +1360,9 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
       case IrOpcode::kUint64LessThan:
         cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
         return VisitWord64Compare(this, value, &cont);
+      case IrOpcode::kUint64LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWord64Compare(this, value, &cont);
       case IrOpcode::kFloat32Equal:
         cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
         return VisitFloat32Compare(this, value, &cont);
@@ -1572,6 +1575,12 @@ void InstructionSelector::VisitUint64LessThan(Node* node) {
 }
 
 
+void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
 void InstructionSelector::VisitFloat32Equal(Node* node) {
   FlagsContinuation cont(kUnorderedEqual, node);
   VisitFloat32Compare(this, node, &cont);
index 291e5b01d9fa3045666c8e4f1600f7ade507401a..0f6fa2f805b54ab2ea13959ddfb13b6279a522b1 100644 (file)
 #if V8_TARGET_ARCH_IA32 || (V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_32_BIT) || \
     V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||     \
     V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_X87
+
 #define V8_TURBOFAN_BACKEND 1
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS64 || \
+    V8_TARGET_ARCH_PPC64
+// 64-bit TurboFan backends support 64-bit integer arithmetic.
+#define V8_TURBOFAN_BACKEND_64 1
+#else
+#define V8_TURBOFAN_BACKEND_64 0
+#endif
+
 #else
 #define V8_TURBOFAN_BACKEND 0
 #endif
+
 #if V8_TURBOFAN_BACKEND
 #define V8_TURBOFAN_TARGET 1
 #else
index 172f4c9e673f2aeb0416b590e71cc2afaa46f0a1..58b26ea90851d98702c74912591a1e5ac2519691 100644 (file)
@@ -82,6 +82,63 @@ TEST(CodeGenInt32Binop) {
 }
 
 
+#if V8_TURBOFAN_BACKEND_64
+static Node* Int64Input(RawMachineAssemblerTester<int64_t>* m, int index) {
+  switch (index) {
+    case 0:
+      return m->Parameter(0);
+    case 1:
+      return m->Parameter(1);
+    case 2:
+      return m->Int64Constant(0);
+    case 3:
+      return m->Int64Constant(1);
+    case 4:
+      return m->Int64Constant(-1);
+    case 5:
+      return m->Int64Constant(0xff);
+    case 6:
+      return m->Int64Constant(0x0123456789abcdefLL);
+    case 7:
+      return m->Load(kMachInt64, m->PointerConstant(NULL));
+    default:
+      return NULL;
+  }
+}
+
+
+TEST(CodeGenInt64Binop) {
+  RawMachineAssemblerTester<void> m;
+
+  const Operator* kOps[] = {
+      m.machine()->Word64And(), m.machine()->Word64Or(),
+      m.machine()->Word64Xor(), m.machine()->Word64Shl(),
+      m.machine()->Word64Shr(), m.machine()->Word64Sar(),
+      m.machine()->Word64Equal(), m.machine()->Int64Add(),
+      m.machine()->Int64Sub(), m.machine()->Int64Mul(), m.machine()->Int64Div(),
+      m.machine()->Uint64Div(), m.machine()->Int64Mod(),
+      m.machine()->Uint64Mod(), m.machine()->Int64LessThan(),
+      m.machine()->Int64LessThanOrEqual(), m.machine()->Uint64LessThan(),
+      m.machine()->Uint64LessThanOrEqual()};
+
+  for (size_t i = 0; i < arraysize(kOps); ++i) {
+    for (int j = 0; j < 8; j++) {
+      for (int k = 0; k < 8; k++) {
+        RawMachineAssemblerTester<int64_t> m(kMachInt64, kMachInt64);
+        Node* a = Int64Input(&m, j);
+        Node* b = Int64Input(&m, k);
+        m.Return(m.NewNode(kOps[i], a, b));
+        m.GenerateCode();
+      }
+    }
+  }
+}
+
+
+// TODO(titzer): add tests that run 64-bit integer operations.
+#endif  // V8_TURBOFAN_BACKEND_64
+
+
 TEST(RunGoto) {
   RawMachineAssemblerTester<int32_t> m;
   int constant = 99999;
index f49a6988f7d9b69f17760d1216d531e1d060cf08..fdba663e248f9354d66d9278c3ace1bc8772532d 100644 (file)
@@ -209,13 +209,14 @@ const PureOperator kPureOperators[] = {
     PURE(Int64Add, 2, 0, 1),                  // --
     PURE(Int64Sub, 2, 0, 1),                  // --
     PURE(Int64Mul, 2, 0, 1),                  // --
-    PURE(Int64Div, 2, 0, 1),                  // --
-    PURE(Uint64Div, 2, 0, 1),                 // --
-    PURE(Int64Mod, 2, 0, 1),                  // --
-    PURE(Uint64Mod, 2, 0, 1),                 // --
+    PURE(Int64Div, 2, 1, 1),                  // --
+    PURE(Uint64Div, 2, 1, 1),                 // --
+    PURE(Int64Mod, 2, 1, 1),                  // --
+    PURE(Uint64Mod, 2, 1, 1),                 // --
     PURE(Int64LessThan, 2, 0, 1),             // --
     PURE(Int64LessThanOrEqual, 2, 0, 1),      // --
     PURE(Uint64LessThan, 2, 0, 1),            // --
+    PURE(Uint64LessThanOrEqual, 2, 0, 1),     // --
     PURE(ChangeFloat32ToFloat64, 1, 0, 1),    // --
     PURE(ChangeFloat64ToInt32, 1, 0, 1),      // --
     PURE(ChangeFloat64ToUint32, 1, 0, 1),     // --
index d87da8d4daab86550e04aeb64b3b41c3baf5caf9..80af21339f18006052e76cc78bce3f7687a0cda7 100644 (file)
@@ -285,11 +285,14 @@ class RawMachineAssembler : public GraphBuilder {
   Node* Int64LessThan(Node* a, Node* b) {
     return NewNode(machine()->Int64LessThan(), a, b);
   }
+  Node* Int64LessThanOrEqual(Node* a, Node* b) {
+    return NewNode(machine()->Int64LessThanOrEqual(), a, b);
+  }
   Node* Uint64LessThan(Node* a, Node* b) {
     return NewNode(machine()->Uint64LessThan(), a, b);
   }
-  Node* Int64LessThanOrEqual(Node* a, Node* b) {
-    return NewNode(machine()->Int64LessThanOrEqual(), a, b);
+  Node* Uint64LessThanOrEqual(Node* a, Node* b) {
+    return NewNode(machine()->Uint64LessThanOrEqual(), a, b);
   }
   Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); }
   Node* Int64GreaterThanOrEqual(Node* a, Node* b) {