Skip to content

Commit 7142fa1

Browse files
authored
[Interpreter] i32/i64 Bitwise Operators (#7332)
Building on #7227, implemented and tested the following: - i32/i64.and - i32/i64.or - i32/i64.xor - i32/i64.shl - i32/i64.shrU - i32/i64.shrS - i32/i64.rotL - i32/i64.rotR
1 parent f56b515 commit 7142fa1

File tree

2 files changed

+316
-2
lines changed

2 files changed

+316
-2
lines changed

src/interpreter/interpreter.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,38 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
140140
case DivFloat64:
141141
push(lhs.div(rhs));
142142
return {};
143+
case AndInt32:
144+
case AndInt64:
145+
push(lhs.and_(rhs));
146+
return {};
147+
case OrInt32:
148+
case OrInt64:
149+
push(lhs.or_(rhs));
150+
return {};
151+
case XorInt32:
152+
case XorInt64:
153+
push(lhs.xor_(rhs));
154+
return {};
155+
case ShlInt32:
156+
case ShlInt64:
157+
push(lhs.shl(rhs));
158+
return {};
159+
case ShrUInt32:
160+
case ShrUInt64:
161+
push(lhs.shrU(rhs));
162+
return {};
163+
case ShrSInt32:
164+
case ShrSInt64:
165+
push(lhs.shrS(rhs));
166+
return {};
167+
case RotLInt32:
168+
case RotLInt64:
169+
push(lhs.rotL(rhs));
170+
return {};
171+
case RotRInt32:
172+
case RotRInt64:
173+
push(lhs.rotR(rhs));
174+
return {};
143175
case EqInt32:
144176
case EqInt64:
145177
case EqFloat32:

test/gtest/interpreter.cpp

Lines changed: 284 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525

2626
using namespace wasm;
2727

28-
// uInt32
28+
// Int32
29+
2930
TEST(InterpreterTest, AddI32) {
3031
Module wasm;
3132
IRBuilder builder(wasm);
@@ -94,6 +95,110 @@ TEST(InterpreterTest, EqI32) {
9495
EXPECT_EQ(results, expected);
9596
}
9697

98+
TEST(InterpreterTest, AndI32) {
99+
Module wasm;
100+
IRBuilder builder(wasm);
101+
102+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(0))).getErr());
103+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(2))).getErr());
104+
ASSERT_FALSE(builder.makeBinary(AndInt32).getErr());
105+
106+
auto expr = builder.build();
107+
ASSERT_FALSE(expr.getErr());
108+
109+
auto results = Interpreter{}.run(*expr);
110+
std::vector<Literal> expected{Literal(uint32_t(0))};
111+
112+
EXPECT_EQ(results, expected);
113+
}
114+
115+
TEST(InterpreterTest, OrI32) {
116+
Module wasm;
117+
IRBuilder builder(wasm);
118+
119+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(2))).getErr());
120+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(4))).getErr());
121+
ASSERT_FALSE(builder.makeBinary(OrInt32).getErr());
122+
123+
auto expr = builder.build();
124+
ASSERT_FALSE(expr.getErr());
125+
126+
auto results = Interpreter{}.run(*expr);
127+
std::vector<Literal> expected{Literal(uint32_t(6))};
128+
129+
EXPECT_EQ(results, expected);
130+
}
131+
132+
TEST(InterpreterTest, XorI32) {
133+
Module wasm;
134+
IRBuilder builder(wasm);
135+
136+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(1))).getErr());
137+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(3))).getErr());
138+
ASSERT_FALSE(builder.makeBinary(XorInt32).getErr());
139+
140+
auto expr = builder.build();
141+
ASSERT_FALSE(expr.getErr());
142+
143+
auto results = Interpreter{}.run(*expr);
144+
std::vector<Literal> expected{Literal(uint32_t(2))};
145+
146+
EXPECT_EQ(results, expected);
147+
}
148+
149+
TEST(InterpreterTest, ShlI32) {
150+
Module wasm;
151+
IRBuilder builder(wasm);
152+
153+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(3))).getErr());
154+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(4))).getErr());
155+
ASSERT_FALSE(builder.makeBinary(ShlInt32).getErr());
156+
157+
auto expr = builder.build();
158+
ASSERT_FALSE(expr.getErr());
159+
160+
auto results = Interpreter{}.run(*expr);
161+
std::vector<Literal> expected{Literal(uint32_t(48))};
162+
163+
EXPECT_EQ(results, expected);
164+
}
165+
166+
TEST(InterpreterTest, RotLI32) {
167+
Module wasm;
168+
IRBuilder builder(wasm);
169+
170+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(1))).getErr());
171+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(4))).getErr());
172+
ASSERT_FALSE(builder.makeBinary(RotLInt32).getErr());
173+
174+
auto expr = builder.build();
175+
ASSERT_FALSE(expr.getErr());
176+
177+
auto results = Interpreter{}.run(*expr);
178+
std::vector<Literal> expected{Literal(uint32_t(16))};
179+
180+
EXPECT_EQ(results, expected);
181+
}
182+
183+
TEST(InterpreterTest, RotRI32) {
184+
Module wasm;
185+
IRBuilder builder(wasm);
186+
187+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(2))).getErr());
188+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(3))).getErr());
189+
ASSERT_FALSE(builder.makeBinary(RotRInt32).getErr());
190+
191+
auto expr = builder.build();
192+
ASSERT_FALSE(expr.getErr());
193+
194+
auto results = Interpreter{}.run(*expr);
195+
std::vector<Literal> expected{Literal(uint32_t(1073741824))};
196+
197+
EXPECT_EQ(results, expected);
198+
}
199+
200+
// uInt32
201+
97202
TEST(InterpreterTest, LtUI32) {
98203
Module wasm;
99204
IRBuilder builder(wasm);
@@ -128,7 +233,25 @@ TEST(InterpreterTest, GtUI32) {
128233
EXPECT_EQ(results, expected);
129234
}
130235

236+
TEST(InterpreterTest, ShrUI32) {
237+
Module wasm;
238+
IRBuilder builder(wasm);
239+
240+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(1))).getErr());
241+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(2))).getErr());
242+
ASSERT_FALSE(builder.makeBinary(ShrUInt32).getErr());
243+
244+
auto expr = builder.build();
245+
ASSERT_FALSE(expr.getErr());
246+
247+
auto results = Interpreter{}.run(*expr);
248+
std::vector<Literal> expected{Literal(uint32_t(0))};
249+
250+
EXPECT_EQ(results, expected);
251+
}
252+
131253
// sInt32
254+
132255
TEST(InterpreterTest, LtSI32) {
133256
Module wasm;
134257
IRBuilder builder(wasm);
@@ -163,7 +286,25 @@ TEST(InterpreterTest, GtSI32) {
163286
EXPECT_EQ(results, expected);
164287
}
165288

166-
// uInt64
289+
TEST(InterpreterTest, ShrSI32) {
290+
Module wasm;
291+
IRBuilder builder(wasm);
292+
293+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(1))).getErr());
294+
ASSERT_FALSE(builder.makeConst(Literal(uint32_t(2))).getErr());
295+
ASSERT_FALSE(builder.makeBinary(ShrSInt32).getErr());
296+
297+
auto expr = builder.build();
298+
ASSERT_FALSE(expr.getErr());
299+
300+
auto results = Interpreter{}.run(*expr);
301+
std::vector<Literal> expected{Literal(uint32_t(0))};
302+
303+
EXPECT_EQ(results, expected);
304+
}
305+
306+
// Int64
307+
167308
TEST(InterpreterTest, AddI64) {
168309
Module wasm;
169310
IRBuilder builder(wasm);
@@ -232,6 +373,110 @@ TEST(InterpreterTest, EqI64) {
232373
EXPECT_EQ(results, expected);
233374
}
234375

376+
TEST(InterpreterTest, AndI64) {
377+
Module wasm;
378+
IRBuilder builder(wasm);
379+
380+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(1))).getErr());
381+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(2))).getErr());
382+
ASSERT_FALSE(builder.makeBinary(AndInt64).getErr());
383+
384+
auto expr = builder.build();
385+
ASSERT_FALSE(expr.getErr());
386+
387+
auto results = Interpreter{}.run(*expr);
388+
std::vector<Literal> expected{Literal(uint64_t(0))};
389+
390+
EXPECT_EQ(results, expected);
391+
}
392+
393+
TEST(InterpreterTest, OrI64) {
394+
Module wasm;
395+
IRBuilder builder(wasm);
396+
397+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(1))).getErr());
398+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(2))).getErr());
399+
ASSERT_FALSE(builder.makeBinary(OrInt64).getErr());
400+
401+
auto expr = builder.build();
402+
ASSERT_FALSE(expr.getErr());
403+
404+
auto results = Interpreter{}.run(*expr);
405+
std::vector<Literal> expected{Literal(uint64_t(3))};
406+
407+
EXPECT_EQ(results, expected);
408+
}
409+
410+
TEST(InterpreterTest, XorI64) {
411+
Module wasm;
412+
IRBuilder builder(wasm);
413+
414+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(1))).getErr());
415+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(2))).getErr());
416+
ASSERT_FALSE(builder.makeBinary(XorInt64).getErr());
417+
418+
auto expr = builder.build();
419+
ASSERT_FALSE(expr.getErr());
420+
421+
auto results = Interpreter{}.run(*expr);
422+
std::vector<Literal> expected{Literal(uint64_t(3))};
423+
424+
EXPECT_EQ(results, expected);
425+
}
426+
427+
TEST(InterpreterTest, ShlI64) {
428+
Module wasm;
429+
IRBuilder builder(wasm);
430+
431+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(1))).getErr());
432+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(2))).getErr());
433+
ASSERT_FALSE(builder.makeBinary(ShlInt64).getErr());
434+
435+
auto expr = builder.build();
436+
ASSERT_FALSE(expr.getErr());
437+
438+
auto results = Interpreter{}.run(*expr);
439+
std::vector<Literal> expected{Literal(uint64_t(4))};
440+
441+
EXPECT_EQ(results, expected);
442+
}
443+
444+
TEST(InterpreterTest, RotLI64) {
445+
Module wasm;
446+
IRBuilder builder(wasm);
447+
448+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(1))).getErr());
449+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(2))).getErr());
450+
ASSERT_FALSE(builder.makeBinary(RotLInt64).getErr());
451+
452+
auto expr = builder.build();
453+
ASSERT_FALSE(expr.getErr());
454+
455+
auto results = Interpreter{}.run(*expr);
456+
std::vector<Literal> expected{Literal(uint64_t(4))};
457+
458+
EXPECT_EQ(results, expected);
459+
}
460+
461+
TEST(InterpreterTest, RotRI64) {
462+
Module wasm;
463+
IRBuilder builder(wasm);
464+
465+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(1))).getErr());
466+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(2))).getErr());
467+
ASSERT_FALSE(builder.makeBinary(RotRInt64).getErr());
468+
469+
auto expr = builder.build();
470+
ASSERT_FALSE(expr.getErr());
471+
472+
auto results = Interpreter{}.run(*expr);
473+
std::vector<Literal> expected{Literal(uint64_t(4611686018427387904))};
474+
475+
EXPECT_EQ(results, expected);
476+
}
477+
478+
// uInt64
479+
235480
TEST(InterpreterTest, LtUI64) {
236481
Module wasm;
237482
IRBuilder builder(wasm);
@@ -266,7 +511,25 @@ TEST(InterpreterTest, GtUI64) {
266511
EXPECT_EQ(results, expected);
267512
}
268513

514+
TEST(InterpreterTest, ShrUI64) {
515+
Module wasm;
516+
IRBuilder builder(wasm);
517+
518+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(1))).getErr());
519+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(2))).getErr());
520+
ASSERT_FALSE(builder.makeBinary(ShrUInt64).getErr());
521+
522+
auto expr = builder.build();
523+
ASSERT_FALSE(expr.getErr());
524+
525+
auto results = Interpreter{}.run(*expr);
526+
std::vector<Literal> expected{Literal(uint64_t(0))};
527+
528+
EXPECT_EQ(results, expected);
529+
}
530+
269531
// sInt64
532+
270533
TEST(InterpreterTest, LtSI64) {
271534
Module wasm;
272535
IRBuilder builder(wasm);
@@ -301,7 +564,25 @@ TEST(InterpreterTest, GtSI64) {
301564
EXPECT_EQ(results, expected);
302565
}
303566

567+
TEST(InterpreterTest, ShrSI64) {
568+
Module wasm;
569+
IRBuilder builder(wasm);
570+
571+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(1))).getErr());
572+
ASSERT_FALSE(builder.makeConst(Literal(uint64_t(2))).getErr());
573+
ASSERT_FALSE(builder.makeBinary(ShrSInt64).getErr());
574+
575+
auto expr = builder.build();
576+
ASSERT_FALSE(expr.getErr());
577+
578+
auto results = Interpreter{}.run(*expr);
579+
std::vector<Literal> expected{Literal(uint64_t(0))};
580+
581+
EXPECT_EQ(results, expected);
582+
}
583+
304584
// Float32
585+
305586
TEST(InterpreterTest, AddF32) {
306587
Module wasm;
307588
IRBuilder builder(wasm);
@@ -468,6 +749,7 @@ TEST(InterpreterTest, NearF32) {
468749
}
469750

470751
// Float 64
752+
471753
TEST(InterpreterTest, AddF64) {
472754
Module wasm;
473755
IRBuilder builder(wasm);

0 commit comments

Comments
 (0)