Commit e4a60b63f2

gracefu <81774659+gracefuu@users.noreply.github.com>
2021-04-07 23:24:40
stage2 wasm: Add bitwise/boolean ops &, |, ^, and, or
1 parent 4c71942
Changed files (2)
src
codegen
test
stage2
src/codegen/wasm.zig
@@ -657,6 +657,10 @@ pub const Context = struct {
             .breakpoint => self.genBreakpoint(inst.castTag(.breakpoint).?),
             .br => self.genBr(inst.castTag(.br).?),
             .call => self.genCall(inst.castTag(.call).?),
+            .bit_or => self.genBinOp(inst.castTag(.bit_or).?, .@"or"),
+            .bit_and => self.genBinOp(inst.castTag(.bit_and).?, .@"and"),
+            .bool_or => self.genBinOp(inst.castTag(.bool_or).?, .@"or"),
+            .bool_and => self.genBinOp(inst.castTag(.bool_and).?, .@"and"),
             .cmp_eq => self.genCmp(inst.castTag(.cmp_eq).?, .eq),
             .cmp_gte => self.genCmp(inst.castTag(.cmp_gte).?, .gte),
             .cmp_gt => self.genCmp(inst.castTag(.cmp_gt).?, .gt),
@@ -669,6 +673,8 @@ pub const Context = struct {
             .load => self.genLoad(inst.castTag(.load).?),
             .loop => self.genLoop(inst.castTag(.loop).?),
             .mul => self.genBinOp(inst.castTag(.mul).?, .mul),
+            .div => self.genBinOp(inst.castTag(.div).?, .div),
+            .xor => self.genBinOp(inst.castTag(.xor).?, .xor),
             .not => self.genNot(inst.castTag(.not).?),
             .ret => self.genRet(inst.castTag(.ret).?),
             .retvoid => WValue.none,
@@ -764,6 +770,7 @@ pub const Context = struct {
         const opcode: wasm.Opcode = buildOpcode(.{
             .op = op,
             .valtype1 = try self.typeToValtype(inst.base.src, inst.base.ty),
+            .signedness = if (inst.base.ty.isSignedInt()) .signed else .unsigned,
         });
         try self.code.append(wasm.opcode(opcode));
         return .none;
test/stage2/wasm.zig
@@ -153,6 +153,106 @@ pub fn addCases(ctx: *TestContext) !void {
             \\    return x * y;
             \\}
         , "350\n");
+
+        case.addCompareOutput(
+            \\export fn _start() u32 {
+            \\    var i: u32 = 352;
+            \\    i /= 7; // i = 50
+            \\    var result: u32 = foo(i, 7);
+            \\    return result;
+            \\}
+            \\fn foo(x: u32, y: u32) u32 {
+            \\    return x / y;
+            \\}
+        , "7\n");
+
+        case.addCompareOutput(
+            \\export fn _start() u32 {
+            \\    var i: u32 = 5;
+            \\    i &= 6;
+            \\    return i;
+            \\}
+        , "4\n");
+
+        case.addCompareOutput(
+            \\export fn _start() u32 {
+            \\    var i: u32 = 5;
+            \\    i |= 6;
+            \\    return i;
+            \\}
+        , "7\n");
+
+        case.addCompareOutput(
+            \\export fn _start() u32 {
+            \\    var i: u32 = 5;
+            \\    i ^= 6;
+            \\    return i;
+            \\}
+        , "3\n");
+
+        case.addCompareOutput(
+            \\export fn _start() bool {
+            \\    var b: bool = false;
+            \\    b = b or false;
+            \\    return b;
+            \\}
+        , "0\n");
+
+        case.addCompareOutput(
+            \\export fn _start() bool {
+            \\    var b: bool = true;
+            \\    b = b or false;
+            \\    return b;
+            \\}
+        , "1\n");
+
+        case.addCompareOutput(
+            \\export fn _start() bool {
+            \\    var b: bool = false;
+            \\    b = b or true;
+            \\    return b;
+            \\}
+        , "1\n");
+
+        case.addCompareOutput(
+            \\export fn _start() bool {
+            \\    var b: bool = true;
+            \\    b = b or true;
+            \\    return b;
+            \\}
+        , "1\n");
+
+        case.addCompareOutput(
+            \\export fn _start() bool {
+            \\    var b: bool = false;
+            \\    b = b and false;
+            \\    return b;
+            \\}
+        , "0\n");
+
+        case.addCompareOutput(
+            \\export fn _start() bool {
+            \\    var b: bool = true;
+            \\    b = b and false;
+            \\    return b;
+            \\}
+        , "0\n");
+
+        case.addCompareOutput(
+            \\export fn _start() bool {
+            \\    var b: bool = false;
+            \\    b = b and true;
+            \\    return b;
+            \\}
+        , "0\n");
+
+        case.addCompareOutput(
+            \\export fn _start() bool {
+            \\    var b: bool = true;
+            \\    b = b and true;
+            \\    return b;
+            \\}
+        , "1\n");
     }
 
     {