| Index: src/compiler/arm64/instruction-selector-arm64.cc
|
| diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc
|
| index fbc7df27e3157e33347a507d9769b86245865c5a..88b77fff488716d5797ea70089a104d6ce77d12a 100644
|
| --- a/src/compiler/arm64/instruction-selector-arm64.cc
|
| +++ b/src/compiler/arm64/instruction-selector-arm64.cc
|
| @@ -1343,18 +1343,6 @@ void InstructionSelector::VisitFloat64Mod(Node* node) {
|
| }
|
|
|
|
|
| -void InstructionSelector::VisitFloat32Max(Node* node) { UNREACHABLE(); }
|
| -
|
| -
|
| -void InstructionSelector::VisitFloat64Max(Node* node) { UNREACHABLE(); }
|
| -
|
| -
|
| -void InstructionSelector::VisitFloat32Min(Node* node) { UNREACHABLE(); }
|
| -
|
| -
|
| -void InstructionSelector::VisitFloat64Min(Node* node) { UNREACHABLE(); }
|
| -
|
| -
|
| void InstructionSelector::VisitFloat32Abs(Node* node) {
|
| VisitRR(this, kArm64Float32Abs, node);
|
| }
|
| @@ -1601,6 +1589,21 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
|
| }
|
|
|
|
|
| +// Shared routine for multiple compare-and-select operations.
|
| +void VisitCompareAndSelect(InstructionSelector* selector,
|
| + InstructionCode opcode, InstructionOperand cmp_left,
|
| + InstructionOperand cmp_right,
|
| + InstructionOperand if_true,
|
| + InstructionOperand if_false,
|
| + FlagsContinuation* cont) {
|
| + Arm64OperandGenerator g(selector);
|
| + opcode = cont->Encode(opcode);
|
| + DCHECK(cont->IsSelect());
|
| + selector->Emit(opcode, g.DefineAsRegister(cont->result()), cmp_left,
|
| + cmp_right, if_true, if_false);
|
| +}
|
| +
|
| +
|
| // Shared routine for multiple word compare operations.
|
| void VisitWordCompare(InstructionSelector* selector, Node* node,
|
| InstructionCode opcode, FlagsContinuation* cont,
|
| @@ -1651,7 +1654,7 @@ void VisitWord64Test(InstructionSelector* selector, Node* node,
|
| }
|
|
|
|
|
| -// Shared routine for multiple float64 compare operations.
|
| +// Shared routine for multiple float32 compare operations.
|
| void VisitFloat32Compare(InstructionSelector* selector, Node* node,
|
| FlagsContinuation* cont) {
|
| Arm64OperandGenerator g(selector);
|
| @@ -1666,6 +1669,24 @@ void VisitFloat32Compare(InstructionSelector* selector, Node* node,
|
| }
|
|
|
|
|
| +void VisitFloat32CompareAndSelect(InstructionSelector* selector, Node* node,
|
| + InstructionCode opcode, Node* cmp_left,
|
| + Node* cmp_right, Node* sel_true,
|
| + Node* sel_false, FlagsContinuation* cont) {
|
| + // (cmp_left <op> cmp_right) ? sel_true : sel_false
|
| + Arm64OperandGenerator g(selector);
|
| + if (Float32Matcher(cmp_right).Is(0.0f)) {
|
| + VisitCompareAndSelect(selector, opcode, g.UseRegister(cmp_left),
|
| + g.UseImmediate(cmp_right), g.UseRegister(sel_true),
|
| + g.UseRegister(sel_false), cont);
|
| + } else {
|
| + VisitCompareAndSelect(selector, opcode, g.UseRegister(cmp_left),
|
| + g.UseRegister(cmp_right), g.UseRegister(sel_true),
|
| + g.UseRegister(sel_false), cont);
|
| + }
|
| +}
|
| +
|
| +
|
| // Shared routine for multiple float64 compare operations.
|
| void VisitFloat64Compare(InstructionSelector* selector, Node* node,
|
| FlagsContinuation* cont) {
|
| @@ -1680,6 +1701,24 @@ void VisitFloat64Compare(InstructionSelector* selector, Node* node,
|
| }
|
| }
|
|
|
| +
|
| +void VisitFloat64CompareAndSelect(InstructionSelector* selector, Node* node,
|
| + InstructionCode opcode, Node* cmp_left,
|
| + Node* cmp_right, Node* sel_true,
|
| + Node* sel_false, FlagsContinuation* cont) {
|
| + // (cmp_left <op> cmp_right) ? sel_true : sel_false
|
| + Arm64OperandGenerator g(selector);
|
| + if (Float64Matcher(cmp_right).Is(0.0)) {
|
| + VisitCompareAndSelect(selector, opcode, g.UseRegister(cmp_left),
|
| + g.UseImmediate(cmp_right), g.UseRegister(sel_true),
|
| + g.UseRegister(sel_false), cont);
|
| + } else {
|
| + VisitCompareAndSelect(selector, opcode, g.UseRegister(cmp_left),
|
| + g.UseRegister(cmp_right), g.UseRegister(sel_true),
|
| + g.UseRegister(sel_false), cont);
|
| + }
|
| +}
|
| +
|
| } // namespace
|
|
|
|
|
| @@ -2027,6 +2066,42 @@ void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
|
| }
|
|
|
|
|
| +void InstructionSelector::VisitFloat32Max(Node* node) {
|
| + // (b < a) ? a : b
|
| + FlagsContinuation cont(kUnsignedLessThan, node, kFlags_select);
|
| + VisitFloat32CompareAndSelect(this, node, kArm64Float32CmpAndFloat32Sel,
|
| + node->InputAt(1), node->InputAt(0),
|
| + node->InputAt(0), node->InputAt(1), &cont);
|
| +}
|
| +
|
| +
|
| +void InstructionSelector::VisitFloat32Min(Node* node) {
|
| + // (a < b) ? a : b
|
| + FlagsContinuation cont(kUnsignedLessThan, node, kFlags_select);
|
| + VisitFloat32CompareAndSelect(this, node, kArm64Float32CmpAndFloat32Sel,
|
| + node->InputAt(0), node->InputAt(1),
|
| + node->InputAt(0), node->InputAt(1), &cont);
|
| +}
|
| +
|
| +
|
| +void InstructionSelector::VisitFloat64Max(Node* node) {
|
| + // (b < a) ? a : b
|
| + FlagsContinuation cont(kUnsignedLessThan, node, kFlags_select);
|
| + VisitFloat64CompareAndSelect(this, node, kArm64Float64CmpAndFloat64Sel,
|
| + node->InputAt(1), node->InputAt(0),
|
| + node->InputAt(0), node->InputAt(1), &cont);
|
| +}
|
| +
|
| +
|
| +void InstructionSelector::VisitFloat64Min(Node* node) {
|
| + // (a < b) ? a : b
|
| + FlagsContinuation cont(kUnsignedLessThan, node, kFlags_select);
|
| + VisitFloat64CompareAndSelect(this, node, kArm64Float64CmpAndFloat64Sel,
|
| + node->InputAt(0), node->InputAt(1),
|
| + node->InputAt(0), node->InputAt(1), &cont);
|
| +}
|
| +
|
| +
|
| void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
|
| Arm64OperandGenerator g(this);
|
| Emit(kArm64Float64ExtractLowWord32, g.DefineAsRegister(node),
|
| @@ -2079,7 +2154,11 @@ void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
|
| // static
|
| MachineOperatorBuilder::Flags
|
| InstructionSelector::SupportedMachineOperatorFlags() {
|
| - return MachineOperatorBuilder::kFloat64RoundDown |
|
| + return MachineOperatorBuilder::kFloat32Max |
|
| + MachineOperatorBuilder::kFloat32Min |
|
| + MachineOperatorBuilder::kFloat64Max |
|
| + MachineOperatorBuilder::kFloat64Min |
|
| + MachineOperatorBuilder::kFloat64RoundDown |
|
| MachineOperatorBuilder::kFloat64RoundTruncate |
|
| MachineOperatorBuilder::kFloat64RoundTiesAway |
|
| MachineOperatorBuilder::kWord32ShiftIsSafe |
|
|
|