Commit 53c13108 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by V8 LUCI CQ

[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: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83381}
parent 24de6208
...@@ -367,6 +367,18 @@ class AssemblerInterface : public Superclass { ...@@ -367,6 +367,18 @@ class AssemblerInterface : public Superclass {
WordRepresentation::Word32()) WordRepresentation::Word32())
DECL_SINGLE_REP_UNARY(Word64PopCount, WordUnary, PopCount, DECL_SINGLE_REP_UNARY(Word64PopCount, WordUnary, PopCount,
WordRepresentation::Word64()) 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_SINGLE_REP_UNARY
#undef DECL_MULTI_REP_UNARY #undef DECL_MULTI_REP_UNARY
......
...@@ -436,6 +436,10 @@ OpIndex GraphBuilder::Process( ...@@ -436,6 +436,10 @@ OpIndex GraphBuilder::Process(
UNARY_CASE(Word64Ctz, Word64CountTrailingZeros) UNARY_CASE(Word64Ctz, Word64CountTrailingZeros)
UNARY_CASE(Word32Popcnt, Word32PopCount) UNARY_CASE(Word32Popcnt, Word32PopCount)
UNARY_CASE(Word64Popcnt, Word64PopCount) 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(Float32Abs, Float32Abs)
UNARY_CASE(Float64Abs, Float64Abs) UNARY_CASE(Float64Abs, Float64Abs)
...@@ -505,6 +509,19 @@ OpIndex GraphBuilder::Process( ...@@ -505,6 +509,19 @@ OpIndex GraphBuilder::Process(
CHANGE_CASE(ChangeFloat64ToUint32, UnsignedNarrowing, Float64, Word32) CHANGE_CASE(ChangeFloat64ToUint32, UnsignedNarrowing, Float64, Word32)
CHANGE_CASE(ChangeFloat64ToInt64, SignedNarrowing, Float64, Word64) CHANGE_CASE(ChangeFloat64ToInt64, SignedNarrowing, Float64, Word64)
CHANGE_CASE(ChangeFloat64ToUint64, UnsignedNarrowing, 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(Float64ExtractLowWord32, ExtractLowHalf, Float64, Word32)
CHANGE_CASE(Float64ExtractHighWord32, ExtractHighHalf, Float64, Word32) CHANGE_CASE(Float64ExtractHighWord32, ExtractHighHalf, Float64, Word32)
#undef CHANGE_CASE #undef CHANGE_CASE
...@@ -541,6 +558,11 @@ OpIndex GraphBuilder::Process( ...@@ -541,6 +558,11 @@ OpIndex GraphBuilder::Process(
RegisterRepresentation::Float64(), RegisterRepresentation::Float64(),
RegisterRepresentation::Word64()); RegisterRepresentation::Word64());
} }
case IrOpcode::kTruncateFloat64ToUint32: {
return assembler.Change(
Map(node->InputAt(0)), ChangeOp::Kind::kUnsignedFloatTruncate,
RegisterRepresentation::Float64(), RegisterRepresentation::Word32());
}
case IrOpcode::kFloat64InsertLowWord32: case IrOpcode::kFloat64InsertLowWord32:
return assembler.Float64InsertWord32( return assembler.Float64InsertWord32(
Map(node->InputAt(0)), Map(node->InputAt(1)), Map(node->InputAt(0)), Map(node->InputAt(1)),
......
...@@ -51,6 +51,10 @@ std::ostream& operator<<(std::ostream& os, WordUnaryOp::Kind kind) { ...@@ -51,6 +51,10 @@ std::ostream& operator<<(std::ostream& os, WordUnaryOp::Kind kind) {
return os << "CountTrailingZeros"; return os << "CountTrailingZeros";
case WordUnaryOp::Kind::kPopCount: case WordUnaryOp::Kind::kPopCount:
return os << "PopCount"; 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) { ...@@ -150,6 +154,8 @@ bool WordUnaryOp::IsSupported(Kind kind, WordRepresentation rep) {
switch (kind) { switch (kind) {
case Kind::kCountLeadingZeros: case Kind::kCountLeadingZeros:
case Kind::kReverseBytes: case Kind::kReverseBytes:
case Kind::kSignExtend8:
case Kind::kSignExtend16:
return true; return true;
case Kind::kCountTrailingZeros: case Kind::kCountTrailingZeros:
return rep == WordRepresentation::Word32() return rep == WordRepresentation::Word32()
...@@ -224,6 +230,10 @@ std::ostream& operator<<(std::ostream& os, ChangeOp::Kind kind) { ...@@ -224,6 +230,10 @@ std::ostream& operator<<(std::ostream& os, ChangeOp::Kind kind) {
return os << "SignExtend"; return os << "SignExtend";
case ChangeOp::Kind::kBitcast: case ChangeOp::Kind::kBitcast:
return os << "Bitcast"; 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> { ...@@ -726,6 +726,8 @@ struct WordUnaryOp : FixedArityOperationT<1, WordUnaryOp> {
kCountLeadingZeros, kCountLeadingZeros,
kCountTrailingZeros, kCountTrailingZeros,
kPopCount, kPopCount,
kSignExtend8,
kSignExtend16,
}; };
Kind kind; Kind kind;
WordRepresentation rep; WordRepresentation rep;
...@@ -898,12 +900,16 @@ struct ChangeOp : FixedArityOperationT<1, ChangeOp> { ...@@ -898,12 +900,16 @@ struct ChangeOp : FixedArityOperationT<1, ChangeOp> {
// like kSignedFloatTruncate, but overflow guaranteed to result in the // like kSignedFloatTruncate, but overflow guaranteed to result in the
// minimal integer // minimal integer
kSignedFloatTruncateOverflowToMin, kSignedFloatTruncateOverflowToMin,
// like kSignedFloatTruncate, but saturates to min/max value if overflow
kSignedFloatTruncateSat,
// conversion to unsigned integer, rounding towards zero, // conversion to unsigned integer, rounding towards zero,
// overflow behavior system-specific // overflow behavior system-specific
kUnsignedFloatTruncate, kUnsignedFloatTruncate,
// like kUnsignedFloatTruncate, but overflow guaranteed to result in the // like kUnsignedFloatTruncate, but overflow guaranteed to result in the
// minimal integer // minimal integer
kUnsignedFloatTruncateOverflowToMin, kUnsignedFloatTruncateOverflowToMin,
// like kUnsignedFloatTruncate, but saturates to 0/max value if overflow
kUnsignedFloatTruncateSat,
// JS semantics float64 to word32 truncation // JS semantics float64 to word32 truncation
// https://tc39.es/ecma262/#sec-touint32 // https://tc39.es/ecma262/#sec-touint32
kJSFloatTruncate, kJSFloatTruncate,
......
...@@ -359,8 +359,6 @@ Node* ScheduleBuilder::ProcessOperation(const OverflowCheckedBinopOp& op) { ...@@ -359,8 +359,6 @@ Node* ScheduleBuilder::ProcessOperation(const OverflowCheckedBinopOp& op) {
return AddNode(o, {GetNode(op.left()), GetNode(op.right())}); return AddNode(o, {GetNode(op.left()), GetNode(op.right())});
} }
Node* ScheduleBuilder::ProcessOperation(const WordUnaryOp& op) { Node* ScheduleBuilder::ProcessOperation(const WordUnaryOp& op) {
DCHECK(op.rep == WordRepresentation::Word32() ||
op.rep == WordRepresentation::Word64());
bool word64 = op.rep == WordRepresentation::Word64(); bool word64 = op.rep == WordRepresentation::Word64();
const Operator* o; const Operator* o;
switch (op.kind) { switch (op.kind) {
...@@ -376,12 +374,18 @@ Node* ScheduleBuilder::ProcessOperation(const WordUnaryOp& op) { ...@@ -376,12 +374,18 @@ Node* ScheduleBuilder::ProcessOperation(const WordUnaryOp& op) {
case WordUnaryOp::Kind::kPopCount: case WordUnaryOp::Kind::kPopCount:
o = word64 ? machine.Word64Popcnt().op() : machine.Word32Popcnt().op(); o = word64 ? machine.Word64Popcnt().op() : machine.Word32Popcnt().op();
break; 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())}); return AddNode(o, {GetNode(op.input())});
} }
Node* ScheduleBuilder::ProcessOperation(const FloatUnaryOp& op) { Node* ScheduleBuilder::ProcessOperation(const FloatUnaryOp& op) {
DCHECK(op.rep == FloatRepresentation::Float32() ||
op.rep == FloatRepresentation::Float64());
bool float64 = op.rep == FloatRepresentation::Float64(); bool float64 = op.rep == FloatRepresentation::Float64();
const Operator* o; const Operator* o;
switch (op.kind) { switch (op.kind) {
...@@ -629,6 +633,9 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) { ...@@ -629,6 +633,9 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) {
} else if (op.from == FloatRepresentation::Float64() && } else if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word32()) { op.to == WordRepresentation::Word32()) {
o = machine.RoundFloat64ToInt32(); o = machine.RoundFloat64ToInt32();
} else if (op.from == FloatRepresentation::Float32() &&
op.to == WordRepresentation::Word32()) {
o = machine.TruncateFloat32ToInt32(TruncateKind::kArchitectureDefault);
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
...@@ -637,6 +644,9 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) { ...@@ -637,6 +644,9 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) {
if (op.from == FloatRepresentation::Float64() && if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word64()) { op.to == WordRepresentation::Word64()) {
o = machine.TruncateFloat64ToInt64(TruncateKind::kSetOverflowToMin); o = machine.TruncateFloat64ToInt64(TruncateKind::kSetOverflowToMin);
} else if (op.from == FloatRepresentation::Float32() &&
op.to == WordRepresentation::Word32()) {
o = machine.TruncateFloat32ToInt32(TruncateKind::kSetOverflowToMin);
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
...@@ -645,6 +655,9 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) { ...@@ -645,6 +655,9 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) {
if (op.from == FloatRepresentation::Float32() && if (op.from == FloatRepresentation::Float32() &&
op.to == WordRepresentation::Word32()) { op.to == WordRepresentation::Word32()) {
o = machine.TruncateFloat32ToUint32(TruncateKind::kArchitectureDefault); o = machine.TruncateFloat32ToUint32(TruncateKind::kArchitectureDefault);
} else if (op.from == FloatRepresentation::Float64() &&
op.to == WordRepresentation::Word32()) {
o = machine.TruncateFloat64ToUint32();
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
...@@ -776,6 +789,34 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) { ...@@ -776,6 +789,34 @@ Node* ScheduleBuilder::ProcessOperation(const ChangeOp& op) {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
break; 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())}); return AddNode(o, {GetNode(op.input())});
} }
......
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