Commit c24220c0 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Improve code generation for unordered comparisons.

TEST=cctest,unittests

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

Cr-Commit-Position: refs/heads/master@{#26034}
parent 527e19af
......@@ -200,6 +200,41 @@ class OutOfLineLoadInteger FINAL : public OutOfLineCode {
Register const result_;
};
Condition FlagsConditionToCondition(FlagsCondition condition) {
switch (condition) {
case kEqual:
return eq;
case kNotEqual:
return ne;
case kSignedLessThan:
return lt;
case kSignedGreaterThanOrEqual:
return ge;
case kSignedLessThanOrEqual:
return le;
case kSignedGreaterThan:
return gt;
case kUnsignedLessThan:
return lo;
case kUnsignedGreaterThanOrEqual:
return hs;
case kUnsignedLessThanOrEqual:
return ls;
case kUnsignedGreaterThan:
return hi;
case kOverflow:
return vs;
case kNotOverflow:
return vc;
case kUnorderedEqual:
case kUnorderedNotEqual:
break;
}
UNREACHABLE();
return kNoCondition;
}
} // namespace
......@@ -686,65 +721,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
ArmOperandConverter i(this, instr);
Label* tlabel = branch->true_label;
Label* flabel = branch->false_label;
switch (branch->condition) {
case kUnorderedEqual:
// The "eq" condition will not catch the unordered case.
// The jump/fall through to false label will be used if the comparison
// was unordered.
case kEqual:
__ b(eq, tlabel);
break;
case kUnorderedNotEqual:
// Unordered or not equal can be tested with "ne" condtion.
// See ARMv7 manual A8.3 - Conditional execution.
case kNotEqual:
__ b(ne, tlabel);
break;
case kSignedLessThan:
__ b(lt, tlabel);
break;
case kSignedGreaterThanOrEqual:
__ b(ge, tlabel);
break;
case kSignedLessThanOrEqual:
__ b(le, tlabel);
break;
case kSignedGreaterThan:
__ b(gt, tlabel);
break;
case kUnorderedLessThan:
// The "lo" condition will not catch the unordered case.
// The jump/fall through to false label will be used if the comparison
// was unordered.
case kUnsignedLessThan:
__ b(lo, tlabel);
break;
case kUnorderedGreaterThanOrEqual:
// Unordered, greater than or equal can be tested with "hs" condtion.
// See ARMv7 manual A8.3 - Conditional execution.
case kUnsignedGreaterThanOrEqual:
__ b(hs, tlabel);
break;
case kUnorderedLessThanOrEqual:
// The "ls" condition will not catch the unordered case.
// The jump/fall through to false label will be used if the comparison
// was unordered.
case kUnsignedLessThanOrEqual:
__ b(ls, tlabel);
break;
case kUnorderedGreaterThan:
// Unordered or greater than can be tested with "hi" condtion.
// See ARMv7 manual A8.3 - Conditional execution.
case kUnsignedGreaterThan:
__ b(hi, tlabel);
break;
case kOverflow:
__ b(vs, tlabel);
break;
case kNotOverflow:
__ b(vc, tlabel);
break;
}
Condition cc = FlagsConditionToCondition(branch->condition);
__ b(cc, tlabel);
if (!branch->fallthru) __ b(flabel); // no fallthru to flabel.
}
......@@ -758,86 +736,14 @@ void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
void CodeGenerator::AssembleArchBoolean(Instruction* instr,
FlagsCondition condition) {
ArmOperandConverter i(this, instr);
Label done;
// Materialize a full 32-bit 1 or 0 value. The result register is always the
// last output of the instruction.
Label check;
DCHECK_NE(0, instr->OutputCount());
Register reg = i.OutputRegister(instr->OutputCount() - 1);
Condition cc = kNoCondition;
switch (condition) {
case kUnorderedEqual:
__ b(vc, &check);
__ mov(reg, Operand(0));
__ b(&done);
// Fall through.
case kEqual:
cc = eq;
break;
case kUnorderedNotEqual:
__ b(vc, &check);
__ mov(reg, Operand(1));
__ b(&done);
// Fall through.
case kNotEqual:
cc = ne;
break;
case kSignedLessThan:
cc = lt;
break;
case kSignedGreaterThanOrEqual:
cc = ge;
break;
case kSignedLessThanOrEqual:
cc = le;
break;
case kSignedGreaterThan:
cc = gt;
break;
case kUnorderedLessThan:
__ b(vc, &check);
__ mov(reg, Operand(0));
__ b(&done);
// Fall through.
case kUnsignedLessThan:
cc = lo;
break;
case kUnorderedGreaterThanOrEqual:
__ b(vc, &check);
__ mov(reg, Operand(1));
__ b(&done);
// Fall through.
case kUnsignedGreaterThanOrEqual:
cc = hs;
break;
case kUnorderedLessThanOrEqual:
__ b(vc, &check);
__ mov(reg, Operand(0));
__ b(&done);
// Fall through.
case kUnsignedLessThanOrEqual:
cc = ls;
break;
case kUnorderedGreaterThan:
__ b(vc, &check);
__ mov(reg, Operand(1));
__ b(&done);
// Fall through.
case kUnsignedGreaterThan:
cc = hi;
break;
case kOverflow:
cc = vs;
break;
case kNotOverflow:
cc = vc;
break;
}
__ bind(&check);
Condition cc = FlagsConditionToCondition(condition);
__ mov(reg, Operand(0));
__ mov(reg, Operand(1), LeaveCC, cc);
__ bind(&done);
}
......
......@@ -1167,13 +1167,13 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
return VisitWordCompare(selector, value, cont);
case IrOpcode::kFloat64Equal:
cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
cont->OverwriteAndNegateIfEqual(kEqual);
return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kFloat64LessThan:
cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kFloat64LessThanOrEqual:
cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kProjection:
// Check if this is the overflow output projection of an
......@@ -1304,19 +1304,19 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
void InstructionSelector::VisitFloat64Equal(Node* node) {
FlagsContinuation cont(kUnorderedEqual, node);
FlagsContinuation cont(kEqual, node);
VisitFloat64Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat64LessThan(Node* node) {
FlagsContinuation cont(kUnorderedLessThan, node);
FlagsContinuation cont(kUnsignedLessThan, node);
VisitFloat64Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
VisitFloat64Compare(this, node, &cont);
}
......
......@@ -216,6 +216,41 @@ class OutOfLineLoadZero FINAL : public OutOfLineCode {
Register const result_;
};
Condition FlagsConditionToCondition(FlagsCondition condition) {
switch (condition) {
case kEqual:
return eq;
case kNotEqual:
return ne;
case kSignedLessThan:
return lt;
case kSignedGreaterThanOrEqual:
return ge;
case kSignedLessThanOrEqual:
return le;
case kSignedGreaterThan:
return gt;
case kUnsignedLessThan:
return lo;
case kUnsignedGreaterThanOrEqual:
return hs;
case kUnsignedLessThanOrEqual:
return ls;
case kUnsignedGreaterThan:
return hi;
case kOverflow:
return vs;
case kNotOverflow:
return vc;
case kUnorderedEqual:
case kUnorderedNotEqual:
break;
}
UNREACHABLE();
return nv;
}
} // namespace
......@@ -786,65 +821,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
UNREACHABLE();
}
} else {
switch (condition) {
case kUnorderedEqual:
// The "eq" condition will not catch the unordered case.
// The jump/fall through to false label will be used if the comparison
// was unordered.
case kEqual:
__ B(eq, tlabel);
break;
case kUnorderedNotEqual:
// Unordered or not equal can be tested with "ne" condtion.
// See ARMv8 manual C1.2.3 - Condition Code.
case kNotEqual:
__ B(ne, tlabel);
break;
case kSignedLessThan:
__ B(lt, tlabel);
break;
case kSignedGreaterThanOrEqual:
__ B(ge, tlabel);
break;
case kSignedLessThanOrEqual:
__ B(le, tlabel);
break;
case kSignedGreaterThan:
__ B(gt, tlabel);
break;
case kUnorderedLessThan:
// The "lo" condition will not catch the unordered case.
// The jump/fall through to false label will be used if the comparison
// was unordered.
case kUnsignedLessThan:
__ B(lo, tlabel);
break;
case kUnorderedGreaterThanOrEqual:
// Unordered, greater than or equal can be tested with "hs" condtion.
// See ARMv8 manual C1.2.3 - Condition Code.
case kUnsignedGreaterThanOrEqual:
__ B(hs, tlabel);
break;
case kUnorderedLessThanOrEqual:
// The "ls" condition will not catch the unordered case.
// The jump/fall through to false label will be used if the comparison
// was unordered.
case kUnsignedLessThanOrEqual:
__ B(ls, tlabel);
break;
case kUnorderedGreaterThan:
// Unordered or greater than can be tested with "hi" condtion.
// See ARMv8 manual C1.2.3 - Condition Code.
case kUnsignedGreaterThan:
__ B(hi, tlabel);
break;
case kOverflow:
__ B(vs, tlabel);
break;
case kNotOverflow:
__ B(vc, tlabel);
break;
}
Condition cc = FlagsConditionToCondition(condition);
__ B(cc, tlabel);
}
if (!branch->fallthru) __ B(flabel); // no fallthru to flabel.
}
......@@ -859,85 +837,13 @@ void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
void CodeGenerator::AssembleArchBoolean(Instruction* instr,
FlagsCondition condition) {
Arm64OperandConverter i(this, instr);
Label done;
// Materialize a full 64-bit 1 or 0 value. The result register is always the
// last output of the instruction.
Label check;
DCHECK_NE(0, instr->OutputCount());
Register reg = i.OutputRegister(instr->OutputCount() - 1);
Condition cc = nv;
switch (condition) {
case kUnorderedEqual:
__ B(vc, &check);
__ Mov(reg, 0);
__ B(&done);
// Fall through.
case kEqual:
cc = eq;
break;
case kUnorderedNotEqual:
__ B(vc, &check);
__ Mov(reg, 1);
__ B(&done);
// Fall through.
case kNotEqual:
cc = ne;
break;
case kSignedLessThan:
cc = lt;
break;
case kSignedGreaterThanOrEqual:
cc = ge;
break;
case kSignedLessThanOrEqual:
cc = le;
break;
case kSignedGreaterThan:
cc = gt;
break;
case kUnorderedLessThan:
__ B(vc, &check);
__ Mov(reg, 0);
__ B(&done);
// Fall through.
case kUnsignedLessThan:
cc = lo;
break;
case kUnorderedGreaterThanOrEqual:
__ B(vc, &check);
__ Mov(reg, 1);
__ B(&done);
// Fall through.
case kUnsignedGreaterThanOrEqual:
cc = hs;
break;
case kUnorderedLessThanOrEqual:
__ B(vc, &check);
__ Mov(reg, 0);
__ B(&done);
// Fall through.
case kUnsignedLessThanOrEqual:
cc = ls;
break;
case kUnorderedGreaterThan:
__ B(vc, &check);
__ Mov(reg, 1);
__ B(&done);
// Fall through.
case kUnsignedGreaterThan:
cc = hi;
break;
case kOverflow:
cc = vs;
break;
case kNotOverflow:
cc = vc;
break;
}
__ Bind(&check);
Condition cc = FlagsConditionToCondition(condition);
__ Cset(reg, cc);
__ Bind(&done);
}
......
......@@ -1295,13 +1295,13 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
kArithmeticImm);
case IrOpcode::kFloat64Equal:
cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
cont.OverwriteAndNegateIfEqual(kEqual);
return VisitFloat64Compare(this, value, &cont);
case IrOpcode::kFloat64LessThan:
cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
return VisitFloat64Compare(this, value, &cont);
case IrOpcode::kFloat64LessThanOrEqual:
cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
return VisitFloat64Compare(this, value, &cont);
case IrOpcode::kProjection:
// Check if this is the overflow output projection of an
......@@ -1497,19 +1497,19 @@ void InstructionSelector::VisitUint64LessThan(Node* node) {
void InstructionSelector::VisitFloat64Equal(Node* node) {
FlagsContinuation cont(kUnorderedEqual, node);
FlagsContinuation cont(kEqual, node);
VisitFloat64Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat64LessThan(Node* node) {
FlagsContinuation cont(kUnorderedLessThan, node);
FlagsContinuation cont(kUnsignedLessThan, node);
VisitFloat64Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
VisitFloat64Compare(this, node, &cont);
}
......@@ -1525,6 +1525,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kInt32DivIsSafe |
MachineOperatorBuilder::kUint32DivIsSafe;
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -731,27 +731,15 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
case kSignedGreaterThan:
__ j(greater, tlabel);
break;
case kUnorderedLessThan:
__ j(parity_even, flabel, flabel_distance);
// Fall through.
case kUnsignedLessThan:
__ j(below, tlabel);
break;
case kUnorderedGreaterThanOrEqual:
__ j(parity_even, tlabel);
// Fall through.
case kUnsignedGreaterThanOrEqual:
__ j(above_equal, tlabel);
break;
case kUnorderedLessThanOrEqual:
__ j(parity_even, flabel, flabel_distance);
// Fall through.
case kUnsignedLessThanOrEqual:
__ j(below_equal, tlabel);
break;
case kUnorderedGreaterThan:
__ j(parity_even, tlabel);
// Fall through.
case kUnsignedGreaterThan:
__ j(above, tlabel);
break;
......@@ -813,35 +801,15 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
case kSignedGreaterThan:
cc = greater;
break;
case kUnorderedLessThan:
__ j(parity_odd, &check, Label::kNear);
__ Move(reg, Immediate(0));
__ jmp(&done, Label::kNear);
// Fall through.
case kUnsignedLessThan:
cc = below;
break;
case kUnorderedGreaterThanOrEqual:
__ j(parity_odd, &check, Label::kNear);
__ mov(reg, Immediate(1));
__ jmp(&done, Label::kNear);
// Fall through.
case kUnsignedGreaterThanOrEqual:
cc = above_equal;
break;
case kUnorderedLessThanOrEqual:
__ j(parity_odd, &check, Label::kNear);
__ Move(reg, Immediate(0));
__ jmp(&done, Label::kNear);
// Fall through.
case kUnsignedLessThanOrEqual:
cc = below_equal;
break;
case kUnorderedGreaterThan:
__ j(parity_odd, &check, Label::kNear);
__ mov(reg, Immediate(1));
__ jmp(&done, Label::kNear);
// Fall through.
case kUnsignedGreaterThan:
cc = above;
break;
......
......@@ -799,11 +799,12 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
}
// Shared routine for multiple float compare operations.
// Shared routine for multiple float64 compare operations (inputs commuted).
void VisitFloat64Compare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
VisitCompare(selector, kSSEFloat64Cmp, node->InputAt(0), node->InputAt(1),
cont, node->op()->HasProperty(Operator::kCommutative));
Node* const left = node->InputAt(0);
Node* const right = node->InputAt(1);
VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false);
}
......@@ -868,10 +869,10 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kFloat64LessThan:
cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kFloat64LessThanOrEqual:
cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kProjection:
// Check if this is the overflow output projection of an
......@@ -984,13 +985,13 @@ void InstructionSelector::VisitFloat64Equal(Node* node) {
void InstructionSelector::VisitFloat64LessThan(Node* node) {
FlagsContinuation cont(kUnorderedLessThan, node);
FlagsContinuation cont(kUnsignedGreaterThan, node);
VisitFloat64Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
VisitFloat64Compare(this, node, &cont);
}
......@@ -1006,6 +1007,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
}
return MachineOperatorBuilder::Flag::kNoFlags;
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -102,10 +102,6 @@ enum FlagsCondition {
kUnsignedGreaterThan,
kUnorderedEqual,
kUnorderedNotEqual,
kUnorderedLessThan,
kUnorderedGreaterThanOrEqual,
kUnorderedLessThanOrEqual,
kUnorderedGreaterThan,
kOverflow,
kNotOverflow
};
......@@ -129,7 +125,7 @@ typedef int32_t InstructionCode;
typedef BitField<ArchOpcode, 0, 7> ArchOpcodeField;
typedef BitField<AddressingMode, 7, 5> AddressingModeField;
typedef BitField<FlagsMode, 12, 2> FlagsModeField;
typedef BitField<FlagsCondition, 14, 5> FlagsConditionField;
typedef BitField<FlagsCondition, 14, 4> FlagsConditionField;
typedef BitField<int, 14, 18> MiscField;
} // namespace compiler
......
......@@ -303,18 +303,6 @@ class FlagsContinuation FINAL {
case kUnorderedEqual:
case kUnorderedNotEqual:
return;
case kUnorderedLessThan:
condition_ = kUnorderedGreaterThan;
return;
case kUnorderedGreaterThanOrEqual:
condition_ = kUnorderedLessThanOrEqual;
return;
case kUnorderedLessThanOrEqual:
condition_ = kUnorderedGreaterThanOrEqual;
return;
case kUnorderedGreaterThan:
condition_ = kUnorderedLessThan;
return;
}
UNREACHABLE();
}
......
......@@ -252,14 +252,6 @@ std::ostream& operator<<(std::ostream& os, const FlagsCondition& fc) {
return os << "unordered equal";
case kUnorderedNotEqual:
return os << "unordered not equal";
case kUnorderedLessThan:
return os << "unordered less than";
case kUnorderedGreaterThanOrEqual:
return os << "unordered greater than or equal";
case kUnorderedLessThanOrEqual:
return os << "unordered less than or equal";
case kUnorderedGreaterThan:
return os << "unordered greater than";
case kOverflow:
return os << "overflow";
case kNotOverflow:
......
......@@ -1042,27 +1042,15 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
case kSignedGreaterThan:
__ j(greater, tlabel);
break;
case kUnorderedLessThan:
__ j(parity_even, flabel, flabel_distance);
// Fall through.
case kUnsignedLessThan:
__ j(below, tlabel);
break;
case kUnorderedGreaterThanOrEqual:
__ j(parity_even, tlabel);
// Fall through.
case kUnsignedGreaterThanOrEqual:
__ j(above_equal, tlabel);
break;
case kUnorderedLessThanOrEqual:
__ j(parity_even, flabel, flabel_distance);
// Fall through.
case kUnsignedLessThanOrEqual:
__ j(below_equal, tlabel);
break;
case kUnorderedGreaterThan:
__ j(parity_even, tlabel);
// Fall through.
case kUnsignedGreaterThan:
__ j(above, tlabel);
break;
......@@ -1123,35 +1111,15 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
case kSignedGreaterThan:
cc = greater;
break;
case kUnorderedLessThan:
__ j(parity_odd, &check, Label::kNear);
__ movl(reg, Immediate(0));
__ jmp(&done, Label::kNear);
// Fall through.
case kUnsignedLessThan:
cc = below;
break;
case kUnorderedGreaterThanOrEqual:
__ j(parity_odd, &check, Label::kNear);
__ movl(reg, Immediate(1));
__ jmp(&done, Label::kNear);
// Fall through.
case kUnsignedGreaterThanOrEqual:
cc = above_equal;
break;
case kUnorderedLessThanOrEqual:
__ j(parity_odd, &check, Label::kNear);
__ movl(reg, Immediate(0));
__ jmp(&done, Label::kNear);
// Fall through.
case kUnsignedLessThanOrEqual:
cc = below_equal;
break;
case kUnorderedGreaterThan:
__ j(parity_odd, &check, Label::kNear);
__ movl(reg, Immediate(1));
__ jmp(&done, Label::kNear);
// Fall through.
case kUnsignedGreaterThan:
cc = above;
break;
......
......@@ -1027,11 +1027,12 @@ static void VisitCompareZero(InstructionSelector* selector, Node* node,
}
// Shared routine for multiple float64 compare operations.
// Shared routine for multiple float64 compare operations (inputs commuted).
static void VisitFloat64Compare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
VisitCompare(selector, kSSEFloat64Cmp, node->InputAt(0), node->InputAt(1),
cont, node->op()->HasProperty(Operator::kCommutative));
Node* const left = node->InputAt(0);
Node* const right = node->InputAt(1);
VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false);
}
......@@ -1102,10 +1103,10 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
return VisitFloat64Compare(this, value, &cont);
case IrOpcode::kFloat64LessThan:
cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
return VisitFloat64Compare(this, value, &cont);
case IrOpcode::kFloat64LessThanOrEqual:
cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
return VisitFloat64Compare(this, value, &cont);
case IrOpcode::kProjection:
// Check if this is the overflow output projection of an
......@@ -1291,13 +1292,13 @@ void InstructionSelector::VisitFloat64Equal(Node* node) {
void InstructionSelector::VisitFloat64LessThan(Node* node) {
FlagsContinuation cont(kUnorderedLessThan, node);
FlagsContinuation cont(kUnsignedGreaterThan, node);
VisitFloat64Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
VisitFloat64Compare(this, node, &cont);
}
......
......@@ -444,10 +444,10 @@ TEST(BranchCombineFloat64Compares) {
m.Bind(&blockb);
m.Return(m.Int32Constant(ne_constant));
for (size_t i = 0; i < arraysize(inputs); i++) {
for (size_t j = 0; j < arraysize(inputs); j += 2) {
for (size_t i = 0; i < arraysize(inputs); ++i) {
for (size_t j = 0; j < arraysize(inputs); ++j) {
input_a = inputs[i];
input_b = inputs[i];
input_b = inputs[j];
int32_t expected =
invert ? (cmp.Float64Compare(input_a, input_b) ? ne_constant
: eq_constant)
......
......@@ -62,7 +62,7 @@ Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type,
// ARM64 logical instructions.
static const MachInst2 kLogicalInstructions[] = {
const MachInst2 kLogicalInstructions[] = {
{&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32},
{&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64},
{&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32},
......@@ -74,7 +74,7 @@ static const MachInst2 kLogicalInstructions[] = {
// ARM64 logical immediates: contiguous set bits, rotated about a power of two
// sized block. The block is then duplicated across the word. Below is a random
// subset of the 32-bit immediates.
static const uint32_t kLogical32Immediates[] = {
const uint32_t kLogical32Immediates[] = {
0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0,
0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000,
0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000,
......@@ -95,7 +95,7 @@ static const uint32_t kLogical32Immediates[] = {
// Random subset of 64-bit logical immediates.
static const uint64_t kLogical64Immediates[] = {
const uint64_t kLogical64Immediates[] = {
0x0000000000000001, 0x0000000000000002, 0x0000000000000003,
0x0000000000000070, 0x0000000000000080, 0x0000000000000100,
0x00000000000001c0, 0x0000000000000300, 0x0000000000000600,
......@@ -131,7 +131,7 @@ std::ostream& operator<<(std::ostream& os, const AddSub& op) {
}
static const AddSub kAddSubInstructions[] = {
const AddSub kAddSubInstructions[] = {
{{&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32},
kArm64Sub32},
{{&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64},
......@@ -144,7 +144,7 @@ static const AddSub kAddSubInstructions[] = {
// ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12.
// Below is a combination of a random subset and some edge values.
static const int32_t kAddSubImmediates[] = {
const int32_t kAddSubImmediates[] = {
0, 1, 69, 493, 599, 701, 719,
768, 818, 842, 945, 1246, 1286, 1429,
1669, 2171, 2179, 2182, 2254, 2334, 2338,
......@@ -160,7 +160,7 @@ static const int32_t kAddSubImmediates[] = {
// ARM64 flag setting data processing instructions.
static const MachInst2 kDPFlagSetInstructions[] = {
const MachInst2 kDPFlagSetInstructions[] = {
{&RawMachineAssembler::Word32And, "Word32And", kArm64Tst32, kMachInt32},
{&RawMachineAssembler::Int32Add, "Int32Add", kArm64Cmn32, kMachInt32},
{&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Cmp32, kMachInt32},
......@@ -168,7 +168,7 @@ static const MachInst2 kDPFlagSetInstructions[] = {
// ARM64 arithmetic with overflow instructions.
static const MachInst2 kOvfAddSubInstructions[] = {
const MachInst2 kOvfAddSubInstructions[] = {
{&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow",
kArm64Add32, kMachInt32},
{&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow",
......@@ -176,7 +176,7 @@ static const MachInst2 kOvfAddSubInstructions[] = {
// ARM64 shift instructions.
static const Shift kShiftInstructions[] = {
const Shift kShiftInstructions[] = {
{{&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Lsl32, kMachInt32},
kMode_Operand2_R_LSL_I},
{{&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Lsl, kMachInt64},
......@@ -196,7 +196,7 @@ static const Shift kShiftInstructions[] = {
// ARM64 Mul/Div instructions.
static const MachInst2 kMulDivInstructions[] = {
const MachInst2 kMulDivInstructions[] = {
{&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32},
{&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64},
{&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32},
......@@ -206,7 +206,7 @@ static const MachInst2 kMulDivInstructions[] = {
// ARM64 FP arithmetic instructions.
static const MachInst2 kFPArithInstructions[] = {
const MachInst2 kFPArithInstructions[] = {
{&RawMachineAssembler::Float64Add, "Float64Add", kArm64Float64Add,
kMachFloat64},
{&RawMachineAssembler::Float64Sub, "Float64Sub", kArm64Float64Sub,
......@@ -229,16 +229,16 @@ std::ostream& operator<<(std::ostream& os, const FPCmp& cmp) {
// ARM64 FP comparison instructions.
static const FPCmp kFPCmpInstructions[] = {
const FPCmp kFPCmpInstructions[] = {
{{&RawMachineAssembler::Float64Equal, "Float64Equal", kArm64Float64Cmp,
kMachFloat64},
kUnorderedEqual},
kEqual},
{{&RawMachineAssembler::Float64LessThan, "Float64LessThan",
kArm64Float64Cmp, kMachFloat64},
kUnorderedLessThan},
kUnsignedLessThan},
{{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
kArm64Float64Cmp, kMachFloat64},
kUnorderedLessThanOrEqual}};
kUnsignedLessThanOrEqual}};
struct Conversion {
......@@ -254,7 +254,7 @@ std::ostream& operator<<(std::ostream& os, const Conversion& conv) {
// ARM64 type conversion instructions.
static const Conversion kConversionInstructions[] = {
const Conversion kConversionInstructions[] = {
{{&RawMachineAssembler::ChangeFloat32ToFloat64, "ChangeFloat32ToFloat64",
kArm64Float32ToFloat64, kMachFloat64},
kMachFloat32},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment