From 0a5b6ad7556c10187e35fe87bb2f9dfbb618d8b9 Mon Sep 17 00:00:00 2001 From: titzer Date: Thu, 2 Jul 2015 22:13:57 -0700 Subject: [PATCH] [turbofan] Add Uint64LessThanOrEqual to 64-bit TurboFan backends. 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} --- src/compiler/arm64/instruction-selector-arm64.cc | 10 ++++ src/compiler/instruction-selector.cc | 9 +++- src/compiler/machine-operator.cc | 9 ++-- src/compiler/machine-operator.h | 1 + src/compiler/mips64/instruction-selector-mips64.cc | 9 ++++ src/compiler/opcodes.h | 1 + src/compiler/ppc/instruction-selector-ppc.cc | 7 ++- src/compiler/typer.cc | 5 ++ src/compiler/verifier.cc | 1 + src/compiler/x64/instruction-selector-x64.cc | 9 ++++ src/globals.h | 10 ++++ test/cctest/compiler/test-run-machops.cc | 57 ++++++++++++++++++++++ .../compiler/machine-operator-unittest.cc | 9 ++-- test/unittests/compiler/raw-machine-assembler.h | 7 ++- 14 files changed, 131 insertions(+), 13 deletions(-) diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc index b304abc..7c1c1d7 100644 --- a/src/compiler/arm64/instruction-selector-arm64.cc +++ b/src/compiler/arm64/instruction-selector-arm64.cc @@ -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); diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index 6ab063e..0a6f237 100644 --- a/src/compiler/instruction-selector.cc +++ b/src/compiler/instruction-selector.cc @@ -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(); } diff --git a/src/compiler/machine-operator.cc b/src/compiler/machine-operator.cc index e850534..f34fc86 100644 --- a/src/compiler/machine-operator.cc +++ b/src/compiler/machine-operator.cc @@ -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) \ diff --git a/src/compiler/machine-operator.h b/src/compiler/machine-operator.h index 1df9727..288006c 100644 --- a/src/compiler/machine-operator.h +++ b/src/compiler/machine-operator.h @@ -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 diff --git a/src/compiler/mips64/instruction-selector-mips64.cc b/src/compiler/mips64/instruction-selector-mips64.cc index d4dbfe0..8db0113 100644 --- a/src/compiler/mips64/instruction-selector-mips64.cc +++ b/src/compiler/mips64/instruction-selector-mips64.cc @@ -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); diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h index 5772ddc..5fe0450 100644 --- a/src/compiler/opcodes.h +++ b/src/compiler/opcodes.h @@ -203,6 +203,7 @@ V(Int64LessThan) \ V(Int64LessThanOrEqual) \ V(Uint64LessThan) \ + V(Uint64LessThanOrEqual) \ V(Float32Equal) \ V(Float32LessThan) \ V(Float32LessThanOrEqual) \ diff --git a/src/compiler/ppc/instruction-selector-ppc.cc b/src/compiler/ppc/instruction-selector-ppc.cc index 339184d..ec9e43c 100644 --- a/src/compiler/ppc/instruction-selector-ppc.cc +++ b/src/compiler/ppc/instruction-selector-ppc.cc @@ -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 diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index bab9f4f..10cfd05 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -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()); } diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc index 9c6695a..7272801 100644 --- a/src/compiler/verifier.cc +++ b/src/compiler/verifier.cc @@ -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: diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc index b245fa8..a7331fd 100644 --- a/src/compiler/x64/instruction-selector-x64.cc +++ b/src/compiler/x64/instruction-selector-x64.cc @@ -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); diff --git a/src/globals.h b/src/globals.h index 291e5b0..0f6fa2f 100644 --- a/src/globals.h +++ b/src/globals.h @@ -33,10 +33,20 @@ #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 diff --git a/test/cctest/compiler/test-run-machops.cc b/test/cctest/compiler/test-run-machops.cc index 172f4c9..58b26ea 100644 --- a/test/cctest/compiler/test-run-machops.cc +++ b/test/cctest/compiler/test-run-machops.cc @@ -82,6 +82,63 @@ TEST(CodeGenInt32Binop) { } +#if V8_TURBOFAN_BACKEND_64 +static Node* Int64Input(RawMachineAssemblerTester* 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 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 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 m; int constant = 99999; diff --git a/test/unittests/compiler/machine-operator-unittest.cc b/test/unittests/compiler/machine-operator-unittest.cc index f49a698..fdba663 100644 --- a/test/unittests/compiler/machine-operator-unittest.cc +++ b/test/unittests/compiler/machine-operator-unittest.cc @@ -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), // -- diff --git a/test/unittests/compiler/raw-machine-assembler.h b/test/unittests/compiler/raw-machine-assembler.h index d87da8d..80af213 100644 --- a/test/unittests/compiler/raw-machine-assembler.h +++ b/test/unittests/compiler/raw-machine-assembler.h @@ -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) { -- 2.7.4