[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:
parent
24de62081e
commit
53c13108c4
@ -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
|
||||
|
||||
|
@ -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)),
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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())});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user