authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-03-07 00:25:21+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-11 14:31:21-05:00
logbdb917006c9920f2a0d2091cb0f3d52454e039f0
tree5ee944462e7096be770e34c51348d88a5aa95426
parentb1a22fdbab4a30a91cd628037f2c7e15978607a5

stage2 tzir: Add wrapping integer arithmetic instructions


4 files changed, 49 insertions(+), 4 deletions(-)

src/codegen.zig+30
...@@ -865,6 +865,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -865,6 +865,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
865 fn genFuncInst(self: *Self, inst: *ir.Inst) !MCValue {865 fn genFuncInst(self: *Self, inst: *ir.Inst) !MCValue {
866 switch (inst.tag) {866 switch (inst.tag) {
867 .add => return self.genAdd(inst.castTag(.add).?),867 .add => return self.genAdd(inst.castTag(.add).?),
868 .addwrap => return self.genAddWrap(inst.castTag(.addwrap).?),
868 .alloc => return self.genAlloc(inst.castTag(.alloc).?),869 .alloc => return self.genAlloc(inst.castTag(.alloc).?),
869 .arg => return self.genArg(inst.castTag(.arg).?),870 .arg => return self.genArg(inst.castTag(.arg).?),
870 .assembly => return self.genAsm(inst.castTag(.assembly).?),871 .assembly => return self.genAsm(inst.castTag(.assembly).?),
...@@ -900,12 +901,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -900,12 +901,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
900 .loop => return self.genLoop(inst.castTag(.loop).?),901 .loop => return self.genLoop(inst.castTag(.loop).?),
901 .not => return self.genNot(inst.castTag(.not).?),902 .not => return self.genNot(inst.castTag(.not).?),
902 .mul => return self.genMul(inst.castTag(.mul).?),903 .mul => return self.genMul(inst.castTag(.mul).?),
904 .mulwrap => return self.genMulWrap(inst.castTag(.mulwrap).?),
903 .ptrtoint => return self.genPtrToInt(inst.castTag(.ptrtoint).?),905 .ptrtoint => return self.genPtrToInt(inst.castTag(.ptrtoint).?),
904 .ref => return self.genRef(inst.castTag(.ref).?),906 .ref => return self.genRef(inst.castTag(.ref).?),
905 .ret => return self.genRet(inst.castTag(.ret).?),907 .ret => return self.genRet(inst.castTag(.ret).?),
906 .retvoid => return self.genRetVoid(inst.castTag(.retvoid).?),908 .retvoid => return self.genRetVoid(inst.castTag(.retvoid).?),
907 .store => return self.genStore(inst.castTag(.store).?),909 .store => return self.genStore(inst.castTag(.store).?),
908 .sub => return self.genSub(inst.castTag(.sub).?),910 .sub => return self.genSub(inst.castTag(.sub).?),
911 .subwrap => return self.genSubWrap(inst.castTag(.subwrap).?),
909 .switchbr => return self.genSwitch(inst.castTag(.switchbr).?),912 .switchbr => return self.genSwitch(inst.castTag(.switchbr).?),
910 .unreach => return MCValue{ .unreach = {} },913 .unreach => return MCValue{ .unreach = {} },
911 .optional_payload => return self.genOptionalPayload(inst.castTag(.optional_payload).?),914 .optional_payload => return self.genOptionalPayload(inst.castTag(.optional_payload).?),
...@@ -1129,6 +1132,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1129,6 +1132,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1129 }1132 }
1130 }1133 }
11311134
1135 fn genAddWrap(self: *Self, inst: *ir.Inst.BinOp) !MCValue {
1136 // No side effects, so if it's unreferenced, do nothing.
1137 if (inst.base.isUnused())
1138 return MCValue.dead;
1139 switch (arch) {
1140 else => return self.fail(inst.base.src, "TODO implement addwrap for {}", .{self.target.cpu.arch}),
1141 }
1142 }
1143
1132 fn genMul(self: *Self, inst: *ir.Inst.BinOp) !MCValue {1144 fn genMul(self: *Self, inst: *ir.Inst.BinOp) !MCValue {
1133 // No side effects, so if it's unreferenced, do nothing.1145 // No side effects, so if it's unreferenced, do nothing.
1134 if (inst.base.isUnused())1146 if (inst.base.isUnused())
...@@ -1139,6 +1151,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1139,6 +1151,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1139 }1151 }
1140 }1152 }
11411153
1154 fn genMulWrap(self: *Self, inst: *ir.Inst.BinOp) !MCValue {
1155 // No side effects, so if it's unreferenced, do nothing.
1156 if (inst.base.isUnused())
1157 return MCValue.dead;
1158 switch (arch) {
1159 else => return self.fail(inst.base.src, "TODO implement mulwrap for {}", .{self.target.cpu.arch}),
1160 }
1161 }
1162
1142 fn genBitAnd(self: *Self, inst: *ir.Inst.BinOp) !MCValue {1163 fn genBitAnd(self: *Self, inst: *ir.Inst.BinOp) !MCValue {
1143 // No side effects, so if it's unreferenced, do nothing.1164 // No side effects, so if it's unreferenced, do nothing.
1144 if (inst.base.isUnused())1165 if (inst.base.isUnused())
...@@ -1392,6 +1413,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1392,6 +1413,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1392 }1413 }
1393 }1414 }
13941415
1416 fn genSubWrap(self: *Self, inst: *ir.Inst.BinOp) !MCValue {
1417 // No side effects, so if it's unreferenced, do nothing.
1418 if (inst.base.isUnused())
1419 return MCValue.dead;
1420 switch (arch) {
1421 else => return self.fail(inst.base.src, "TODO implement subwrap for {}", .{self.target.cpu.arch}),
1422 }
1423 }
1424
1395 fn genArmBinOp(self: *Self, inst: *ir.Inst, op_lhs: *ir.Inst, op_rhs: *ir.Inst, op: ir.Inst.Tag) !MCValue {1425 fn genArmBinOp(self: *Self, inst: *ir.Inst, op_lhs: *ir.Inst, op_rhs: *ir.Inst, op: ir.Inst.Tag) !MCValue {
1396 const lhs = try self.resolveInst(op_lhs);1426 const lhs = try self.resolveInst(op_lhs);
1397 const rhs = try self.resolveInst(op_rhs);1427 const rhs = try self.resolveInst(op_rhs);
src/ir.zig+6
...@@ -53,6 +53,7 @@ pub const Inst = struct {...@@ -53,6 +53,7 @@ pub const Inst = struct {
5353
54 pub const Tag = enum {54 pub const Tag = enum {
55 add,55 add,
56 addwrap,
56 alloc,57 alloc,
57 arg,58 arg,
58 assembly,59 assembly,
...@@ -105,8 +106,10 @@ pub const Inst = struct {...@@ -105,8 +106,10 @@ pub const Inst = struct {
105 /// Write a value to a pointer. LHS is pointer, RHS is value.106 /// Write a value to a pointer. LHS is pointer, RHS is value.
106 store,107 store,
107 sub,108 sub,
109 subwrap,
108 unreach,110 unreach,
109 mul,111 mul,
112 mulwrap,
110 not,113 not,
111 floatcast,114 floatcast,
112 intcast,115 intcast,
...@@ -165,8 +168,11 @@ pub const Inst = struct {...@@ -165,8 +168,11 @@ pub const Inst = struct {
165 => UnOp,168 => UnOp,
166169
167 .add,170 .add,
171 .addwrap,
168 .sub,172 .sub,
173 .subwrap,
169 .mul,174 .mul,
175 .mulwrap,
170 .cmp_lt,176 .cmp_lt,
171 .cmp_lte,177 .cmp_lte,
172 .cmp_eq,178 .cmp_eq,
src/zir.zig+6
...@@ -1680,8 +1680,11 @@ const DumpTzir = struct {...@@ -1680,8 +1680,11 @@ const DumpTzir = struct {
1680 },1680 },
16811681
1682 .add,1682 .add,
1683 .addwrap,
1683 .sub,1684 .sub,
1685 .subwrap,
1684 .mul,1686 .mul,
1687 .mulwrap,
1685 .cmp_lt,1688 .cmp_lt,
1686 .cmp_lte,1689 .cmp_lte,
1687 .cmp_eq,1690 .cmp_eq,
...@@ -1803,8 +1806,11 @@ const DumpTzir = struct {...@@ -1803,8 +1806,11 @@ const DumpTzir = struct {
1803 },1806 },
18041807
1805 .add,1808 .add,
1809 .addwrap,
1806 .sub,1810 .sub,
1811 .subwrap,
1807 .mul,1812 .mul,
1813 .mulwrap,
1808 .cmp_lt,1814 .cmp_lt,
1809 .cmp_lte,1815 .cmp_lte,
1810 .cmp_eq,1816 .cmp_eq,
src/zir_sema.zig+7-4
...@@ -2179,10 +2179,13 @@ fn zirArithmetic(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!...@@ -2179,10 +2179,13 @@ fn zirArithmetic(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!
2179 }2179 }
21802180
2181 const b = try mod.requireRuntimeBlock(scope, inst.base.src);2181 const b = try mod.requireRuntimeBlock(scope, inst.base.src);
2182 const ir_tag = switch (inst.base.tag) {2182 const ir_tag: Inst.Tag = switch (inst.base.tag) {
2183 .add => Inst.Tag.add,2183 .add => .add,
2184 .sub => Inst.Tag.sub,2184 .addwrap => .addwrap,
2185 .mul => Inst.Tag.mul,2185 .sub => .sub,
2186 .subwrap => .subwrap,
2187 .mul => .mul,
2188 .mulwrap => .mulwrap,
2186 else => return mod.fail(scope, inst.base.src, "TODO implement arithmetic for operand '{s}''", .{@tagName(inst.base.tag)}),2189 else => return mod.fail(scope, inst.base.src, "TODO implement arithmetic for operand '{s}''", .{@tagName(inst.base.tag)}),
2187 };2190 };
21882191