Skip to content

Commit 45f8dd9

Browse files
Support for wide arithmetic
1 parent 7f3617c commit 45f8dd9

29 files changed

Lines changed: 389 additions & 14 deletions

scripts/gen-s-parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@
146146
("i64.shr_u", "makeBinary(BinaryOp::ShrUInt64)"),
147147
("i64.rotl", "makeBinary(BinaryOp::RotLInt64)"),
148148
("i64.rotr", "makeBinary(BinaryOp::RotRInt64)"),
149+
("i64.add128", "makeWideIntBinary(WideIntBinaryOp::AddInt128)"),
149150
("f32.abs", "makeUnary(UnaryOp::AbsFloat32)"),
150151
("f32.neg", "makeUnary(UnaryOp::NegFloat32)"),
151152
("f32.ceil", "makeUnary(UnaryOp::CeilFloat32)"),

src/gen-s-parser.inc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3405,12 +3405,23 @@ switch (buf[0]) {
34053405
switch (buf[4]) {
34063406
case 'a': {
34073407
switch (buf[5]) {
3408-
case 'd':
3409-
if (op == "i64.add"sv) {
3410-
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::AddInt64));
3411-
return Ok{};
3408+
case 'd': {
3409+
switch (buf[7]) {
3410+
case '\0':
3411+
if (op == "i64.add"sv) {
3412+
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::AddInt64));
3413+
return Ok{};
3414+
}
3415+
goto parse_error;
3416+
case '1':
3417+
if (op == "i64.add128"sv) {
3418+
CHECK_ERR(makeWideIntBinary(ctx, pos, annotations, WideIntBinaryOp::AddInt128));
3419+
return Ok{};
3420+
}
3421+
goto parse_error;
3422+
default: goto parse_error;
34123423
}
3413-
goto parse_error;
3424+
}
34143425
case 'n':
34153426
if (op == "i64.and"sv) {
34163427
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::AndInt64));

src/interpreter/interpreter.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,22 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
217217
}
218218
}
219219
Flow visitSelect(Select* curr) { WASM_UNREACHABLE("TODO"); }
220+
Flow visitWideIntBinary(WideIntBinary* curr) {
221+
if (curr->op == AddInt128) {
222+
uint64_t highRHS = pop().geti64();
223+
uint64_t lowRHS = pop().geti64();
224+
uint64_t highLHS = pop().geti64();
225+
uint64_t lowLHS = pop().geti64();
226+
227+
uint64_t lowRes = lowLHS + lowRHS;
228+
uint64_t highRes = highLHS + highRHS + (lowRes < lowLHS);
229+
230+
push(Literal(lowRes));
231+
push(Literal(highRes));
232+
return {};
233+
}
234+
WASM_UNREACHABLE("TODO");
235+
}
220236
Flow visitDrop(Drop* curr) { WASM_UNREACHABLE("TODO"); }
221237
Flow visitReturn(Return* curr) { WASM_UNREACHABLE("TODO"); }
222238
Flow visitMemorySize(MemorySize* curr) { WASM_UNREACHABLE("TODO"); }

src/ir/ReFinalize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ void ReFinalize::visitMemoryFill(MemoryFill* curr) { curr->finalize(); }
109109
void ReFinalize::visitConst(Const* curr) { curr->finalize(); }
110110
void ReFinalize::visitUnary(Unary* curr) { curr->finalize(); }
111111
void ReFinalize::visitBinary(Binary* curr) { curr->finalize(); }
112+
void ReFinalize::visitWideIntBinary(WideIntBinary* curr) { curr->finalize(); }
112113
void ReFinalize::visitSelect(Select* curr) { curr->finalize(); }
113114
void ReFinalize::visitDrop(Drop* curr) { curr->finalize(); }
114115
void ReFinalize::visitReturn(Return* curr) { curr->finalize(); }

src/ir/child-typer.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,14 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
703703
}
704704
}
705705

706+
void visitWideIntBinary(WideIntBinary* curr) {
707+
size_t num = 4;
708+
curr->operands.resize(num);
709+
for (size_t i = 0; i < num; ++i) {
710+
note(&curr->operands[i], Type::i64);
711+
}
712+
}
713+
706714
void visitSelect(Select* curr, std::optional<Type> type = std::nullopt) {
707715
if (type) {
708716
note(&curr->ifTrue, *type);

src/ir/cost.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,13 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
573573
}
574574
return ret + visit(curr->left) + visit(curr->right);
575575
}
576+
CostType visitWideIntBinary(WideIntBinary* curr) {
577+
CostType ret = 1;
578+
for (auto* child : curr->operands) {
579+
ret += visit(child);
580+
}
581+
return ret;
582+
}
576583
CostType visitSelect(Select* curr) {
577584
return 1 + visit(curr->condition) + visit(curr->ifTrue) +
578585
visit(curr->ifFalse);

src/ir/effects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,7 @@ class EffectAnalyzer {
945945
}
946946
}
947947
}
948+
void visitWideIntBinary(WideIntBinary* curr) {}
948949
void visitSelect(Select* curr) {}
949950
void visitDrop(Drop* curr) {}
950951
void visitReturn(Return* curr) { parent.branchesOut = true; }

src/ir/possible-contents.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ struct InfoCollector
634634
addRoot(curr);
635635
}
636636
void visitBinary(Binary* curr) { addRoot(curr); }
637+
void visitWideIntBinary(WideIntBinary* curr) { addRoot(curr); }
637638
void visitSelect(Select* curr) {
638639
receiveChildValue(curr->ifTrue, curr);
639640
receiveChildValue(curr->ifFalse, curr);

src/ir/subtype-exprs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ struct SubtypingDiscoverer : public OverriddenVisitor<SubType> {
213213
void visitConst(Const* curr) {}
214214
void visitUnary(Unary* curr) {}
215215
void visitBinary(Binary* curr) {}
216+
void visitWideIntBinary(WideIntBinary* curr) {}
216217
void visitSelect(Select* curr) {
217218
self()->noteSubtype(curr->ifTrue, curr);
218219
self()->noteSubtype(curr->ifFalse, curr);

src/parser/contexts.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,10 @@ struct NullInstrParserCtx {
476476
Result<> makeBinary(Index, const std::vector<Annotation>&, BinaryOp) {
477477
return Ok{};
478478
}
479+
Result<>
480+
makeWideIntBinary(Index, const std::vector<Annotation>&, WideIntBinaryOp) {
481+
return Ok{};
482+
}
479483
Result<> makeUnary(Index, const std::vector<Annotation>&, UnaryOp) {
480484
return Ok{};
481485
}
@@ -2159,6 +2163,12 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
21592163
return withLoc(pos, irBuilder.makeBinary(op));
21602164
}
21612165

2166+
Result<> makeWideIntBinary(Index pos,
2167+
const std::vector<Annotation>& annotations,
2168+
WideIntBinaryOp op) {
2169+
return withLoc(pos, irBuilder.makeWideIntBinary(op));
2170+
}
2171+
21622172
Result<>
21632173
makeUnary(Index pos, const std::vector<Annotation>& annotations, UnaryOp op) {
21642174
return withLoc(pos, irBuilder.makeUnary(op));

0 commit comments

Comments
 (0)