Commit ab5a0e2f authored by jyan's avatar jyan Committed by Commit bot

[turbofan] introduce Int32/64AbsWithOverflow optional operator

some arch like s390 has native instr can benefit from this.
see ~10% improvement on MathAbs on s390

Review-Url: https://codereview.chromium.org/2785773002
Cr-Commit-Position: refs/heads/master@{#44310}
parent 591562c1
...@@ -48,36 +48,45 @@ TF_BUILTIN(MathAbs, CodeStubAssembler) { ...@@ -48,36 +48,45 @@ TF_BUILTIN(MathAbs, CodeStubAssembler) {
Bind(&if_xissmi); Bind(&if_xissmi);
{ {
// Check if {x} is already positive. Label if_overflow(this, Label::kDeferred), if_notoverflow(this);
Label if_xispositive(this), if_xisnotpositive(this); Node* pair = NULL;
BranchIfSmiLessThanOrEqual(SmiConstant(Smi::FromInt(0)), x,
&if_xispositive, &if_xisnotpositive);
Bind(&if_xispositive); // check if support abs function
{ if (IsIntPtrAbsWithOverflowSupported()) {
// Just return the input {x}. pair = IntPtrAbsWithOverflow(x);
Return(x);
}
Bind(&if_xisnotpositive);
{
// Try to negate the {x} value.
Node* pair =
IntPtrSubWithOverflow(IntPtrConstant(0), BitcastTaggedToWord(x));
Node* overflow = Projection(1, pair); Node* overflow = Projection(1, pair);
Label if_overflow(this, Label::kDeferred), if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow); Branch(overflow, &if_overflow, &if_notoverflow);
} else {
// Check if {x} is already positive.
Label if_xispositive(this), if_xisnotpositive(this);
BranchIfSmiLessThanOrEqual(SmiConstant(Smi::FromInt(0)), x,
&if_xispositive, &if_xisnotpositive);
Bind(&if_xispositive);
{
// Just return the input {x}.
Return(x);
}
Bind(&if_notoverflow); Bind(&if_xisnotpositive);
{ {
// There is a Smi representation for negated {x}. // Try to negate the {x} value.
Node* result = Projection(0, pair); pair =
Return(BitcastWordToTagged(result)); IntPtrSubWithOverflow(IntPtrConstant(0), BitcastTaggedToWord(x));
Node* overflow = Projection(1, pair);
Branch(overflow, &if_overflow, &if_notoverflow);
} }
}
Bind(&if_overflow); Bind(&if_notoverflow);
{ Return(NumberConstant(0.0 - Smi::kMinValue)); } {
// There is a Smi representation for negated {x}.
Node* result = Projection(0, pair);
Return(BitcastWordToTagged(result));
} }
Bind(&if_overflow);
{ Return(NumberConstant(0.0 - Smi::kMinValue)); }
} }
Bind(&if_xisnotsmi); Bind(&if_xisnotsmi);
......
...@@ -2483,6 +2483,14 @@ SIMD_BINOP_LIST(SIMD_VISIT_BINOP) ...@@ -2483,6 +2483,14 @@ SIMD_BINOP_LIST(SIMD_VISIT_BINOP)
SIMD_FORMAT_LIST(SIMD_VISIT_SELECT_OP) SIMD_FORMAT_LIST(SIMD_VISIT_SELECT_OP)
#undef SIMD_VISIT_SELECT_OP #undef SIMD_VISIT_SELECT_OP
void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
UNREACHABLE();
}
void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -2782,6 +2782,14 @@ void InstructionSelector::VisitAtomicCompareExchange(Node* node) { ...@@ -2782,6 +2782,14 @@ void InstructionSelector::VisitAtomicCompareExchange(Node* node) {
Emit(code, 1, outputs, input_count, inputs, 2, temp); Emit(code, 1, outputs, input_count, inputs, 2, temp);
} }
void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
UNREACHABLE();
}
void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -165,6 +165,19 @@ bool CodeAssembler::IsFloat64RoundTruncateSupported() const { ...@@ -165,6 +165,19 @@ bool CodeAssembler::IsFloat64RoundTruncateSupported() const {
return raw_assembler()->machine()->Float64RoundTruncate().IsSupported(); return raw_assembler()->machine()->Float64RoundTruncate().IsSupported();
} }
bool CodeAssembler::IsInt32AbsWithOverflowSupported() const {
return raw_assembler()->machine()->Int32AbsWithOverflow().IsSupported();
}
bool CodeAssembler::IsInt64AbsWithOverflowSupported() const {
return raw_assembler()->machine()->Int64AbsWithOverflow().IsSupported();
}
bool CodeAssembler::IsIntPtrAbsWithOverflowSupported() const {
return Is64() ? IsInt64AbsWithOverflowSupported()
: IsInt32AbsWithOverflowSupported();
}
Node* CodeAssembler::Int32Constant(int32_t value) { Node* CodeAssembler::Int32Constant(int32_t value) {
return raw_assembler()->Int32Constant(value); return raw_assembler()->Int32Constant(value);
} }
......
...@@ -167,6 +167,9 @@ typedef std::function<void()> CodeAssemblerCallback; ...@@ -167,6 +167,9 @@ typedef std::function<void()> CodeAssemblerCallback;
V(Float64RoundTruncate) \ V(Float64RoundTruncate) \
V(Word32Clz) \ V(Word32Clz) \
V(Word32Not) \ V(Word32Not) \
V(Int32AbsWithOverflow) \
V(Int64AbsWithOverflow) \
V(IntPtrAbsWithOverflow) \
V(Word32BinaryNot) V(Word32BinaryNot)
// A "public" interface used by components outside of compiler directory to // A "public" interface used by components outside of compiler directory to
...@@ -201,6 +204,9 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -201,6 +204,9 @@ class V8_EXPORT_PRIVATE CodeAssembler {
bool IsFloat64RoundDownSupported() const; bool IsFloat64RoundDownSupported() const;
bool IsFloat64RoundTiesEvenSupported() const; bool IsFloat64RoundTiesEvenSupported() const;
bool IsFloat64RoundTruncateSupported() const; bool IsFloat64RoundTruncateSupported() const;
bool IsInt32AbsWithOverflowSupported() const;
bool IsInt64AbsWithOverflowSupported() const;
bool IsIntPtrAbsWithOverflowSupported() const;
// Shortened aliases for use in CodeAssembler subclasses. // Shortened aliases for use in CodeAssembler subclasses.
typedef CodeAssemblerLabel Label; typedef CodeAssemblerLabel Label;
......
...@@ -1838,6 +1838,14 @@ void InstructionSelector::VisitI32x4ReplaceLane(Node* node) { ...@@ -1838,6 +1838,14 @@ void InstructionSelector::VisitI32x4ReplaceLane(Node* node) {
g.Use(node->InputAt(1))); g.Use(node->InputAt(1)));
} }
void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
UNREACHABLE();
}
void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -1126,6 +1126,8 @@ void InstructionSelector::VisitNode(Node* node) { ...@@ -1126,6 +1126,8 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsWord32(node), VisitWord32ReverseBits(node); return MarkAsWord32(node), VisitWord32ReverseBits(node);
case IrOpcode::kWord32ReverseBytes: case IrOpcode::kWord32ReverseBytes:
return MarkAsWord32(node), VisitWord32ReverseBytes(node); return MarkAsWord32(node), VisitWord32ReverseBytes(node);
case IrOpcode::kInt32AbsWithOverflow:
return MarkAsWord32(node), VisitInt32AbsWithOverflow(node);
case IrOpcode::kWord32Popcnt: case IrOpcode::kWord32Popcnt:
return MarkAsWord32(node), VisitWord32Popcnt(node); return MarkAsWord32(node), VisitWord32Popcnt(node);
case IrOpcode::kWord64Popcnt: case IrOpcode::kWord64Popcnt:
...@@ -1152,6 +1154,8 @@ void InstructionSelector::VisitNode(Node* node) { ...@@ -1152,6 +1154,8 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsWord64(node), VisitWord64ReverseBits(node); return MarkAsWord64(node), VisitWord64ReverseBits(node);
case IrOpcode::kWord64ReverseBytes: case IrOpcode::kWord64ReverseBytes:
return MarkAsWord64(node), VisitWord64ReverseBytes(node); return MarkAsWord64(node), VisitWord64ReverseBytes(node);
case IrOpcode::kInt64AbsWithOverflow:
return MarkAsWord64(node), VisitInt64AbsWithOverflow(node);
case IrOpcode::kWord64Equal: case IrOpcode::kWord64Equal:
return VisitWord64Equal(node); return VisitWord64Equal(node);
case IrOpcode::kInt32Add: case IrOpcode::kInt32Add:
...@@ -2392,6 +2396,8 @@ void InstructionSelector::VisitProjection(Node* node) { ...@@ -2392,6 +2396,8 @@ void InstructionSelector::VisitProjection(Node* node) {
case IrOpcode::kWord32PairShl: case IrOpcode::kWord32PairShl:
case IrOpcode::kWord32PairShr: case IrOpcode::kWord32PairShr:
case IrOpcode::kWord32PairSar: case IrOpcode::kWord32PairSar:
case IrOpcode::kInt32AbsWithOverflow:
case IrOpcode::kInt64AbsWithOverflow:
if (ProjectionIndexOf(node->op()) == 0u) { if (ProjectionIndexOf(node->op()) == 0u) {
Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
} else { } else {
......
...@@ -346,6 +346,8 @@ MachineType AtomicCompareExchangeRepresentationOf(Operator const* op) { ...@@ -346,6 +346,8 @@ MachineType AtomicCompareExchangeRepresentationOf(Operator const* op) {
V(Word64ReverseBits, Operator::kNoProperties, 1, 0, 1) \ V(Word64ReverseBits, Operator::kNoProperties, 1, 0, 1) \
V(Word32ReverseBytes, Operator::kNoProperties, 1, 0, 1) \ V(Word32ReverseBytes, Operator::kNoProperties, 1, 0, 1) \
V(Word64ReverseBytes, Operator::kNoProperties, 1, 0, 1) \ V(Word64ReverseBytes, Operator::kNoProperties, 1, 0, 1) \
V(Int32AbsWithOverflow, Operator::kNoProperties, 1, 0, 1) \
V(Int64AbsWithOverflow, Operator::kNoProperties, 1, 0, 1) \
V(Word32Popcnt, Operator::kNoProperties, 1, 0, 1) \ V(Word32Popcnt, Operator::kNoProperties, 1, 0, 1) \
V(Word64Popcnt, Operator::kNoProperties, 1, 0, 1) \ V(Word64Popcnt, Operator::kNoProperties, 1, 0, 1) \
V(Float32RoundDown, Operator::kNoProperties, 1, 0, 1) \ V(Float32RoundDown, Operator::kNoProperties, 1, 0, 1) \
......
...@@ -131,13 +131,15 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final ...@@ -131,13 +131,15 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
kWord64ReverseBits = 1u << 17, kWord64ReverseBits = 1u << 17,
kWord32ReverseBytes = 1u << 18, kWord32ReverseBytes = 1u << 18,
kWord64ReverseBytes = 1u << 19, kWord64ReverseBytes = 1u << 19,
kAllOptionalOps = kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp | kInt32AbsWithOverflow = 1u << 20,
kFloat64RoundUp | kFloat32RoundTruncate | kInt64AbsWithOverflow = 1u << 21,
kFloat64RoundTruncate | kFloat64RoundTiesAway | kAllOptionalOps =
kFloat32RoundTiesEven | kFloat64RoundTiesEven | kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp |
kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt | kFloat64RoundUp | kFloat32RoundTruncate | kFloat64RoundTruncate |
kWord32ReverseBits | kWord64ReverseBits | kFloat64RoundTiesAway | kFloat32RoundTiesEven | kFloat64RoundTiesEven |
kWord32ReverseBytes | kWord64ReverseBytes kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt |
kWord32ReverseBits | kWord64ReverseBits | kWord32ReverseBytes |
kWord64ReverseBytes | kInt32AbsWithOverflow | kInt64AbsWithOverflow
}; };
typedef base::Flags<Flag, unsigned> Flags; typedef base::Flags<Flag, unsigned> Flags;
...@@ -232,6 +234,8 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final ...@@ -232,6 +234,8 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
const OptionalOperator Word64ReverseBits(); const OptionalOperator Word64ReverseBits();
const OptionalOperator Word32ReverseBytes(); const OptionalOperator Word32ReverseBytes();
const OptionalOperator Word64ReverseBytes(); const OptionalOperator Word64ReverseBytes();
const OptionalOperator Int32AbsWithOverflow();
const OptionalOperator Int64AbsWithOverflow();
bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; } bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
const Operator* Word64And(); const Operator* Word64And();
......
...@@ -1891,6 +1891,14 @@ void InstructionSelector::VisitAtomicCompareExchange(Node* node) { ...@@ -1891,6 +1891,14 @@ void InstructionSelector::VisitAtomicCompareExchange(Node* node) {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
UNREACHABLE();
}
void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -2642,6 +2642,14 @@ void InstructionSelector::VisitAtomicCompareExchange(Node* node) { ...@@ -2642,6 +2642,14 @@ void InstructionSelector::VisitAtomicCompareExchange(Node* node) {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
UNREACHABLE();
}
void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -380,6 +380,7 @@ ...@@ -380,6 +380,7 @@
#define MACHINE_UNOP_32_LIST(V) \ #define MACHINE_UNOP_32_LIST(V) \
V(Word32Clz) \ V(Word32Clz) \
V(Word32Ctz) \ V(Word32Ctz) \
V(Int32AbsWithOverflow) \
V(Word32ReverseBits) \ V(Word32ReverseBits) \
V(Word32ReverseBytes) V(Word32ReverseBytes)
...@@ -499,6 +500,7 @@ ...@@ -499,6 +500,7 @@
V(Word64Ctz) \ V(Word64Ctz) \
V(Word64ReverseBits) \ V(Word64ReverseBits) \
V(Word64ReverseBytes) \ V(Word64ReverseBytes) \
V(Int64AbsWithOverflow) \
V(BitcastTaggedToWord) \ V(BitcastTaggedToWord) \
V(BitcastWordToTagged) \ V(BitcastWordToTagged) \
V(BitcastWordToTaggedSigned) \ V(BitcastWordToTaggedSigned) \
......
...@@ -2155,6 +2155,14 @@ void InstructionSelector::VisitAtomicCompareExchange(Node* node) { ...@@ -2155,6 +2155,14 @@ void InstructionSelector::VisitAtomicCompareExchange(Node* node) {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
UNREACHABLE();
}
void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -439,6 +439,19 @@ class V8_EXPORT_PRIVATE RawMachineAssembler { ...@@ -439,6 +439,19 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
#undef UINTPTR_BINOP #undef UINTPTR_BINOP
Node* Int32AbsWithOverflow(Node* a) {
return AddNode(machine()->Int32AbsWithOverflow().op(), a);
}
Node* Int64AbsWithOverflow(Node* a) {
return AddNode(machine()->Int64AbsWithOverflow().op(), a);
}
Node* IntPtrAbsWithOverflow(Node* a) {
return kPointerSize == 8 ? Int64AbsWithOverflow(a)
: Int32AbsWithOverflow(a);
}
Node* Float32Add(Node* a, Node* b) { Node* Float32Add(Node* a, Node* b) {
return AddNode(machine()->Float32Add(), a, b); return AddNode(machine()->Float32Add(), a, b);
} }
......
...@@ -309,6 +309,8 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) { ...@@ -309,6 +309,8 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
case kS390_Add64: case kS390_Add64:
case kS390_Sub32: case kS390_Sub32:
case kS390_Sub64: case kS390_Sub64:
case kS390_Abs64:
case kS390_Abs32:
return overflow; return overflow;
default: default:
break; break;
...@@ -1347,6 +1349,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1347,6 +1349,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Operand(offset.offset())); Operand(offset.offset()));
break; break;
} }
case kS390_Abs32:
// TODO(john.yan): zero-ext
__ lpr(i.OutputRegister(0), i.InputRegister(0));
break;
case kS390_Abs64:
__ lpgr(i.OutputRegister(0), i.InputRegister(0));
break;
case kS390_And32: case kS390_And32:
// zero-ext // zero-ext
if (CpuFeatures::IsSupported(DISTINCT_OPS)) { if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
...@@ -1855,6 +1864,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1855,6 +1864,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
if (HasRegisterInput(instr, 1)) { if (HasRegisterInput(instr, 1)) {
__ And(r0, i.InputRegister(0), i.InputRegister(1)); __ And(r0, i.InputRegister(0), i.InputRegister(1));
} else { } else {
// detect tmlh/tmhl/tmhh case
Operand opnd = i.InputImmediate(1); Operand opnd = i.InputImmediate(1);
if (is_uint16(opnd.immediate())) { if (is_uint16(opnd.immediate())) {
__ tmll(i.InputRegister(0), opnd); __ tmll(i.InputRegister(0), opnd);
......
...@@ -12,6 +12,8 @@ namespace compiler { ...@@ -12,6 +12,8 @@ namespace compiler {
// S390-specific opcodes that specify which assembly sequence to emit. // S390-specific opcodes that specify which assembly sequence to emit.
// Most opcodes specify a single instruction. // Most opcodes specify a single instruction.
#define TARGET_ARCH_OPCODE_LIST(V) \ #define TARGET_ARCH_OPCODE_LIST(V) \
V(S390_Abs32) \
V(S390_Abs64) \
V(S390_And32) \ V(S390_And32) \
V(S390_And64) \ V(S390_And64) \
V(S390_Or32) \ V(S390_Or32) \
......
...@@ -13,6 +13,8 @@ bool InstructionScheduler::SchedulerSupported() { return true; } ...@@ -13,6 +13,8 @@ bool InstructionScheduler::SchedulerSupported() { return true; }
int InstructionScheduler::GetTargetInstructionFlags( int InstructionScheduler::GetTargetInstructionFlags(
const Instruction* instr) const { const Instruction* instr) const {
switch (instr->arch_opcode()) { switch (instr->arch_opcode()) {
case kS390_Abs32:
case kS390_Abs64:
case kS390_And32: case kS390_And32:
case kS390_And64: case kS390_And64:
case kS390_Or32: case kS390_Or32:
......
...@@ -389,6 +389,11 @@ bool ProduceWord32Result(Node* node) { ...@@ -389,6 +389,11 @@ bool ProduceWord32Result(Node* node) {
switch (load_rep.representation()) { switch (load_rep.representation()) {
case MachineRepresentation::kWord32: case MachineRepresentation::kWord32:
return true; return true;
case MachineRepresentation::kWord8:
if (load_rep.IsSigned())
return false;
else
return true;
default: default:
return false; return false;
} }
...@@ -515,6 +520,8 @@ void VisitBinOp(InstructionSelector* selector, Node* node, ...@@ -515,6 +520,8 @@ void VisitBinOp(InstructionSelector* selector, Node* node,
V(Word32, Unary, [](ArchOpcode opcode) { \ V(Word32, Unary, [](ArchOpcode opcode) { \
return opcode == kS390_LoadWordS32 || opcode == kS390_LoadWordU32; \ return opcode == kS390_LoadWordS32 || opcode == kS390_LoadWordU32; \
}) \ }) \
V(Word64, Unary, \
[](ArchOpcode opcode) { return opcode == kS390_LoadWord64; }) \
V(Float32, Unary, \ V(Float32, Unary, \
[](ArchOpcode opcode) { return opcode == kS390_LoadFloat32; }) \ [](ArchOpcode opcode) { return opcode == kS390_LoadFloat32; }) \
V(Float64, Unary, \ V(Float64, Unary, \
...@@ -529,8 +536,6 @@ void VisitBinOp(InstructionSelector* selector, Node* node, ...@@ -529,8 +536,6 @@ void VisitBinOp(InstructionSelector* selector, Node* node,
#if V8_TARGET_ARCH_S390X #if V8_TARGET_ARCH_S390X
#define VISIT_OP_LIST(V) \ #define VISIT_OP_LIST(V) \
VISIT_OP_LIST_32(V) \ VISIT_OP_LIST_32(V) \
V(Word64, Unary, \
[](ArchOpcode opcode) { return opcode == kS390_LoadWord64; }) \
V(Word64, Bin, [](ArchOpcode opcode) { return opcode == kS390_LoadWord64; }) V(Word64, Bin, [](ArchOpcode opcode) { return opcode == kS390_LoadWord64; })
#else #else
#define VISIT_OP_LIST VISIT_OP_LIST_32 #define VISIT_OP_LIST VISIT_OP_LIST_32
...@@ -1242,6 +1247,14 @@ void InstructionSelector::VisitWord32ReverseBits(Node* node) { UNREACHABLE(); } ...@@ -1242,6 +1247,14 @@ void InstructionSelector::VisitWord32ReverseBits(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitWord64ReverseBits(Node* node) { UNREACHABLE(); } void InstructionSelector::VisitWord64ReverseBits(Node* node) { UNREACHABLE(); }
#endif #endif
void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
VisitWord32UnaryOp(this, node, kS390_Abs32, OperandMode::kNone);
}
void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
VisitWord64UnaryOp(this, node, kS390_Abs64, OperandMode::kNone);
}
void InstructionSelector::VisitWord64ReverseBytes(Node* node) { void InstructionSelector::VisitWord64ReverseBytes(Node* node) {
S390OperandGenerator g(this); S390OperandGenerator g(this);
Emit(kS390_LoadReverse64RR, g.DefineAsRegister(node), Emit(kS390_LoadReverse64RR, g.DefineAsRegister(node),
...@@ -2037,7 +2050,15 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, ...@@ -2037,7 +2050,15 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
selector, node, kS390_Mul32WithOverflow, selector, node, kS390_Mul32WithOverflow,
OperandMode::kInt32Imm | OperandMode::kAllowDistinctOps, OperandMode::kInt32Imm | OperandMode::kAllowDistinctOps,
cont); cont);
case IrOpcode::kInt32AbsWithOverflow:
cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitWord32UnaryOp(selector, node, kS390_Abs32,
OperandMode::kNone, cont);
#if V8_TARGET_ARCH_S390X #if V8_TARGET_ARCH_S390X
case IrOpcode::kInt64AbsWithOverflow:
cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitWord64UnaryOp(selector, node, kS390_Abs64,
OperandMode::kNone, cont);
case IrOpcode::kInt64AddWithOverflow: case IrOpcode::kInt64AddWithOverflow:
cont->OverwriteAndNegateIfEqual(kOverflow); cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitWord64BinOp(selector, node, kS390_Add64, return VisitWord64BinOp(selector, node, kS390_Add64,
...@@ -2450,6 +2471,8 @@ InstructionSelector::SupportedMachineOperatorFlags() { ...@@ -2450,6 +2471,8 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kWord32Popcnt | MachineOperatorBuilder::kWord32Popcnt |
MachineOperatorBuilder::kWord32ReverseBytes | MachineOperatorBuilder::kWord32ReverseBytes |
MachineOperatorBuilder::kWord64ReverseBytes | MachineOperatorBuilder::kWord64ReverseBytes |
MachineOperatorBuilder::kInt32AbsWithOverflow |
MachineOperatorBuilder::kInt64AbsWithOverflow |
MachineOperatorBuilder::kWord64Popcnt; MachineOperatorBuilder::kWord64Popcnt;
} }
......
...@@ -1270,6 +1270,7 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -1270,6 +1270,7 @@ void Verifier::Visitor::Check(Node* node) {
case IrOpcode::kWord32Ctz: case IrOpcode::kWord32Ctz:
case IrOpcode::kWord32ReverseBits: case IrOpcode::kWord32ReverseBits:
case IrOpcode::kWord32ReverseBytes: case IrOpcode::kWord32ReverseBytes:
case IrOpcode::kInt32AbsWithOverflow:
case IrOpcode::kWord32Popcnt: case IrOpcode::kWord32Popcnt:
case IrOpcode::kWord64And: case IrOpcode::kWord64And:
case IrOpcode::kWord64Or: case IrOpcode::kWord64Or:
...@@ -1283,6 +1284,7 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -1283,6 +1284,7 @@ void Verifier::Visitor::Check(Node* node) {
case IrOpcode::kWord64Ctz: case IrOpcode::kWord64Ctz:
case IrOpcode::kWord64ReverseBits: case IrOpcode::kWord64ReverseBits:
case IrOpcode::kWord64ReverseBytes: case IrOpcode::kWord64ReverseBytes:
case IrOpcode::kInt64AbsWithOverflow:
case IrOpcode::kWord64Equal: case IrOpcode::kWord64Equal:
case IrOpcode::kInt32Add: case IrOpcode::kInt32Add:
case IrOpcode::kInt32AddWithOverflow: case IrOpcode::kInt32AddWithOverflow:
......
...@@ -2469,6 +2469,14 @@ void InstructionSelector::VisitS32x4Select(Node* node) { ...@@ -2469,6 +2469,14 @@ void InstructionSelector::VisitS32x4Select(Node* node) {
g.UseRegister(node->InputAt(2))); g.UseRegister(node->InputAt(2)));
} }
void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
UNREACHABLE();
}
void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -1833,6 +1833,14 @@ void InstructionSelector::VisitAtomicStore(Node* node) { ...@@ -1833,6 +1833,14 @@ void InstructionSelector::VisitAtomicStore(Node* node) {
Emit(code, 0, nullptr, input_count, inputs); Emit(code, 0, nullptr, input_count, inputs);
} }
void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
UNREACHABLE();
}
void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -1067,10 +1067,10 @@ bool Decoder::DecodeFourByte(Instruction* instr) { ...@@ -1067,10 +1067,10 @@ bool Decoder::DecodeFourByte(Instruction* instr) {
break; break;
} }
case LPGR: case LPGR:
Format(instr, "lpgr\t'r1, 'r2"); Format(instr, "lpgr\t'r5,'r6");
break; break;
case LPGFR: case LPGFR:
Format(instr, "lpgfr\t'r1,'r2"); Format(instr, "lpgfr\t'r5,'r6");
break; break;
default: default:
return false; return false;
......
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