| author | |
| committer | |
| log | 2e22f7e5a5ff51aa4a1672e011cdc07b08a9a661 |
| tree | f040c30d93c76e2e1376c1029e5cfdd7b6dc0492 |
| parent | 2e6ce11eb29434231102c00fddd0a1b3e0ba5608 |
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 | ... | @@ -5294,9 +5294,25 @@ fn zirShl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A |
| 5294 | const tracy = trace(@src()); | 5294 | const tracy = trace(@src()); |
| 5295 | defer tracy.end(); | 5295 | defer tracy.end(); |
| 5296 | 5296 | ||
| 5297 | _ = block; | 5297 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 5298 | _ = inst; | 5298 | const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; |
| 5299 | return sema.mod.fail(&block.base, sema.src, "TODO implement zirShl", .{}); | 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); | ||
| 5300 | } | 5316 | } |
| 5301 | 5317 | ||
| 5302 | fn zirShr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5318 | fn 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 { | ... | @@ -1745,7 +1745,13 @@ pub const FuncGen = struct { |
| 1745 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 1745 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1746 | const lhs = try self.resolveInst(bin_op.lhs); | 1746 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1747 | const rhs = try self.resolveInst(bin_op.rhs); | 1747 | 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, ""); | ||
| 1749 | } | 1755 | } |
| 1750 | 1756 | ||
| 1751 | fn airShr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 1757 | 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 { | ... | @@ -809,12 +809,23 @@ pub fn addCases(ctx: *TestContext) !void { |
| 809 | } | 809 | } |
| 810 | 810 | ||
| 811 | { | 811 | { |
| 812 | var case = ctx.exeUsingLlvmBackend("shift right", linux_x64); | 812 | var case = ctx.exeFromCompiledC("shift right + left", .{}); |
| 813 | |||
| 814 | case.addCompareOutput( | 813 | case.addCompareOutput( |
| 815 | \\pub export fn main() void { | 814 | \\pub export fn main() c_int { |
| 816 | \\ var i: u32 = 16; | 815 | \\ var i: u32 = 16; |
| 817 | \\ assert(i >> 1, 8); | 816 | \\ 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; | ||
| 818 | \\} | 829 | \\} |
| 819 | \\fn assert(a: u32, b: u32) void { | 830 | \\fn assert(a: u32, b: u32) void { |
| 820 | \\ if (a != b) unreachable; | 831 | \\ if (a != b) unreachable; |
test/stage2/llvm.zig+10-1| ... | @@ -29,7 +29,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -29,7 +29,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | { | 31 | { |
| 32 | var case = ctx.exeUsingLlvmBackend("shift right", linux_x64); | 32 | var case = ctx.exeUsingLlvmBackend("shift right + left", linux_x64); |
| 33 | 33 | ||
| 34 | case.addCompareOutput( | 34 | case.addCompareOutput( |
| 35 | \\pub export fn main() void { | 35 | \\pub export fn main() void { |
| ... | @@ -40,6 +40,15 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -40,6 +40,15 @@ pub fn addCases(ctx: *TestContext) !void { |
| 40 | \\ if (a != b) unreachable; | 40 | \\ if (a != b) unreachable; |
| 41 | \\} | 41 | \\} |
| 42 | , ""); | 42 | , ""); |
| 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 | , ""); | ||
| 43 | } | 52 | } |
| 44 | 53 | ||
| 45 | { | 54 | { |