aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJacob G-W <jacoblevgw@gmail.com>2021-08-19 13:04:52 -0400
committerJacob G-W <jacoblevgw@gmail.com>2021-08-19 16:18:42 -0400
commit2e22f7e5a5ff51aa4a1672e011cdc07b08a9a661 (patch)
treef040c30d93c76e2e1376c1029e5cfdd7b6dc0492 /src
parent2e6ce11eb29434231102c00fddd0a1b3e0ba5608 (diff)
downloadzig-2e22f7e5a5ff51aa4a1672e011cdc07b08a9a661.tar.gz
zig-2e22f7e5a5ff51aa4a1672e011cdc07b08a9a661.zip
stage2: implement shl
This is implemented in the llvm and cbe backends. x86_64 will take a bit more time.
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig22
-rw-r--r--src/codegen/llvm.zig8
2 files changed, 26 insertions, 4 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index d2b2a665e6..360d936b61 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -5294,9 +5294,25 @@ fn zirShl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A
const tracy = trace(@src());
defer tracy.end();
- _ = block;
- _ = inst;
- return sema.mod.fail(&block.base, sema.src, "TODO implement zirShl", .{});
+ const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+ const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
+ const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
+ const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
+ const lhs = sema.resolveInst(extra.lhs);
+ const rhs = sema.resolveInst(extra.rhs);
+
+ if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
+ if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| {
+ if (lhs_val.isUndef() or rhs_val.isUndef()) {
+ return sema.addConstUndef(sema.typeOf(lhs));
+ }
+ return sema.mod.fail(&block.base, src, "TODO implement comptime shl", .{});
+ }
+ }
+
+ try sema.requireRuntimeBlock(block, src);
+ return block.addBinOp(.shl, lhs, rhs);
}
fn zirShr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 4b5ac9efe9..632b275704 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1745,7 +1745,13 @@ pub const FuncGen = struct {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
- return self.builder.buildShl(lhs, rhs, "");
+ const lhs_type = self.air.typeOf(bin_op.lhs);
+ const tg = self.dg.module.getTarget();
+ const casted_rhs = if (self.air.typeOf(bin_op.rhs).bitSize(tg) < lhs_type.bitSize(tg))
+ self.builder.buildZExt(rhs, try self.dg.llvmType(lhs_type), "")
+ else
+ rhs;
+ return self.builder.buildShl(lhs, casted_rhs, "");
}
fn airShr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {