authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-08-19 13:04:52-04:00
committergravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-08-19 16:18:42-04:00
log2e22f7e5a5ff51aa4a1672e011cdc07b08a9a661
treef040c30d93c76e2e1376c1029e5cfdd7b6dc0492
parent2e6ce11eb29434231102c00fddd0a1b3e0ba5608

stage2: implement shl

This is implemented in the llvm and cbe backends. x86_64 will take a bit more time.

4 files changed, 50 insertions(+), 8 deletions(-)

src/Sema.zig+19-3
......@@ -5294,9 +5294,25 @@ fn zirShl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A
52945294 const tracy = trace(@src());
52955295 defer tracy.end();
52965296
5297 _ = block;
5298 _ = inst;
5299 return sema.mod.fail(&block.base, sema.src, "TODO implement zirShl", .{});
5297 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5298 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
5299 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
5300 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
5301 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
5302 const lhs = sema.resolveInst(extra.lhs);
5303 const rhs = sema.resolveInst(extra.rhs);
5304
5305 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
5306 if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| {
5307 if (lhs_val.isUndef() or rhs_val.isUndef()) {
5308 return sema.addConstUndef(sema.typeOf(lhs));
5309 }
5310 return sema.mod.fail(&block.base, src, "TODO implement comptime shl", .{});
5311 }
5312 }
5313
5314 try sema.requireRuntimeBlock(block, src);
5315 return block.addBinOp(.shl, lhs, rhs);
53005316}
53015317
53025318fn zirShr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
src/codegen/llvm.zig+7-1
......@@ -1745,7 +1745,13 @@ pub const FuncGen = struct {
17451745 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
17461746 const lhs = try self.resolveInst(bin_op.lhs);
17471747 const rhs = try self.resolveInst(bin_op.rhs);
1748 return self.builder.buildShl(lhs, rhs, "");
1748 const lhs_type = self.air.typeOf(bin_op.lhs);
1749 const tg = self.dg.module.getTarget();
1750 const casted_rhs = if (self.air.typeOf(bin_op.rhs).bitSize(tg) < lhs_type.bitSize(tg))
1751 self.builder.buildZExt(rhs, try self.dg.llvmType(lhs_type), "")
1752 else
1753 rhs;
1754 return self.builder.buildShl(lhs, casted_rhs, "");
17491755 }
17501756
17511757 fn airShr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
test/stage2/cbe.zig+14-3
......@@ -809,12 +809,23 @@ pub fn addCases(ctx: *TestContext) !void {
809809 }
810810
811811 {
812 var case = ctx.exeUsingLlvmBackend("shift right", linux_x64);
813
812 var case = ctx.exeFromCompiledC("shift right + left", .{});
814813 case.addCompareOutput(
815 \\pub export fn main() void {
814 \\pub export fn main() c_int {
816815 \\ var i: u32 = 16;
817816 \\ assert(i >> 1, 8);
817 \\ return 0;
818 \\}
819 \\fn assert(a: u32, b: u32) void {
820 \\ if (a != b) unreachable;
821 \\}
822 , "");
823
824 case.addCompareOutput(
825 \\pub export fn main() c_int {
826 \\ var i: u32 = 16;
827 \\ assert(i << 1, 32);
828 \\ return 0;
818829 \\}
819830 \\fn assert(a: u32, b: u32) void {
820831 \\ if (a != b) unreachable;
test/stage2/llvm.zig+10-1
......@@ -29,7 +29,7 @@ pub fn addCases(ctx: *TestContext) !void {
2929 }
3030
3131 {
32 var case = ctx.exeUsingLlvmBackend("shift right", linux_x64);
32 var case = ctx.exeUsingLlvmBackend("shift right + left", linux_x64);
3333
3434 case.addCompareOutput(
3535 \\pub export fn main() void {
......@@ -40,6 +40,15 @@ pub fn addCases(ctx: *TestContext) !void {
4040 \\ if (a != b) unreachable;
4141 \\}
4242 , "");
43 case.addCompareOutput(
44 \\pub export fn main() void {
45 \\ var i: u32 = 16;
46 \\ assert(i << 1, 32);
47 \\}
48 \\fn assert(a: u32, b: u32) void {
49 \\ if (a != b) unreachable;
50 \\}
51 , "");
4352 }
4453
4554 {