From 4c71942f84261e9872cd27139c45b6d5fb1ab6c7 Mon Sep 17 00:00:00 2001 From: gracefu <81774659+gracefuu@users.noreply.github.com> Date: Thu, 8 Apr 2021 05:24:17 +0800 Subject: [PATCH 1/3] stage2: Add .div to ir.zig --- src/Sema.zig | 1 + src/codegen.zig | 10 ++++++++++ src/codegen/c.zig | 3 +++ src/ir.zig | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/src/Sema.zig b/src/Sema.zig index 0b5a21ce421787ff96baa4dcb7823a8944db18c3..1a9c60a68065b06a7b466b0ddec187b5014c81e2 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -3540,6 +3540,7 @@ fn analyzeArithmetic( .subwrap => .subwrap, .mul => .mul, .mulwrap => .mulwrap, + .div => .div, else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(zir_tag)}), }; diff --git a/src/codegen.zig b/src/codegen.zig index fbd412ceba3c0b3cb7c73bf1df1d993b1f93d3bb..3958577d95fd454f08cee522fcb5cdf7e477d054 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -855,6 +855,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { .not => return self.genNot(inst.castTag(.not).?), .mul => return self.genMul(inst.castTag(.mul).?), .mulwrap => return self.genMulWrap(inst.castTag(.mulwrap).?), + .div => return self.genDiv(inst.castTag(.div).?), .ptrtoint => return self.genPtrToInt(inst.castTag(.ptrtoint).?), .ref => return self.genRef(inst.castTag(.ref).?), .ret => return self.genRet(inst.castTag(.ret).?), @@ -1092,6 +1093,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { } } + fn genDiv(self: *Self, inst: *ir.Inst.BinOp) !MCValue { + // No side effects, so if it's unreferenced, do nothing. + if (inst.base.isUnused()) + return MCValue.dead; + switch (arch) { + else => return self.fail(inst.base.src, "TODO implement div for {}", .{self.target.cpu.arch}), + } + } + fn genBitAnd(self: *Self, inst: *ir.Inst.BinOp) !MCValue { // No side effects, so if it's unreferenced, do nothing. if (inst.base.isUnused()) diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 876f86ed0267de2f5ca86f8eee9fe758120cef00..d3ddbdeef9f15056f0e5d07524a2424b8fadec6b 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -582,6 +582,9 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi .mul => try genBinOp(o, inst.castTag(.sub).?, " * "), // TODO make this do wrapping multiplication for signed ints .mulwrap => try genBinOp(o, inst.castTag(.sub).?, " * "), + // TODO use a different strategy for div that communicates to the optimizer + // that wrapping is UB. + .div => try genBinOp(o, inst.castTag(.div).?, " / "), .constant => unreachable, // excluded from function bodies .alloc => try genAlloc(o, inst.castTag(.alloc).?), diff --git a/src/ir.zig b/src/ir.zig index ab6fb29e03548abcaa59a72931824158dd440759..85d4175c43cec12802e09e8a3f6b1bb602352953 100644 --- a/src/ir.zig +++ b/src/ir.zig @@ -115,6 +115,7 @@ pub const Inst = struct { unreach, mul, mulwrap, + div, not, floatcast, intcast, @@ -181,6 +182,7 @@ pub const Inst = struct { .subwrap, .mul, .mulwrap, + .div, .cmp_lt, .cmp_lte, .cmp_eq, @@ -752,6 +754,7 @@ const DumpTzir = struct { .subwrap, .mul, .mulwrap, + .div, .cmp_lt, .cmp_lte, .cmp_eq, @@ -891,6 +894,7 @@ const DumpTzir = struct { .subwrap, .mul, .mulwrap, + .div, .cmp_lt, .cmp_lte, .cmp_eq, -- 2.54.0 From e4a60b63f2c3551440f9b58e8c556545497827bc Mon Sep 17 00:00:00 2001 From: gracefu <81774659+gracefuu@users.noreply.github.com> Date: Thu, 8 Apr 2021 05:24:40 +0800 Subject: [PATCH 2/3] stage2 wasm: Add bitwise/boolean ops &, |, ^, and, or --- src/codegen/wasm.zig | 7 +++ test/stage2/wasm.zig | 100 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/src/codegen/wasm.zig b/src/codegen/wasm.zig index 9372444f539c7ee86a420ea65751dc7058b7a000..fbea02e0c343e7cce993784fbd8c48f8047ca1f9 100644 --- a/src/codegen/wasm.zig +++ b/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; diff --git a/test/stage2/wasm.zig b/test/stage2/wasm.zig index b585ddc56bf5876061498461de1c0d24ffb3944c..ccf2661b4467df4fdf74a64860d2235fb6690398 100644 --- a/test/stage2/wasm.zig +++ b/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"); } { -- 2.54.0 From 6dc35efe4958a0569c4d8576bca84d62264b1d1d Mon Sep 17 00:00:00 2001 From: gracefu <81774659+gracefuu@users.noreply.github.com> Date: Thu, 8 Apr 2021 05:25:29 +0800 Subject: [PATCH 3/3] Sema: fix typo bug for boolean ops (and, or) --- src/Sema.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index 1a9c60a68065b06a7b466b0ddec187b5014c81e2..666c7b98584fd33b6a79b1d70920c612f3c68175 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -3833,7 +3833,7 @@ fn zirBoolBr( _ = try rhs_block.addBr(src, block_inst, rhs_result); const tzir_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, then_block.instructions.items) }; - const tzir_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, rhs_block.instructions.items) }; + const tzir_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, else_block.instructions.items) }; _ = try child_block.addCondBr(src, lhs, tzir_then_body, tzir_else_body); block_inst.body = .{ -- 2.54.0