[turboshaft] Add more operators for wasm

Bug: v8:12783
Change-Id: I09dcdfcf244af830380ca734859a46dd489e3836
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3909808
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83381}
This commit is contained in:
Manos Koukoutos 2022-09-22 10:38:56 +02:00 committed by V8 LUCI CQ
parent 24de62081e
commit 53c13108c4
5 changed files with 95 additions and 4 deletions

View File

@ -367,6 +367,18 @@ class AssemblerInterface : public Superclass {
WordRepresentation::Word32())
DECL_SINGLE_REP_UNARY(Word64PopCount, WordUnary, PopCount,
WordRepresentation::Word64())
DECL_MULTI_REP_UNARY(WordSignExtend8, WordUnary, WordRepresentation,
SignExtend8)
DECL_SINGLE_REP_UNARY(Word32SignExtend8, WordUnary, SignExtend8,
WordRepresentation::Word32())
DECL_SINGLE_REP_UNARY(Word64SignExtend8, WordUnary, SignExtend8,
WordRepresentation::Word64())
DECL_MULTI_REP_UNARY(WordSignExtend16, WordUnary, WordRepresentation,
SignExtend16)
DECL_SINGLE_REP_UNARY(Word32SignExtend16, WordUnary, SignExtend16,
WordRepresentation::Word32())
DECL_SINGLE_REP_UNARY(Word64SignExtend16, WordUnary, SignExtend16,
WordRepresentation::Word64())
#undef DECL_SINGLE_REP_UNARY
#undef DECL_MULTI_REP_UNARY

View File

@ -436,6 +436,10 @@ OpIndex GraphBuilder::Process(
UNARY_CASE(Word64Ctz, Word64CountTrailingZeros)
UNARY_CASE(Word32Popcnt, Word32PopCount)
UNARY_CASE(Word64Popcnt, Word64PopCount)
UNARY_CASE(SignExtendWord8ToInt32, Word32SignExtend8)
UNARY_CASE(SignExtendWord16ToInt32, Word32SignExtend16)
UNARY_CASE(SignExtendWord8ToInt64, Word64SignExtend8)
UNARY_CASE(SignExtendWord16ToInt64, Word64SignExtend16)
UNARY_CASE(Float32Abs, Float32Abs)
UNARY_CASE(Float64Abs, Float64Abs)
@ -505,6 +509,19 @@ OpIndex GraphBuilder::Process(
CHANGE_CASE(ChangeFloat64ToUint32, UnsignedNarrowing, Float64, Word32)
CHANGE_CASE(ChangeFloat64ToInt64, SignedNarrowing, Float64, Word64)
CHANGE_CASE(ChangeFloat64ToUint64, UnsignedNarrowing, Float64, Word64)
CHANGE_CASE(TryTruncateFloat64ToUint64, UnsignedFloatTruncateSat, Float64,
Word64)
CHANGE_CASE(TryTruncateFloat64ToUint32, UnsignedFloatTruncateSat, Float64,
Word32)
CHANGE_CASE(TryTruncateFloat32ToUint64, UnsignedFloatTruncateSat, Float32,
Word64)
CHANGE_CASE(TryTruncateFloat64ToInt64, SignedFloatTruncateSat, Float64,
Word64)
CHANGE_CASE(TryTruncateFloat64ToInt32, SignedFloatTruncateSat, Float64,
Word32)
CHANGE_CASE(TryTruncateFloat32ToInt64, SignedFloatTruncateSat, Float32,
Word64)
CHANGE_CASE(Float64ExtractLowWord32, ExtractLowHalf, Float64, Word32)
CHANGE_CASE(Float64ExtractHighWord32, ExtractHighHalf, Float64, Word32)
#undef CHANGE_CASE
@ -541,6 +558,11 @@ OpIndex GraphBuilder::Process(
RegisterRepresentation::Float64(),
RegisterRepresentation::Word64());
}
case IrOpcode::kTruncateFloat64ToUint32: {
return assembler.Change(
Map(node->InputAt(0)), ChangeOp::Kind::kUnsignedFloatTruncate,
RegisterRepresentation::Float64(), RegisterRepresentation::Word32());
}
case IrOpcode::kFloat64InsertLowWord32:
return assembler.Float64InsertWord32(
Map(node->InputAt(0)), Map(node->InputAt(1)),

View File

@ -51,6 +51,10 @@ std::ostream& operator<<(std::ostream& os, WordUnaryOp::Kind kind) {
return os << "CountTrailingZeros";
case WordUnaryOp::Kind::kPopCount:
return os << "PopCount";
case WordUnaryOp::Kind::kSignExtend8:
return os << "SignExtend8";
case WordUnaryOp::Kind::kSignExtend16:
return os << "SignExtend16";
}
}
@ -150,6 +154,8 @@ bool WordUnaryOp::IsSupported(Kind kind, WordRepresentation rep) {
switch (kind) {
case Kind::kCountLeadingZeros:
case Kind::kReverseBytes:
case Kind::kSignExtend8:
case Kind::kSignExtend16:
return true;
case Kind::kCountTrailingZeros:
return rep == WordRepresentation::Word32()
@ -224,6 +230,10 @@ std::ostream& operator<<(std::ostream& os, ChangeOp::Kind kind) {
return os << "SignExtend";
case ChangeOp::Kind::kBitcast:
return os << "Bitcast";
case ChangeOp::Kind::kSignedFloatTruncateSat:
return os << "SignedFloatTruncateSat";
case ChangeOp::Kind::kUnsignedFloatTruncateSat:
return os << "UnsignedFloatTruncateSat";
}
}

View File

@ -726,6 +726,8 @@ struct WordUnaryOp : FixedArityOperationT<1, WordUnaryOp> {
kCountLeadingZeros,
kCountTrailingZeros,
kPopCount,
kSignExtend8,
kSignExtend16,
};
Kind kind;
WordRepresentation rep;
@ -898,12 +900,16 @@ struct ChangeOp : FixedArityOperationT<1, ChangeOp> {
// like kSignedFloatTruncate, but overflow guaranteed to result in the
// minimal integer
kSignedFloatTruncateOverflowToMin,
// like kSignedFloatTruncate, but saturates to min/max value if overflow
kSignedFloatTruncateSat,
// conversion to unsigned integer, rounding towards zero,
// overflow behavior system-specific
kUnsignedFloatTruncate,
// like kUnsignedFloatTruncate, but overflow guaranteed to result in the
// minimal integer
kUnsignedFloatTruncateOverflowToMin,
// like kUnsignedFloatTruncate, but saturates to 0/max value if overflow
kUnsignedFloatTruncateSat,
// JS semantics float64 to word32 truncation
// https://tc39.es/ecma262/#sec-touint32
kJSFloatTruncate,

View File

@ -359,8 +359,6 @@ Node* ScheduleBuilder::ProcessOperation(const OverflowCheckedBinopOp& op) {
return AddNode(o, {GetNode(op.left()), GetNode(op.right())});
}
Node* ScheduleBuilder::ProcessOperation(const WordUnaryOp& op) {
DCHECK(op.rep == WordRepresentation::Word32() ||
op.rep == WordRepresentation::Word64());
bool word64 = op.rep == WordRepresentation::Word64();
const Operator* o;
switch (op.kind) {
@ -376,12 +374,18 @@ Node* ScheduleBuilder::ProcessOperation(const WordUnaryOp& op) {
case WordUnaryOp::Kind::kPopCount:
o = word64 ? machine.Word64Popcnt().op() : machine.Word32Popcnt().op();
break;
case WordUnaryOp::Kind::kSignExtend8:
o = word64 ? machine.SignExtendWord8ToInt64()
: machine.SignExtendWord8ToInt32();
break;
case WordUnaryOp::Kind::kSignExtend16:
o = word64 ? machine.SignExtendWord16ToInt64()
: machine.SignExtendWord16ToInt32();
break;
}
return AddNode(o, {GetNode(op.input())});
}
Node* ScheduleBuilder::ProcessOperation(const FloatUnaryOp& op) {
DCHECK(op.rep == FloatRepresentation::Float32() ||
op.rep == FloatRepresentation::Float64());
bool float64 = op.rep == FloatRepresentation::Float64();
const Operator* o;
switch (op.kind) {
@ -629,6 +633,9 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) {
} else if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word32()) {
o = machine.RoundFloat64ToInt32();
} else if (op.from == FloatRepresentation::Float32() &&
op.to == WordRepresentation::Word32()) {
o = machine.TruncateFloat32ToInt32(TruncateKind::kArchitectureDefault);
} else {
UNIMPLEMENTED();
}
@ -637,6 +644,9 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) {
if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word64()) {
o = machine.TruncateFloat64ToInt64(TruncateKind::kSetOverflowToMin);
} else if (op.from == FloatRepresentation::Float32() &&
op.to == WordRepresentation::Word32()) {
o = machine.TruncateFloat32ToInt32(TruncateKind::kSetOverflowToMin);
} else {
UNIMPLEMENTED();
}
@ -645,6 +655,9 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) {
if (op.from == FloatRepresentation::Float32() &&
op.to == WordRepresentation::Word32()) {
o = machine.TruncateFloat32ToUint32(TruncateKind::kArchitectureDefault);
} else if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word32()) {
o = machine.TruncateFloat64ToUint32();
} else {
UNIMPLEMENTED();
}
@ -776,6 +789,34 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) {
UNIMPLEMENTED();
}
break;
case Kind::kSignedFloatTruncateSat:
if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word64()) {
o = machine.TryTruncateFloat64ToInt64();
} else if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word32()) {
o = machine.TryTruncateFloat64ToInt32();
} else if (op.from == FloatRepresentation::Float32() &&
op.to == WordRepresentation::Word64()) {
o = machine.TryTruncateFloat32ToInt64();
} else {
UNREACHABLE();
}
break;
case Kind::kUnsignedFloatTruncateSat:
if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word64()) {
o = machine.TryTruncateFloat64ToUint64();
} else if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word32()) {
o = machine.TryTruncateFloat64ToUint32();
} else if (op.from == FloatRepresentation::Float32() &&
op.to == WordRepresentation::Word64()) {
o = machine.TryTruncateFloat32ToUint64();
} else {
UNREACHABLE();
}
break;
}
return AddNode(o, {GetNode(op.input())});
}