| Index: src/compiler/arm/instruction-selector-arm.cc
|
| diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc
|
| index d2c9e7727391ff70eaeb7e56025d3205aef68de6..f58a29de8a6410059ae1a2dec7bab80a407f7c1b 100644
|
| --- a/src/compiler/arm/instruction-selector-arm.cc
|
| +++ b/src/compiler/arm/instruction-selector-arm.cc
|
| @@ -1267,22 +1267,37 @@ void InstructionSelector::VisitTailCall(Node* node) {
|
|
|
| namespace {
|
|
|
| +// Shared routine for multiple compare operations.
|
| +void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
|
| + InstructionOperand left, InstructionOperand right,
|
| + FlagsContinuation* cont) {
|
| + ArmOperandGenerator g(selector);
|
| + opcode = cont->Encode(opcode);
|
| + if (cont->IsBranch()) {
|
| + selector->Emit(opcode, g.NoOutput(), left, right,
|
| + g.Label(cont->true_block()), g.Label(cont->false_block()));
|
| + } else {
|
| + DCHECK(cont->IsSet());
|
| + selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
|
| + }
|
| +}
|
| +
|
| +
|
| // Shared routine for multiple float32 compare operations.
|
| void VisitFloat32Compare(InstructionSelector* selector, Node* node,
|
| FlagsContinuation* cont) {
|
| ArmOperandGenerator g(selector);
|
| Float32BinopMatcher m(node);
|
| - InstructionOperand rhs = m.right().Is(0.0) ? g.UseImmediate(m.right().node())
|
| - : g.UseRegister(m.right().node());
|
| - if (cont->IsBranch()) {
|
| - selector->Emit(cont->Encode(kArmVcmpF32), g.NoOutput(),
|
| - g.UseRegister(m.left().node()), rhs,
|
| - g.Label(cont->true_block()), g.Label(cont->false_block()));
|
| + if (m.right().Is(0.0f)) {
|
| + VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.left().node()),
|
| + g.UseImmediate(m.right().node()), cont);
|
| + } else if (m.left().Is(0.0f)) {
|
| + cont->Commute();
|
| + VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.right().node()),
|
| + g.UseImmediate(m.left().node()), cont);
|
| } else {
|
| - DCHECK(cont->IsSet());
|
| - selector->Emit(cont->Encode(kArmVcmpF32),
|
| - g.DefineAsRegister(cont->result()),
|
| - g.UseRegister(m.left().node()), rhs);
|
| + VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.left().node()),
|
| + g.UseRegister(m.right().node()), cont);
|
| }
|
| }
|
|
|
| @@ -1292,17 +1307,16 @@ void VisitFloat64Compare(InstructionSelector* selector, Node* node,
|
| FlagsContinuation* cont) {
|
| ArmOperandGenerator g(selector);
|
| Float64BinopMatcher m(node);
|
| - InstructionOperand rhs = m.right().Is(0.0) ? g.UseImmediate(m.right().node())
|
| - : g.UseRegister(m.right().node());
|
| - if (cont->IsBranch()) {
|
| - selector->Emit(cont->Encode(kArmVcmpF64), g.NoOutput(),
|
| - g.UseRegister(m.left().node()), rhs,
|
| - g.Label(cont->true_block()), g.Label(cont->false_block()));
|
| + if (m.right().Is(0.0)) {
|
| + VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.left().node()),
|
| + g.UseImmediate(m.right().node()), cont);
|
| + } else if (m.left().Is(0.0)) {
|
| + cont->Commute();
|
| + VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.right().node()),
|
| + g.UseImmediate(m.left().node()), cont);
|
| } else {
|
| - DCHECK(cont->IsSet());
|
| - selector->Emit(cont->Encode(kArmVcmpF64),
|
| - g.DefineAsRegister(cont->result()),
|
| - g.UseRegister(m.left().node()), rhs);
|
| + VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.left().node()),
|
| + g.UseRegister(m.right().node()), cont);
|
| }
|
| }
|
|
|
| @@ -1389,19 +1403,19 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
|
| cont->OverwriteAndNegateIfEqual(kEqual);
|
| return VisitFloat32Compare(selector, value, cont);
|
| case IrOpcode::kFloat32LessThan:
|
| - cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
|
| + cont->OverwriteAndNegateIfEqual(kFloatLessThan);
|
| return VisitFloat32Compare(selector, value, cont);
|
| case IrOpcode::kFloat32LessThanOrEqual:
|
| - cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
|
| + cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
|
| return VisitFloat32Compare(selector, value, cont);
|
| case IrOpcode::kFloat64Equal:
|
| cont->OverwriteAndNegateIfEqual(kEqual);
|
| return VisitFloat64Compare(selector, value, cont);
|
| case IrOpcode::kFloat64LessThan:
|
| - cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
|
| + cont->OverwriteAndNegateIfEqual(kFloatLessThan);
|
| return VisitFloat64Compare(selector, value, cont);
|
| case IrOpcode::kFloat64LessThanOrEqual:
|
| - cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
|
| + cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
|
| return VisitFloat64Compare(selector, value, cont);
|
| case IrOpcode::kProjection:
|
| // Check if this is the overflow output projection of an
|
| @@ -1565,13 +1579,13 @@ void InstructionSelector::VisitFloat32Equal(Node* node) {
|
|
|
|
|
| void InstructionSelector::VisitFloat32LessThan(Node* node) {
|
| - FlagsContinuation cont(kUnsignedLessThan, node);
|
| + FlagsContinuation cont(kFloatLessThan, node);
|
| VisitFloat32Compare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
|
| - FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
|
| + FlagsContinuation cont(kFloatLessThanOrEqual, node);
|
| VisitFloat32Compare(this, node, &cont);
|
| }
|
|
|
| @@ -1583,13 +1597,13 @@ void InstructionSelector::VisitFloat64Equal(Node* node) {
|
|
|
|
|
| void InstructionSelector::VisitFloat64LessThan(Node* node) {
|
| - FlagsContinuation cont(kUnsignedLessThan, node);
|
| + FlagsContinuation cont(kFloatLessThan, node);
|
| VisitFloat64Compare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
|
| - FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
|
| + FlagsContinuation cont(kFloatLessThanOrEqual, node);
|
| VisitFloat64Compare(this, node, &cont);
|
| }
|
|
|
|
|