[turbofan] Make Float32Neg and Float64Neg mandatory operators.

R=bmeurer@chromium.org

Review-Url: https://codereview.chromium.org/2215403002
Cr-Commit-Position: refs/heads/master@{#38399}
This commit is contained in:
ahaas 2016-08-05 11:49:15 -07:00 committed by Commit bot
parent 6b2d24fe8f
commit 6c44ab30fd
19 changed files with 55 additions and 79 deletions

View File

@ -2285,9 +2285,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kFloat64RoundTruncate |
MachineOperatorBuilder::kFloat64RoundTiesAway |
MachineOperatorBuilder::kFloat32RoundTiesEven |
MachineOperatorBuilder::kFloat64RoundTiesEven |
MachineOperatorBuilder::kFloat32Neg |
MachineOperatorBuilder::kFloat64Neg;
MachineOperatorBuilder::kFloat64RoundTiesEven;
}
return flags;
}

View File

@ -2743,9 +2743,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kInt32DivIsSafe |
MachineOperatorBuilder::kUint32DivIsSafe |
MachineOperatorBuilder::kWord32ReverseBits |
MachineOperatorBuilder::kWord64ReverseBits |
MachineOperatorBuilder::kFloat32Neg |
MachineOperatorBuilder::kFloat64Neg;
MachineOperatorBuilder::kWord64ReverseBits;
}
// static

View File

@ -1705,8 +1705,7 @@ MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::kWord32ShiftIsSafe |
MachineOperatorBuilder::kWord32Ctz | MachineOperatorBuilder::kFloat32Neg |
MachineOperatorBuilder::kFloat64Neg;
MachineOperatorBuilder::kWord32Ctz;
if (CpuFeatures::IsSupported(POPCNT)) {
flags |= MachineOperatorBuilder::kWord32Popcnt;
}

View File

@ -163,6 +163,7 @@ MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
V(Float32SubPreserveNan, Operator::kNoProperties, 2, 0, 1) \
V(Float32Mul, Operator::kCommutative, 2, 0, 1) \
V(Float32Div, Operator::kNoProperties, 2, 0, 1) \
V(Float32Neg, Operator::kNoProperties, 1, 0, 1) \
V(Float32Sqrt, Operator::kNoProperties, 1, 0, 1) \
V(Float64Abs, Operator::kNoProperties, 1, 0, 1) \
V(Float64Acos, Operator::kNoProperties, 1, 0, 1) \
@ -183,6 +184,7 @@ MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
V(Float64Log10, Operator::kNoProperties, 1, 0, 1) \
V(Float64Max, Operator::kNoProperties, 2, 0, 1) \
V(Float64Min, Operator::kNoProperties, 2, 0, 1) \
V(Float64Neg, Operator::kNoProperties, 1, 0, 1) \
V(Float64Add, Operator::kCommutative, 2, 0, 1) \
V(Float64Sub, Operator::kNoProperties, 2, 0, 1) \
V(Float64SubPreserveNan, Operator::kNoProperties, 2, 0, 1) \
@ -404,9 +406,7 @@ MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \
V(Float32RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \
V(Float32Neg, Operator::kNoProperties, 1, 0, 1) \
V(Float64Neg, Operator::kNoProperties, 1, 0, 1)
V(Float64RoundTiesEven, Operator::kNoProperties, 1, 0, 1)
#define OVERFLOW_OP_LIST(V) \
V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \

View File

@ -128,18 +128,16 @@ class MachineOperatorBuilder final : public ZoneObject {
kWord64Popcnt = 1u << 19,
kWord32ReverseBits = 1u << 20,
kWord64ReverseBits = 1u << 21,
kFloat32Neg = 1u << 22,
kFloat64Neg = 1u << 23,
kWord32ReverseBytes = 1u << 24,
kWord64ReverseBytes = 1u << 25,
kWord32ReverseBytes = 1u << 22,
kWord64ReverseBytes = 1u << 23,
kAllOptionalOps = kFloat32Max | kFloat32Min | kFloat64Max | kFloat64Min |
kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp |
kFloat64RoundUp | kFloat32RoundTruncate |
kFloat64RoundTruncate | kFloat64RoundTiesAway |
kFloat32RoundTiesEven | kFloat64RoundTiesEven |
kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt |
kWord32ReverseBits | kWord64ReverseBits | kFloat32Neg |
kFloat64Neg | kWord32ReverseBytes | kWord64ReverseBytes
kWord32ReverseBits | kWord64ReverseBits |
kWord32ReverseBytes | kWord64ReverseBytes
};
typedef base::Flags<Flag, unsigned> Flags;
@ -391,8 +389,8 @@ class MachineOperatorBuilder final : public ZoneObject {
const OptionalOperator Float64RoundTiesEven();
// Floating point neg.
const OptionalOperator Float32Neg();
const OptionalOperator Float64Neg();
const Operator* Float32Neg();
const Operator* Float64Neg();
// Floating point trigonometric functions (double-precision).
const Operator* Float64Acos();

View File

@ -1156,6 +1156,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kMipsAbsD:
__ abs_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
case kMipsNegS:
__ neg_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
case kMipsNegD:
__ neg_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
case kMipsSqrtD: {
__ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;

View File

@ -66,6 +66,8 @@ namespace compiler {
V(MipsSqrtD) \
V(MipsMaxD) \
V(MipsMinD) \
V(MipsNegS) \
V(MipsNegD) \
V(MipsAddPair) \
V(MipsSubPair) \
V(MipsMulPair) \

View File

@ -894,9 +894,13 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
VisitRR(this, kMipsFloat64RoundTiesEven, node);
}
void InstructionSelector::VisitFloat32Neg(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitFloat32Neg(Node* node) {
VisitRR(this, kMipsNegS, node);
}
void InstructionSelector::VisitFloat64Neg(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitFloat64Neg(Node* node) {
VisitRR(this, kMipsNegD, node);
}
void InstructionSelector::VisitFloat64Ieee754Binop(Node* node,
InstructionCode opcode) {

View File

@ -1295,6 +1295,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kMips64AbsS:
__ abs_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
case kMips64NegS:
__ neg_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
case kMips64SqrtS: {
__ sqrt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
@ -1349,6 +1352,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kMips64AbsD:
__ abs_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
case kMips64NegD:
__ neg_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
case kMips64SqrtD: {
__ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;

View File

@ -71,6 +71,7 @@ namespace compiler {
V(Mips64DivS) \
V(Mips64ModS) \
V(Mips64AbsS) \
V(Mips64NegS) \
V(Mips64SqrtS) \
V(Mips64MaxS) \
V(Mips64MinS) \
@ -82,6 +83,7 @@ namespace compiler {
V(Mips64DivD) \
V(Mips64ModD) \
V(Mips64AbsD) \
V(Mips64NegD) \
V(Mips64SqrtD) \
V(Mips64MaxD) \
V(Mips64MinD) \

View File

@ -1300,9 +1300,13 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
VisitRR(this, kMips64Float64RoundTiesEven, node);
}
void InstructionSelector::VisitFloat32Neg(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitFloat32Neg(Node* node) {
VisitRR(this, kMips64NegS, node);
}
void InstructionSelector::VisitFloat64Neg(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitFloat64Neg(Node* node) {
VisitRR(this, kMips64NegD, node);
}
void InstructionSelector::VisitFloat64Ieee754Binop(Node* node,
InstructionCode opcode) {

View File

@ -443,7 +443,7 @@ class RawMachineAssembler {
return AddNode(machine()->Float32Div(), a, b);
}
Node* Float32Abs(Node* a) { return AddNode(machine()->Float32Abs(), a); }
Node* Float32Neg(Node* a) { return Float32Sub(Float32Constant(-0.0f), a); }
Node* Float32Neg(Node* a) { return AddNode(machine()->Float32Neg(), a); }
Node* Float32Sqrt(Node* a) { return AddNode(machine()->Float32Sqrt(), a); }
Node* Float32Equal(Node* a, Node* b) {
return AddNode(machine()->Float32Equal(), a, b);
@ -487,7 +487,7 @@ class RawMachineAssembler {
return AddNode(machine()->Float64Min(), a, b);
}
Node* Float64Abs(Node* a) { return AddNode(machine()->Float64Abs(), a); }
Node* Float64Neg(Node* a) { return Float64Sub(Float64Constant(-0.0), a); }
Node* Float64Neg(Node* a) { return AddNode(machine()->Float64Neg(), a); }
Node* Float64Acos(Node* a) { return AddNode(machine()->Float64Acos(), a); }
Node* Float64Acosh(Node* a) { return AddNode(machine()->Float64Acosh(), a); }
Node* Float64Asin(Node* a) { return AddNode(machine()->Float64Asin(), a); }

View File

@ -653,12 +653,8 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input,
op = m->Float32Abs();
break;
case wasm::kExprF32Neg: {
if (m->Float32Neg().IsSupported()) {
op = m->Float32Neg().op();
op = m->Float32Neg();
break;
} else {
return BuildF32Neg(input);
}
}
case wasm::kExprF32Sqrt:
op = m->Float32Sqrt();
@ -667,12 +663,8 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input,
op = m->Float64Abs();
break;
case wasm::kExprF64Neg: {
if (m->Float64Neg().IsSupported()) {
op = m->Float64Neg().op();
op = m->Float64Neg();
break;
} else {
return BuildF64Neg(input);
}
}
case wasm::kExprF64Sqrt:
op = m->Float64Sqrt();
@ -1158,34 +1150,6 @@ Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype,
return result;
}
Node* WasmGraphBuilder::BuildF32Neg(Node* input) {
Node* result =
Unop(wasm::kExprF32ReinterpretI32,
Binop(wasm::kExprI32Xor, Unop(wasm::kExprI32ReinterpretF32, input),
jsgraph()->Int32Constant(0x80000000)));
return result;
}
Node* WasmGraphBuilder::BuildF64Neg(Node* input) {
#if WASM_64
Node* result =
Unop(wasm::kExprF64ReinterpretI64,
Binop(wasm::kExprI64Xor, Unop(wasm::kExprI64ReinterpretF64, input),
jsgraph()->Int64Constant(0x8000000000000000)));
return result;
#else
MachineOperatorBuilder* m = jsgraph()->machine();
Node* old_high_word = graph()->NewNode(m->Float64ExtractHighWord32(), input);
Node* new_high_word = Binop(wasm::kExprI32Xor, old_high_word,
jsgraph()->Int32Constant(0x80000000));
return graph()->NewNode(m->Float64InsertHighWord32(), input, new_high_word);
#endif
}
Node* WasmGraphBuilder::BuildF32CopySign(Node* left, Node* right) {
Node* result = Unop(
wasm::kExprF32ReinterpretI32,

View File

@ -248,8 +248,6 @@ class WasmGraphBuilder {
Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args,
wasm::WasmCodePosition position);
Node* BuildF32Neg(Node* input);
Node* BuildF64Neg(Node* input);
Node* BuildF32CopySign(Node* left, Node* right);
Node* BuildF64CopySign(Node* left, Node* right);
Node* BuildF32Min(Node* left, Node* right);

View File

@ -2186,8 +2186,7 @@ MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::kWord32ShiftIsSafe |
MachineOperatorBuilder::kWord32Ctz | MachineOperatorBuilder::kWord64Ctz |
MachineOperatorBuilder::kFloat32Neg | MachineOperatorBuilder::kFloat64Neg;
MachineOperatorBuilder::kWord32Ctz | MachineOperatorBuilder::kWord64Ctz;
if (CpuFeatures::IsSupported(POPCNT)) {
flags |= MachineOperatorBuilder::kWord32Popcnt |
MachineOperatorBuilder::kWord64Popcnt;

View File

@ -3604,8 +3604,7 @@ TEST(RunFloat32Sub) {
TEST(RunFloat32Neg) {
BufferedRawMachineAssemblerTester<float> m(MachineType::Float32());
if (!m.machine()->Float32Neg().IsSupported()) return;
m.Return(m.AddNode(m.machine()->Float32Neg().op(), m.Parameter(0)));
m.Return(m.AddNode(m.machine()->Float32Neg(), m.Parameter(0)));
FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(-0.0f - *i, m.Call(*i)); }
}
@ -3654,8 +3653,7 @@ TEST(RunFloat64Sub) {
TEST(RunFloat64Neg) {
BufferedRawMachineAssemblerTester<double> m(MachineType::Float64());
if (!m.machine()->Float64Neg().IsSupported()) return;
m.Return(m.AddNode(m.machine()->Float64Neg().op(), m.Parameter(0)));
m.Return(m.AddNode(m.machine()->Float64Neg(), m.Parameter(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_FLOAT_EQ(-0.0 - *i, m.Call(*i)); }
}

View File

@ -3269,7 +3269,7 @@ TEST_F(InstructionSelectorTest, Float32Neg) {
StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
Node* const p0 = m.Parameter(0);
// Don't use m.Float32Neg() as that generates an explicit sub.
Node* const n = m.AddNode(m.machine()->Float32Neg().op(), m.Parameter(0));
Node* const n = m.AddNode(m.machine()->Float32Neg(), m.Parameter(0));
m.Return(n);
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@ -3284,7 +3284,7 @@ TEST_F(InstructionSelectorTest, Float64Neg) {
StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
Node* const p0 = m.Parameter(0);
// Don't use m.Float64Neg() as that generates an explicit sub.
Node* const n = m.AddNode(m.machine()->Float64Neg().op(), m.Parameter(0));
Node* const n = m.AddNode(m.machine()->Float64Neg(), m.Parameter(0));
m.Return(n);
Stream s = m.Build();
ASSERT_EQ(1U, s.size());

View File

@ -4273,7 +4273,7 @@ TEST_F(InstructionSelectorTest, Float32Neg) {
StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
Node* const p0 = m.Parameter(0);
// Don't use m.Float32Neg() as that generates an explicit sub.
Node* const n = m.AddNode(m.machine()->Float32Neg().op(), m.Parameter(0));
Node* const n = m.AddNode(m.machine()->Float32Neg(), m.Parameter(0));
m.Return(n);
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
@ -4288,7 +4288,7 @@ TEST_F(InstructionSelectorTest, Float64Neg) {
StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
Node* const p0 = m.Parameter(0);
// Don't use m.Float64Neg() as that generates an explicit sub.
Node* const n = m.AddNode(m.machine()->Float64Neg().op(), m.Parameter(0));
Node* const n = m.AddNode(m.machine()->Float64Neg(), m.Parameter(0));
m.Return(n);
Stream s = m.Build();
ASSERT_EQ(1U, s.size());

View File

@ -247,6 +247,7 @@ const PureOperator kPureOperators[] = {
PURE(Float32Equal, 2, 0, 1), // --
PURE(Float32LessThan, 2, 0, 1), // --
PURE(Float32LessThanOrEqual, 2, 0, 1), // --
PURE(Float32Neg, 1, 0, 1), // --
PURE(Float64Abs, 1, 0, 1), // --
PURE(Float64Add, 2, 0, 1), // --
PURE(Float64Sub, 2, 0, 1), // --
@ -264,6 +265,7 @@ const PureOperator kPureOperators[] = {
PURE(Float64ExtractHighWord32, 1, 0, 1), // --
PURE(Float64InsertLowWord32, 2, 0, 1), // --
PURE(Float64InsertHighWord32, 2, 0, 1), // --
PURE(Float64Neg, 1, 0, 1), // --
#undef PURE
};
@ -323,8 +325,6 @@ const OptionalOperatorEntry kOptionalOperators[] = {
OPTIONAL_ENTRY(Float64RoundDown, 1, 0, 1), // --
OPTIONAL_ENTRY(Float64RoundTruncate, 1, 0, 1), // --
OPTIONAL_ENTRY(Float64RoundTiesAway, 1, 0, 1), // --
OPTIONAL_ENTRY(Float32Neg, 1, 0, 1), // --
OPTIONAL_ENTRY(Float64Neg, 1, 0, 1), // --
#undef OPTIONAL_ENTRY
};
} // namespace