authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-02 14:37:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:40:03-07:00
log00f82f1c46126f1fc6655c6142ef16e8e5afbf4e
treeaa9f759bddb01a7469083363da65ef4717509a52
parentc7e84ddb722df0403dd6ae8283820c02efc77e50

stage2: add `interned` AIR tag

This required additionally passing the `InternPool` into some AIR methods. Also, implement `Type.isNoReturn` for interned types.

17 files changed, 1050 insertions(+), 961 deletions(-)

src/Air.zig+32-26
...@@ -11,6 +11,7 @@ const Air = @This();...@@ -11,6 +11,7 @@ const Air = @This();
11const Value = @import("value.zig").Value;11const Value = @import("value.zig").Value;
12const Type = @import("type.zig").Type;12const Type = @import("type.zig").Type;
13const InternPool = @import("InternPool.zig");13const InternPool = @import("InternPool.zig");
14const Module = @import("Module.zig");
1415
15instructions: std.MultiArrayList(Inst).Slice,16instructions: std.MultiArrayList(Inst).Slice,
16/// The meaning of this data is determined by `Inst.Tag` value.17/// The meaning of this data is determined by `Inst.Tag` value.
...@@ -401,6 +402,9 @@ pub const Inst = struct {...@@ -401,6 +402,9 @@ pub const Inst = struct {
401 constant,402 constant,
402 /// A comptime-known type. Uses the `ty` field.403 /// A comptime-known type. Uses the `ty` field.
403 const_ty,404 const_ty,
405 /// A comptime-known value via an index into the InternPool.
406 /// Uses the `interned` field.
407 interned,
404 /// Notes the beginning of a source code statement and marks the line and column.408 /// Notes the beginning of a source code statement and marks the line and column.
405 /// Result type is always void.409 /// Result type is always void.
406 /// Uses the `dbg_stmt` field.410 /// Uses the `dbg_stmt` field.
...@@ -928,6 +932,7 @@ pub const Inst = struct {...@@ -928,6 +932,7 @@ pub const Inst = struct {
928 pub const Data = union {932 pub const Data = union {
929 no_op: void,933 no_op: void,
930 un_op: Ref,934 un_op: Ref,
935 interned: InternPool.Index,
931936
932 bin_op: struct {937 bin_op: struct {
933 lhs: Ref,938 lhs: Ref,
...@@ -1147,18 +1152,15 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index {...@@ -1147,18 +1152,15 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index {
1147 return air.extra[extra.end..][0..extra.data.body_len];1152 return air.extra[extra.end..][0..extra.data.body_len];
1148}1153}
11491154
1150pub fn typeOf(air: Air, inst: Air.Inst.Ref) Type {1155pub fn typeOf(air: Air, inst: Air.Inst.Ref, ip: InternPool) Type {
1151 const ref_int = @enumToInt(inst);1156 const ref_int = @enumToInt(inst);
1152 if (ref_int < InternPool.static_keys.len) {1157 if (ref_int < InternPool.static_keys.len) {
1153 return .{1158 return InternPool.static_keys[ref_int].typeOf().toType();
1154 .ip_index = InternPool.static_keys[ref_int].typeOf(),
1155 .legacy = undefined,
1156 };
1157 }1159 }
1158 return air.typeOfIndex(ref_int - ref_start_index);1160 return air.typeOfIndex(ref_int - ref_start_index, ip);
1159}1161}
11601162
1161pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {1163pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {
1162 const datas = air.instructions.items(.data);1164 const datas = air.instructions.items(.data);
1163 switch (air.instructions.items(.tag)[inst]) {1165 switch (air.instructions.items(.tag)[inst]) {
1164 .add,1166 .add,
...@@ -1200,7 +1202,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -1200,7 +1202,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
1200 .div_exact_optimized,1202 .div_exact_optimized,
1201 .rem_optimized,1203 .rem_optimized,
1202 .mod_optimized,1204 .mod_optimized,
1203 => return air.typeOf(datas[inst].bin_op.lhs),1205 => return air.typeOf(datas[inst].bin_op.lhs, ip),
12041206
1205 .sqrt,1207 .sqrt,
1206 .sin,1208 .sin,
...@@ -1218,7 +1220,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -1218,7 +1220,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
1218 .trunc_float,1220 .trunc_float,
1219 .neg,1221 .neg,
1220 .neg_optimized,1222 .neg_optimized,
1221 => return air.typeOf(datas[inst].un_op),1223 => return air.typeOf(datas[inst].un_op, ip),
12221224
1223 .cmp_lt,1225 .cmp_lt,
1224 .cmp_lte,1226 .cmp_lte,
...@@ -1280,6 +1282,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -1280,6 +1282,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
1280 .try_ptr,1282 .try_ptr,
1281 => return air.getRefType(datas[inst].ty_pl.ty),1283 => return air.getRefType(datas[inst].ty_pl.ty),
12821284
1285 .interned => return ip.indexToKey(datas[inst].interned).typeOf().toType(),
1286
1283 .not,1287 .not,
1284 .bitcast,1288 .bitcast,
1285 .load,1289 .load,
...@@ -1371,33 +1375,33 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -1371,33 +1375,33 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
1371 .tag_name, .error_name => return Type.initTag(.const_slice_u8_sentinel_0),1375 .tag_name, .error_name => return Type.initTag(.const_slice_u8_sentinel_0),
13721376
1373 .call, .call_always_tail, .call_never_tail, .call_never_inline => {1377 .call, .call_always_tail, .call_never_tail, .call_never_inline => {
1374 const callee_ty = air.typeOf(datas[inst].pl_op.operand);1378 const callee_ty = air.typeOf(datas[inst].pl_op.operand, ip);
1375 return callee_ty.fnReturnType();1379 return callee_ty.fnReturnType();
1376 },1380 },
13771381
1378 .slice_elem_val, .ptr_elem_val, .array_elem_val => {1382 .slice_elem_val, .ptr_elem_val, .array_elem_val => {
1379 const ptr_ty = air.typeOf(datas[inst].bin_op.lhs);1383 const ptr_ty = air.typeOf(datas[inst].bin_op.lhs, ip);
1380 return ptr_ty.elemType();1384 return ptr_ty.elemType();
1381 },1385 },
1382 .atomic_load => {1386 .atomic_load => {
1383 const ptr_ty = air.typeOf(datas[inst].atomic_load.ptr);1387 const ptr_ty = air.typeOf(datas[inst].atomic_load.ptr, ip);
1384 return ptr_ty.elemType();1388 return ptr_ty.elemType();
1385 },1389 },
1386 .atomic_rmw => {1390 .atomic_rmw => {
1387 const ptr_ty = air.typeOf(datas[inst].pl_op.operand);1391 const ptr_ty = air.typeOf(datas[inst].pl_op.operand, ip);
1388 return ptr_ty.elemType();1392 return ptr_ty.elemType();
1389 },1393 },
13901394
1391 .reduce, .reduce_optimized => return air.typeOf(datas[inst].reduce.operand).childType(),1395 .reduce, .reduce_optimized => return air.typeOf(datas[inst].reduce.operand, ip).childType(),
13921396
1393 .mul_add => return air.typeOf(datas[inst].pl_op.operand),1397 .mul_add => return air.typeOf(datas[inst].pl_op.operand, ip),
1394 .select => {1398 .select => {
1395 const extra = air.extraData(Air.Bin, datas[inst].pl_op.payload).data;1399 const extra = air.extraData(Air.Bin, datas[inst].pl_op.payload).data;
1396 return air.typeOf(extra.lhs);1400 return air.typeOf(extra.lhs, ip);
1397 },1401 },
13981402
1399 .@"try" => {1403 .@"try" => {
1400 const err_union_ty = air.typeOf(datas[inst].pl_op.operand);1404 const err_union_ty = air.typeOf(datas[inst].pl_op.operand, ip);
1401 return err_union_ty.errorUnionPayload();1405 return err_union_ty.errorUnionPayload();
1402 },1406 },
14031407
...@@ -1465,7 +1469,7 @@ pub fn refToIndex(inst: Air.Inst.Ref) ?Air.Inst.Index {...@@ -1465,7 +1469,7 @@ pub fn refToIndex(inst: Air.Inst.Ref) ?Air.Inst.Index {
1465}1469}
14661470
1467/// Returns `null` if runtime-known.1471/// Returns `null` if runtime-known.
1468pub fn value(air: Air, inst: Air.Inst.Ref, mod: *const @import("Module.zig")) ?Value {1472pub fn value(air: Air, inst: Air.Inst.Ref, mod: *const Module) ?Value {
1469 const ref_int = @enumToInt(inst);1473 const ref_int = @enumToInt(inst);
1470 if (ref_int < ref_start_index) {1474 if (ref_int < ref_start_index) {
1471 const ip_index = @intToEnum(InternPool.Index, ref_int);1475 const ip_index = @intToEnum(InternPool.Index, ref_int);
...@@ -1476,7 +1480,7 @@ pub fn value(air: Air, inst: Air.Inst.Ref, mod: *const @import("Module.zig")) ?V...@@ -1476,7 +1480,7 @@ pub fn value(air: Air, inst: Air.Inst.Ref, mod: *const @import("Module.zig")) ?V
1476 switch (air.instructions.items(.tag)[inst_index]) {1480 switch (air.instructions.items(.tag)[inst_index]) {
1477 .constant => return air.values[air_datas[inst_index].ty_pl.payload],1481 .constant => return air.values[air_datas[inst_index].ty_pl.payload],
1478 .const_ty => unreachable,1482 .const_ty => unreachable,
1479 else => return air.typeOfIndex(inst_index).onePossibleValue(mod),1483 else => return air.typeOfIndex(inst_index, mod.intern_pool).onePossibleValue(mod),
1480 }1484 }
1481}1485}
14821486
...@@ -1489,10 +1493,11 @@ pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 {...@@ -1489,10 +1493,11 @@ pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 {
1489 return bytes[0..end :0];1493 return bytes[0..end :0];
1490}1494}
14911495
1492/// Returns whether the given instruction must always be lowered, for instance because it can cause1496/// Returns whether the given instruction must always be lowered, for instance
1493/// side effects. If an instruction does not need to be lowered, and Liveness determines its result1497/// because it can cause side effects. If an instruction does not need to be
1494/// is unused, backends should avoid lowering it.1498/// lowered, and Liveness determines its result is unused, backends should
1495pub fn mustLower(air: Air, inst: Air.Inst.Index) bool {1499/// avoid lowering it.
1500pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: InternPool) bool {
1496 const data = air.instructions.items(.data)[inst];1501 const data = air.instructions.items(.data)[inst];
1497 return switch (air.instructions.items(.tag)[inst]) {1502 return switch (air.instructions.items(.tag)[inst]) {
1498 .arg,1503 .arg,
...@@ -1631,6 +1636,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index) bool {...@@ -1631,6 +1636,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index) bool {
1631 .cmp_vector_optimized,1636 .cmp_vector_optimized,
1632 .constant,1637 .constant,
1633 .const_ty,1638 .const_ty,
1639 .interned,
1634 .is_null,1640 .is_null,
1635 .is_non_null,1641 .is_non_null,
1636 .is_null_ptr,1642 .is_null_ptr,
...@@ -1699,8 +1705,8 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index) bool {...@@ -1699,8 +1705,8 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index) bool {
1699 => false,1705 => false,
17001706
1701 .assembly => @truncate(u1, air.extraData(Air.Asm, data.ty_pl.payload).data.flags >> 31) != 0,1707 .assembly => @truncate(u1, air.extraData(Air.Asm, data.ty_pl.payload).data.flags >> 31) != 0,
1702 .load => air.typeOf(data.ty_op.operand).isVolatilePtr(),1708 .load => air.typeOf(data.ty_op.operand, ip).isVolatilePtr(),
1703 .slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs).isVolatilePtr(),1709 .slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs, ip).isVolatilePtr(),
1704 .atomic_load => air.typeOf(data.atomic_load.ptr).isVolatilePtr(),1710 .atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtr(),
1705 };1711 };
1706}1712}
src/InternPool.zig+6
...@@ -241,6 +241,11 @@ pub const Item = struct {...@@ -241,6 +241,11 @@ pub const Item = struct {
241/// When adding a tag to this enum, consider adding a corresponding entry to241/// When adding a tag to this enum, consider adding a corresponding entry to
242/// `primitives` in AstGen.zig.242/// `primitives` in AstGen.zig.
243pub const Index = enum(u32) {243pub const Index = enum(u32) {
244 pub const first_type: Index = .u1_type;
245 pub const last_type: Index = .empty_struct_type;
246 pub const first_value: Index = .undef;
247 pub const last_value: Index = .empty_struct;
248
244 u1_type,249 u1_type,
245 u8_type,250 u8_type,
246 i8_type,251 i8_type,
...@@ -329,6 +334,7 @@ pub const Index = enum(u32) {...@@ -329,6 +334,7 @@ pub const Index = enum(u32) {
329 bool_false,334 bool_false,
330 /// `.{}` (untyped)335 /// `.{}` (untyped)
331 empty_struct,336 empty_struct,
337
332 /// Used for generic parameters where the type and value338 /// Used for generic parameters where the type and value
333 /// is not known until generic function instantiation.339 /// is not known until generic function instantiation.
334 generic_poison,340 generic_poison,
src/Liveness.zig+12-6
...@@ -131,7 +131,7 @@ fn LivenessPassData(comptime pass: LivenessPass) type {...@@ -131,7 +131,7 @@ fn LivenessPassData(comptime pass: LivenessPass) type {
131 };131 };
132}132}
133133
134pub fn analyze(gpa: Allocator, air: Air) Allocator.Error!Liveness {134pub fn analyze(gpa: Allocator, air: Air, intern_pool: *const InternPool) Allocator.Error!Liveness {
135 const tracy = trace(@src());135 const tracy = trace(@src());
136 defer tracy.end();136 defer tracy.end();
137137
...@@ -144,6 +144,7 @@ pub fn analyze(gpa: Allocator, air: Air) Allocator.Error!Liveness {...@@ -144,6 +144,7 @@ pub fn analyze(gpa: Allocator, air: Air) Allocator.Error!Liveness {
144 ),144 ),
145 .extra = .{},145 .extra = .{},
146 .special = .{},146 .special = .{},
147 .intern_pool = intern_pool,
147 };148 };
148 errdefer gpa.free(a.tomb_bits);149 errdefer gpa.free(a.tomb_bits);
149 errdefer a.special.deinit(gpa);150 errdefer a.special.deinit(gpa);
...@@ -322,6 +323,7 @@ pub fn categorizeOperand(...@@ -322,6 +323,7 @@ pub fn categorizeOperand(
322 .ret_ptr,323 .ret_ptr,
323 .constant,324 .constant,
324 .const_ty,325 .const_ty,
326 .interned,
325 .trap,327 .trap,
326 .breakpoint,328 .breakpoint,
327 .dbg_stmt,329 .dbg_stmt,
...@@ -820,6 +822,7 @@ pub const BigTomb = struct {...@@ -820,6 +822,7 @@ pub const BigTomb = struct {
820const Analysis = struct {822const Analysis = struct {
821 gpa: Allocator,823 gpa: Allocator,
822 air: Air,824 air: Air,
825 intern_pool: *const InternPool,
823 tomb_bits: []usize,826 tomb_bits: []usize,
824 special: std.AutoHashMapUnmanaged(Air.Inst.Index, u32),827 special: std.AutoHashMapUnmanaged(Air.Inst.Index, u32),
825 extra: std.ArrayListUnmanaged(u32),828 extra: std.ArrayListUnmanaged(u32),
...@@ -971,6 +974,7 @@ fn analyzeInst(...@@ -971,6 +974,7 @@ fn analyzeInst(
971974
972 .constant,975 .constant,
973 .const_ty,976 .const_ty,
977 .interned,
974 => unreachable,978 => unreachable,
975979
976 .trap,980 .trap,
...@@ -1255,6 +1259,7 @@ fn analyzeOperands(...@@ -1255,6 +1259,7 @@ fn analyzeOperands(
1255) Allocator.Error!void {1259) Allocator.Error!void {
1256 const gpa = a.gpa;1260 const gpa = a.gpa;
1257 const inst_tags = a.air.instructions.items(.tag);1261 const inst_tags = a.air.instructions.items(.tag);
1262 const ip = a.intern_pool;
12581263
1259 switch (pass) {1264 switch (pass) {
1260 .loop_analysis => {1265 .loop_analysis => {
...@@ -1265,7 +1270,7 @@ fn analyzeOperands(...@@ -1265,7 +1270,7 @@ fn analyzeOperands(
12651270
1266 // Don't compute any liveness for constants1271 // Don't compute any liveness for constants
1267 switch (inst_tags[operand]) {1272 switch (inst_tags[operand]) {
1268 .constant, .const_ty => continue,1273 .constant, .const_ty, .interned => continue,
1269 else => {},1274 else => {},
1270 }1275 }
12711276
...@@ -1290,7 +1295,7 @@ fn analyzeOperands(...@@ -1290,7 +1295,7 @@ fn analyzeOperands(
1290 // If our result is unused and the instruction doesn't need to be lowered, backends will1295 // If our result is unused and the instruction doesn't need to be lowered, backends will
1291 // skip the lowering of this instruction, so we don't want to record uses of operands.1296 // skip the lowering of this instruction, so we don't want to record uses of operands.
1292 // That way, we can mark as many instructions as possible unused.1297 // That way, we can mark as many instructions as possible unused.
1293 if (!immediate_death or a.air.mustLower(inst)) {1298 if (!immediate_death or a.air.mustLower(inst, ip.*)) {
1294 // Note that it's important we iterate over the operands backwards, so that if a dying1299 // Note that it's important we iterate over the operands backwards, so that if a dying
1295 // operand is used multiple times we mark its last use as its death.1300 // operand is used multiple times we mark its last use as its death.
1296 var i = operands.len;1301 var i = operands.len;
...@@ -1301,7 +1306,7 @@ fn analyzeOperands(...@@ -1301,7 +1306,7 @@ fn analyzeOperands(
13011306
1302 // Don't compute any liveness for constants1307 // Don't compute any liveness for constants
1303 switch (inst_tags[operand]) {1308 switch (inst_tags[operand]) {
1304 .constant, .const_ty => continue,1309 .constant, .const_ty, .interned => continue,
1305 else => {},1310 else => {},
1306 }1311 }
13071312
...@@ -1821,6 +1826,7 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type {...@@ -1821,6 +1826,7 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type {
18211826
1822 /// Must be called with operands in reverse order.1827 /// Must be called with operands in reverse order.
1823 fn feed(big: *Self, op_ref: Air.Inst.Ref) !void {1828 fn feed(big: *Self, op_ref: Air.Inst.Ref) !void {
1829 const ip = big.a.intern_pool;
1824 // Note that after this, `operands_remaining` becomes the index of the current operand1830 // Note that after this, `operands_remaining` becomes the index of the current operand
1825 big.operands_remaining -= 1;1831 big.operands_remaining -= 1;
18261832
...@@ -1834,14 +1840,14 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type {...@@ -1834,14 +1840,14 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type {
1834 // Don't compute any liveness for constants1840 // Don't compute any liveness for constants
1835 const inst_tags = big.a.air.instructions.items(.tag);1841 const inst_tags = big.a.air.instructions.items(.tag);
1836 switch (inst_tags[operand]) {1842 switch (inst_tags[operand]) {
1837 .constant, .const_ty => return,1843 .constant, .const_ty, .interned => return,
1838 else => {},1844 else => {},
1839 }1845 }
18401846
1841 // If our result is unused and the instruction doesn't need to be lowered, backends will1847 // If our result is unused and the instruction doesn't need to be lowered, backends will
1842 // skip the lowering of this instruction, so we don't want to record uses of operands.1848 // skip the lowering of this instruction, so we don't want to record uses of operands.
1843 // That way, we can mark as many instructions as possible unused.1849 // That way, we can mark as many instructions as possible unused.
1844 if (big.will_die_immediately and !big.a.air.mustLower(big.inst)) return;1850 if (big.will_die_immediately and !big.a.air.mustLower(big.inst, ip.*)) return;
18451851
1846 const extra_byte = (big.operands_remaining - (bpi - 1)) / 31;1852 const extra_byte = (big.operands_remaining - (bpi - 1)) / 31;
1847 const extra_bit = @intCast(u5, big.operands_remaining - (bpi - 1) - extra_byte * 31);1853 const extra_bit = @intCast(u5, big.operands_remaining - (bpi - 1) - extra_byte * 31);
src/Liveness/Verify.zig+7-3
...@@ -5,6 +5,7 @@ air: Air,...@@ -5,6 +5,7 @@ air: Air,
5liveness: Liveness,5liveness: Liveness,
6live: LiveMap = .{},6live: LiveMap = .{},
7blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, LiveMap) = .{},7blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, LiveMap) = .{},
8intern_pool: *const InternPool,
89
9pub const Error = error{ LivenessInvalid, OutOfMemory };10pub const Error = error{ LivenessInvalid, OutOfMemory };
1011
...@@ -27,10 +28,11 @@ pub fn verify(self: *Verify) Error!void {...@@ -27,10 +28,11 @@ pub fn verify(self: *Verify) Error!void {
27const LiveMap = std.AutoHashMapUnmanaged(Air.Inst.Index, void);28const LiveMap = std.AutoHashMapUnmanaged(Air.Inst.Index, void);
2829
29fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {30fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
31 const ip = self.intern_pool;
30 const tag = self.air.instructions.items(.tag);32 const tag = self.air.instructions.items(.tag);
31 const data = self.air.instructions.items(.data);33 const data = self.air.instructions.items(.data);
32 for (body) |inst| {34 for (body) |inst| {
33 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {35 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*)) {
34 // This instruction will not be lowered and should be ignored.36 // This instruction will not be lowered and should be ignored.
35 continue;37 continue;
36 }38 }
...@@ -42,6 +44,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {...@@ -42,6 +44,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
42 .ret_ptr,44 .ret_ptr,
43 .constant,45 .constant,
44 .const_ty,46 .const_ty,
47 .interned,
45 .breakpoint,48 .breakpoint,
46 .dbg_stmt,49 .dbg_stmt,
47 .dbg_inline_begin,50 .dbg_inline_begin,
...@@ -554,7 +557,7 @@ fn verifyDeath(self: *Verify, inst: Air.Inst.Index, operand: Air.Inst.Index) Err...@@ -554,7 +557,7 @@ fn verifyDeath(self: *Verify, inst: Air.Inst.Index, operand: Air.Inst.Index) Err
554fn verifyOperand(self: *Verify, inst: Air.Inst.Index, op_ref: Air.Inst.Ref, dies: bool) Error!void {557fn verifyOperand(self: *Verify, inst: Air.Inst.Index, op_ref: Air.Inst.Ref, dies: bool) Error!void {
555 const operand = Air.refToIndex(op_ref) orelse return;558 const operand = Air.refToIndex(op_ref) orelse return;
556 switch (self.air.instructions.items(.tag)[operand]) {559 switch (self.air.instructions.items(.tag)[operand]) {
557 .constant, .const_ty => {},560 .constant, .const_ty, .interned => {},
558 else => {561 else => {
559 if (dies) {562 if (dies) {
560 if (!self.live.remove(operand)) return invalid("%{}: dead operand %{} reused and killed again", .{ inst, operand });563 if (!self.live.remove(operand)) return invalid("%{}: dead operand %{} reused and killed again", .{ inst, operand });
...@@ -576,7 +579,7 @@ fn verifyInst(...@@ -576,7 +579,7 @@ fn verifyInst(
576 }579 }
577 const tag = self.air.instructions.items(.tag);580 const tag = self.air.instructions.items(.tag);
578 switch (tag[inst]) {581 switch (tag[inst]) {
579 .constant, .const_ty => unreachable,582 .constant, .const_ty, .interned => unreachable,
580 else => {583 else => {
581 if (self.liveness.isUnused(inst)) {584 if (self.liveness.isUnused(inst)) {
582 assert(!self.live.contains(inst));585 assert(!self.live.contains(inst));
...@@ -604,4 +607,5 @@ const log = std.log.scoped(.liveness_verify);...@@ -604,4 +607,5 @@ const log = std.log.scoped(.liveness_verify);
604607
605const Air = @import("../Air.zig");608const Air = @import("../Air.zig");
606const Liveness = @import("../Liveness.zig");609const Liveness = @import("../Liveness.zig");
610const InternPool = @import("../InternPool.zig");
607const Verify = @This();611const Verify = @This();
src/Module.zig+2-1
...@@ -4397,7 +4397,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {...@@ -4397,7 +4397,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
4397 if (no_bin_file and !dump_air and !dump_llvm_ir) return;4397 if (no_bin_file and !dump_air and !dump_llvm_ir) return;
43984398
4399 log.debug("analyze liveness of {s}", .{decl.name});4399 log.debug("analyze liveness of {s}", .{decl.name});
4400 var liveness = try Liveness.analyze(gpa, air);4400 var liveness = try Liveness.analyze(gpa, air, &mod.intern_pool);
4401 defer liveness.deinit(gpa);4401 defer liveness.deinit(gpa);
44024402
4403 if (dump_air) {4403 if (dump_air) {
...@@ -4414,6 +4414,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {...@@ -4414,6 +4414,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
4414 .gpa = gpa,4414 .gpa = gpa,
4415 .air = air,4415 .air = air,
4416 .liveness = liveness,4416 .liveness = liveness,
4417 .intern_pool = &mod.intern_pool,
4417 };4418 };
4418 defer verify.deinit();4419 defer verify.deinit();
44194420
src/Sema.zig+9-83
...@@ -33007,7 +33007,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33007,7 +33007,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3300733007
33008/// Returns the type of the AIR instruction.33008/// Returns the type of the AIR instruction.
33009fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type {33009fn typeOf(sema: *Sema, inst: Air.Inst.Ref) Type {
33010 return sema.getTmpAir().typeOf(inst);33010 return sema.getTmpAir().typeOf(inst, sema.mod.intern_pool);
33011}33011}
3301233012
33013pub fn getTmpAir(sema: Sema) Air {33013pub fn getTmpAir(sema: Sema) Air {
...@@ -33019,88 +33019,14 @@ pub fn getTmpAir(sema: Sema) Air {...@@ -33019,88 +33019,14 @@ pub fn getTmpAir(sema: Sema) Air {
33019}33019}
3302033020
33021pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {33021pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
33022 switch (ty.ip_index) {33022 if (ty.ip_index != .none) {
33023 .u1_type => return .u1_type,33023 if (@enumToInt(ty.ip_index) < Air.ref_start_index)
33024 .u8_type => return .u8_type,33024 return @intToEnum(Air.Inst.Ref, @enumToInt(ty.ip_index));
33025 .i8_type => return .i8_type,33025 try sema.air_instructions.append(sema.gpa, .{
33026 .u16_type => return .u16_type,33026 .tag = .interned,
33027 .i16_type => return .i16_type,33027 .data = .{ .interned = ty.ip_index },
33028 .u29_type => return .u29_type,33028 });
33029 .u32_type => return .u32_type,33029 return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1));
33030 .i32_type => return .i32_type,
33031 .u64_type => return .u64_type,
33032 .i64_type => return .i64_type,
33033 .u80_type => return .u80_type,
33034 .u128_type => return .u128_type,
33035 .i128_type => return .i128_type,
33036 .usize_type => return .usize_type,
33037 .isize_type => return .isize_type,
33038 .c_char_type => return .c_char_type,
33039 .c_short_type => return .c_short_type,
33040 .c_ushort_type => return .c_ushort_type,
33041 .c_int_type => return .c_int_type,
33042 .c_uint_type => return .c_uint_type,
33043 .c_long_type => return .c_long_type,
33044 .c_ulong_type => return .c_ulong_type,
33045 .c_longlong_type => return .c_longlong_type,
33046 .c_ulonglong_type => return .c_ulonglong_type,
33047 .c_longdouble_type => return .c_longdouble_type,
33048 .f16_type => return .f16_type,
33049 .f32_type => return .f32_type,
33050 .f64_type => return .f64_type,
33051 .f80_type => return .f80_type,
33052 .f128_type => return .f128_type,
33053 .anyopaque_type => return .anyopaque_type,
33054 .bool_type => return .bool_type,
33055 .void_type => return .void_type,
33056 .type_type => return .type_type,
33057 .anyerror_type => return .anyerror_type,
33058 .comptime_int_type => return .comptime_int_type,
33059 .comptime_float_type => return .comptime_float_type,
33060 .noreturn_type => return .noreturn_type,
33061 .anyframe_type => return .anyframe_type,
33062 .null_type => return .null_type,
33063 .undefined_type => return .undefined_type,
33064 .enum_literal_type => return .enum_literal_type,
33065 .atomic_order_type => return .atomic_order_type,
33066 .atomic_rmw_op_type => return .atomic_rmw_op_type,
33067 .calling_convention_type => return .calling_convention_type,
33068 .address_space_type => return .address_space_type,
33069 .float_mode_type => return .float_mode_type,
33070 .reduce_op_type => return .reduce_op_type,
33071 .call_modifier_type => return .call_modifier_type,
33072 .prefetch_options_type => return .prefetch_options_type,
33073 .export_options_type => return .export_options_type,
33074 .extern_options_type => return .extern_options_type,
33075 .type_info_type => return .type_info_type,
33076 .manyptr_u8_type => return .manyptr_u8_type,
33077 .manyptr_const_u8_type => return .manyptr_const_u8_type,
33078 .single_const_pointer_to_comptime_int_type => return .single_const_pointer_to_comptime_int_type,
33079 .const_slice_u8_type => return .const_slice_u8_type,
33080 .anyerror_void_error_union_type => return .anyerror_void_error_union_type,
33081 .generic_poison_type => return .generic_poison_type,
33082 .var_args_param_type => return .var_args_param_type,
33083 .empty_struct_type => return .empty_struct_type,
33084
33085 // values
33086 .undef => unreachable,
33087 .zero => unreachable,
33088 .zero_usize => unreachable,
33089 .one => unreachable,
33090 .one_usize => unreachable,
33091 .calling_convention_c => unreachable,
33092 .calling_convention_inline => unreachable,
33093 .void_value => unreachable,
33094 .unreachable_value => unreachable,
33095 .null_value => unreachable,
33096 .bool_true => unreachable,
33097 .bool_false => unreachable,
33098 .empty_struct => unreachable,
33099 .generic_poison => unreachable,
33100
33101 _ => {},
33102
33103 .none => unreachable,
33104 }33030 }
33105 switch (ty.tag()) {33031 switch (ty.tag()) {
33106 .u1 => return .u1_type,33032 .u1 => return .u1_type,
src/arch/aarch64/CodeGen.zig+92-80
...@@ -521,7 +521,7 @@ fn gen(self: *Self) !void {...@@ -521,7 +521,7 @@ fn gen(self: *Self) !void {
521 const inst = self.air.getMainBody()[arg_index];521 const inst = self.air.getMainBody()[arg_index];
522 assert(self.air.instructions.items(.tag)[inst] == .arg);522 assert(self.air.instructions.items(.tag)[inst] == .arg);
523523
524 const ty = self.air.typeOfIndex(inst);524 const ty = self.typeOfIndex(inst);
525525
526 const abi_size = @intCast(u32, ty.abiSize(mod));526 const abi_size = @intCast(u32, ty.abiSize(mod));
527 const abi_align = ty.abiAlignment(mod);527 const abi_align = ty.abiAlignment(mod);
...@@ -653,13 +653,14 @@ fn gen(self: *Self) !void {...@@ -653,13 +653,14 @@ fn gen(self: *Self) !void {
653}653}
654654
655fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {655fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
656 const mod = self.bin_file.options.module.?;
657 const ip = &mod.intern_pool;
656 const air_tags = self.air.instructions.items(.tag);658 const air_tags = self.air.instructions.items(.tag);
657659
658 for (body) |inst| {660 for (body) |inst| {
659 // TODO: remove now-redundant isUnused calls from AIR handler functions661 // TODO: remove now-redundant isUnused calls from AIR handler functions
660 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {662 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
661 continue;663 continue;
662 }
663664
664 const old_air_bookkeeping = self.air_bookkeeping;665 const old_air_bookkeeping = self.air_bookkeeping;
665 try self.ensureProcessDeathCapacity(Liveness.bpi);666 try self.ensureProcessDeathCapacity(Liveness.bpi);
...@@ -845,6 +846,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -845,6 +846,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
845846
846 .constant => unreachable, // excluded from function bodies847 .constant => unreachable, // excluded from function bodies
847 .const_ty => unreachable, // excluded from function bodies848 .const_ty => unreachable, // excluded from function bodies
849 .interned => unreachable, // excluded from function bodies
848 .unreach => self.finishAirBookkeeping(),850 .unreach => self.finishAirBookkeeping(),
849851
850 .optional_payload => try self.airOptionalPayload(inst),852 .optional_payload => try self.airOptionalPayload(inst),
...@@ -1028,7 +1030,7 @@ fn allocMem(...@@ -1028,7 +1030,7 @@ fn allocMem(
1028/// Use a pointer instruction as the basis for allocating stack memory.1030/// Use a pointer instruction as the basis for allocating stack memory.
1029fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {1031fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1030 const mod = self.bin_file.options.module.?;1032 const mod = self.bin_file.options.module.?;
1031 const elem_ty = self.air.typeOfIndex(inst).elemType();1033 const elem_ty = self.typeOfIndex(inst).elemType();
10321034
1033 if (!elem_ty.hasRuntimeBits(mod)) {1035 if (!elem_ty.hasRuntimeBits(mod)) {
1034 // return the stack offset 0. Stack offset 0 will be where all1036 // return the stack offset 0. Stack offset 0 will be where all
...@@ -1067,7 +1069,7 @@ fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst...@@ -1067,7 +1069,7 @@ fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst
1067}1069}
10681070
1069pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {1071pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {
1070 const stack_mcv = try self.allocRegOrMem(self.air.typeOfIndex(inst), false, inst);1072 const stack_mcv = try self.allocRegOrMem(self.typeOfIndex(inst), false, inst);
1071 log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv });1073 log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv });
10721074
1073 const reg_mcv = self.getResolvedInstValue(inst);1075 const reg_mcv = self.getResolvedInstValue(inst);
...@@ -1079,14 +1081,14 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void...@@ -1079,14 +1081,14 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
10791081
1080 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];1082 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
1081 try branch.inst_table.put(self.gpa, inst, stack_mcv);1083 try branch.inst_table.put(self.gpa, inst, stack_mcv);
1082 try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);1084 try self.genSetStack(self.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
1083}1085}
10841086
1085/// Save the current instruction stored in the compare flags if1087/// Save the current instruction stored in the compare flags if
1086/// occupied1088/// occupied
1087fn spillCompareFlagsIfOccupied(self: *Self) !void {1089fn spillCompareFlagsIfOccupied(self: *Self) !void {
1088 if (self.compare_flags_inst) |inst_to_save| {1090 if (self.compare_flags_inst) |inst_to_save| {
1089 const ty = self.air.typeOfIndex(inst_to_save);1091 const ty = self.typeOfIndex(inst_to_save);
1090 const mcv = self.getResolvedInstValue(inst_to_save);1092 const mcv = self.getResolvedInstValue(inst_to_save);
1091 const new_mcv = switch (mcv) {1093 const new_mcv = switch (mcv) {
1092 .compare_flags => try self.allocRegOrMem(ty, true, inst_to_save),1094 .compare_flags => try self.allocRegOrMem(ty, true, inst_to_save),
...@@ -1094,7 +1096,7 @@ fn spillCompareFlagsIfOccupied(self: *Self) !void {...@@ -1094,7 +1096,7 @@ fn spillCompareFlagsIfOccupied(self: *Self) !void {
1094 else => unreachable, // mcv doesn't occupy the compare flags1096 else => unreachable, // mcv doesn't occupy the compare flags
1095 };1097 };
10961098
1097 try self.setRegOrMem(self.air.typeOfIndex(inst_to_save), new_mcv, mcv);1099 try self.setRegOrMem(self.typeOfIndex(inst_to_save), new_mcv, mcv);
1098 log.debug("spilling {d} to mcv {any}", .{ inst_to_save, new_mcv });1100 log.debug("spilling {d} to mcv {any}", .{ inst_to_save, new_mcv });
10991101
1100 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];1102 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
...@@ -1126,9 +1128,9 @@ fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register {...@@ -1126,9 +1128,9 @@ fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register {
1126/// This can have a side effect of spilling instructions to the stack to free up a register.1128/// This can have a side effect of spilling instructions to the stack to free up a register.
1127fn copyToNewRegister(self: *Self, reg_owner: Air.Inst.Index, mcv: MCValue) !MCValue {1129fn copyToNewRegister(self: *Self, reg_owner: Air.Inst.Index, mcv: MCValue) !MCValue {
1128 const raw_reg = try self.register_manager.allocReg(reg_owner, gp);1130 const raw_reg = try self.register_manager.allocReg(reg_owner, gp);
1129 const ty = self.air.typeOfIndex(reg_owner);1131 const ty = self.typeOfIndex(reg_owner);
1130 const reg = self.registerAlias(raw_reg, ty);1132 const reg = self.registerAlias(raw_reg, ty);
1131 try self.genSetReg(self.air.typeOfIndex(reg_owner), reg, mcv);1133 try self.genSetReg(self.typeOfIndex(reg_owner), reg, mcv);
1132 return MCValue{ .register = reg };1134 return MCValue{ .register = reg };
1133}1135}
11341136
...@@ -1181,10 +1183,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -1181,10 +1183,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1181 const mod = self.bin_file.options.module.?;1183 const mod = self.bin_file.options.module.?;
1182 const operand = ty_op.operand;1184 const operand = ty_op.operand;
1183 const operand_mcv = try self.resolveInst(operand);1185 const operand_mcv = try self.resolveInst(operand);
1184 const operand_ty = self.air.typeOf(operand);1186 const operand_ty = self.typeOf(operand);
1185 const operand_info = operand_ty.intInfo(mod);1187 const operand_info = operand_ty.intInfo(mod);
11861188
1187 const dest_ty = self.air.typeOfIndex(inst);1189 const dest_ty = self.typeOfIndex(inst);
1188 const dest_info = dest_ty.intInfo(mod);1190 const dest_info = dest_ty.intInfo(mod);
11891191
1190 const result: MCValue = result: {1192 const result: MCValue = result: {
...@@ -1201,14 +1203,14 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -1201,14 +1203,14 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
12011203
1202 if (dest_info.bits > operand_info.bits) {1204 if (dest_info.bits > operand_info.bits) {
1203 const dest_mcv = try self.allocRegOrMem(dest_ty, true, inst);1205 const dest_mcv = try self.allocRegOrMem(dest_ty, true, inst);
1204 try self.setRegOrMem(self.air.typeOfIndex(inst), dest_mcv, truncated);1206 try self.setRegOrMem(self.typeOfIndex(inst), dest_mcv, truncated);
1205 break :result dest_mcv;1207 break :result dest_mcv;
1206 } else {1208 } else {
1207 if (self.reuseOperand(inst, operand, 0, truncated)) {1209 if (self.reuseOperand(inst, operand, 0, truncated)) {
1208 break :result truncated;1210 break :result truncated;
1209 } else {1211 } else {
1210 const dest_mcv = try self.allocRegOrMem(dest_ty, true, inst);1212 const dest_mcv = try self.allocRegOrMem(dest_ty, true, inst);
1211 try self.setRegOrMem(self.air.typeOfIndex(inst), dest_mcv, truncated);1213 try self.setRegOrMem(self.typeOfIndex(inst), dest_mcv, truncated);
1212 break :result dest_mcv;1214 break :result dest_mcv;
1213 }1215 }
1214 }1216 }
...@@ -1303,8 +1305,8 @@ fn trunc(...@@ -1303,8 +1305,8 @@ fn trunc(
1303fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {1305fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
1304 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1306 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1305 const operand = try self.resolveInst(ty_op.operand);1307 const operand = try self.resolveInst(ty_op.operand);
1306 const operand_ty = self.air.typeOf(ty_op.operand);1308 const operand_ty = self.typeOf(ty_op.operand);
1307 const dest_ty = self.air.typeOfIndex(inst);1309 const dest_ty = self.typeOfIndex(inst);
13081310
1309 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {1311 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
1310 break :blk try self.trunc(inst, operand, operand_ty, dest_ty);1312 break :blk try self.trunc(inst, operand, operand_ty, dest_ty);
...@@ -1325,7 +1327,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -1325,7 +1327,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1325 const mod = self.bin_file.options.module.?;1327 const mod = self.bin_file.options.module.?;
1326 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1328 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1327 const operand = try self.resolveInst(ty_op.operand);1329 const operand = try self.resolveInst(ty_op.operand);
1328 const operand_ty = self.air.typeOf(ty_op.operand);1330 const operand_ty = self.typeOf(ty_op.operand);
1329 switch (operand) {1331 switch (operand) {
1330 .dead => unreachable,1332 .dead => unreachable,
1331 .unreach => unreachable,1333 .unreach => unreachable,
...@@ -1492,8 +1494,8 @@ fn minMax(...@@ -1492,8 +1494,8 @@ fn minMax(
1492fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {1494fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {
1493 const tag = self.air.instructions.items(.tag)[inst];1495 const tag = self.air.instructions.items(.tag)[inst];
1494 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1496 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1495 const lhs_ty = self.air.typeOf(bin_op.lhs);1497 const lhs_ty = self.typeOf(bin_op.lhs);
1496 const rhs_ty = self.air.typeOf(bin_op.rhs);1498 const rhs_ty = self.typeOf(bin_op.rhs);
14971499
1498 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1500 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1499 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };1501 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
...@@ -1512,9 +1514,9 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -1512,9 +1514,9 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
1512 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;1514 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
1513 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1515 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1514 const ptr = try self.resolveInst(bin_op.lhs);1516 const ptr = try self.resolveInst(bin_op.lhs);
1515 const ptr_ty = self.air.typeOf(bin_op.lhs);1517 const ptr_ty = self.typeOf(bin_op.lhs);
1516 const len = try self.resolveInst(bin_op.rhs);1518 const len = try self.resolveInst(bin_op.rhs);
1517 const len_ty = self.air.typeOf(bin_op.rhs);1519 const len_ty = self.typeOf(bin_op.rhs);
15181520
1519 const ptr_bits = self.target.ptrBitWidth();1521 const ptr_bits = self.target.ptrBitWidth();
1520 const ptr_bytes = @divExact(ptr_bits, 8);1522 const ptr_bytes = @divExact(ptr_bits, 8);
...@@ -2436,8 +2438,8 @@ fn ptrArithmetic(...@@ -2436,8 +2438,8 @@ fn ptrArithmetic(
24362438
2437fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {2439fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
2438 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2440 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2439 const lhs_ty = self.air.typeOf(bin_op.lhs);2441 const lhs_ty = self.typeOf(bin_op.lhs);
2440 const rhs_ty = self.air.typeOf(bin_op.rhs);2442 const rhs_ty = self.typeOf(bin_op.rhs);
24412443
2442 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2444 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2443 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };2445 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
...@@ -2487,8 +2489,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {...@@ -2487,8 +2489,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
2487fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {2489fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
2488 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2490 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2489 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;2491 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
2490 const lhs_ty = self.air.typeOf(bin_op.lhs);2492 const lhs_ty = self.typeOf(bin_op.lhs);
2491 const rhs_ty = self.air.typeOf(bin_op.rhs);2493 const rhs_ty = self.typeOf(bin_op.rhs);
24922494
2493 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2495 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2494 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };2496 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
...@@ -2525,10 +2527,10 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2525,10 +2527,10 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
2525 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2527 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2526 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };2528 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2527 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };2529 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
2528 const lhs_ty = self.air.typeOf(extra.lhs);2530 const lhs_ty = self.typeOf(extra.lhs);
2529 const rhs_ty = self.air.typeOf(extra.rhs);2531 const rhs_ty = self.typeOf(extra.rhs);
25302532
2531 const tuple_ty = self.air.typeOfIndex(inst);2533 const tuple_ty = self.typeOfIndex(inst);
2532 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));2534 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
2533 const tuple_align = tuple_ty.abiAlignment(mod);2535 const tuple_align = tuple_ty.abiAlignment(mod);
2534 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));2536 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
...@@ -2653,10 +2655,10 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2653,10 +2655,10 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2653 const result: MCValue = result: {2655 const result: MCValue = result: {
2654 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };2656 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2655 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };2657 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
2656 const lhs_ty = self.air.typeOf(extra.lhs);2658 const lhs_ty = self.typeOf(extra.lhs);
2657 const rhs_ty = self.air.typeOf(extra.rhs);2659 const rhs_ty = self.typeOf(extra.rhs);
26582660
2659 const tuple_ty = self.air.typeOfIndex(inst);2661 const tuple_ty = self.typeOfIndex(inst);
2660 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));2662 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
2661 const tuple_align = tuple_ty.abiAlignment(mod);2663 const tuple_align = tuple_ty.abiAlignment(mod);
2662 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));2664 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
...@@ -2877,10 +2879,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2877,10 +2879,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2877 const result: MCValue = result: {2879 const result: MCValue = result: {
2878 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };2880 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2879 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };2881 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
2880 const lhs_ty = self.air.typeOf(extra.lhs);2882 const lhs_ty = self.typeOf(extra.lhs);
2881 const rhs_ty = self.air.typeOf(extra.rhs);2883 const rhs_ty = self.typeOf(extra.rhs);
28822884
2883 const tuple_ty = self.air.typeOfIndex(inst);2885 const tuple_ty = self.typeOfIndex(inst);
2884 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));2886 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
2885 const tuple_align = tuple_ty.abiAlignment(mod);2887 const tuple_align = tuple_ty.abiAlignment(mod);
2886 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));2888 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
...@@ -3013,7 +3015,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3013,7 +3015,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
3013fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {3015fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
3014 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3016 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3015 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3017 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3016 const optional_ty = self.air.typeOf(ty_op.operand);3018 const optional_ty = self.typeOf(ty_op.operand);
3017 const mcv = try self.resolveInst(ty_op.operand);3019 const mcv = try self.resolveInst(ty_op.operand);
3018 break :result try self.optionalPayload(inst, mcv, optional_ty);3020 break :result try self.optionalPayload(inst, mcv, optional_ty);
3019 };3021 };
...@@ -3132,7 +3134,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3132,7 +3134,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
3132 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3134 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3133 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3135 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3134 const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };3136 const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
3135 const error_union_ty = self.air.typeOf(ty_op.operand);3137 const error_union_ty = self.typeOf(ty_op.operand);
31363138
3137 break :result try self.errUnionErr(error_union_bind, error_union_ty, inst);3139 break :result try self.errUnionErr(error_union_bind, error_union_ty, inst);
3138 };3140 };
...@@ -3212,7 +3214,7 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -3212,7 +3214,7 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
3212 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3214 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3213 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3215 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3214 const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };3216 const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
3215 const error_union_ty = self.air.typeOf(ty_op.operand);3217 const error_union_ty = self.typeOf(ty_op.operand);
32163218
3217 break :result try self.errUnionPayload(error_union_bind, error_union_ty, inst);3219 break :result try self.errUnionPayload(error_union_bind, error_union_ty, inst);
3218 };3220 };
...@@ -3266,12 +3268,12 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3266,12 +3268,12 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3266 }3268 }
32673269
3268 const result: MCValue = result: {3270 const result: MCValue = result: {
3269 const payload_ty = self.air.typeOf(ty_op.operand);3271 const payload_ty = self.typeOf(ty_op.operand);
3270 if (!payload_ty.hasRuntimeBits(mod)) {3272 if (!payload_ty.hasRuntimeBits(mod)) {
3271 break :result MCValue{ .immediate = 1 };3273 break :result MCValue{ .immediate = 1 };
3272 }3274 }
32733275
3274 const optional_ty = self.air.typeOfIndex(inst);3276 const optional_ty = self.typeOfIndex(inst);
3275 const operand = try self.resolveInst(ty_op.operand);3277 const operand = try self.resolveInst(ty_op.operand);
3276 const operand_lock: ?RegisterLock = switch (operand) {3278 const operand_lock: ?RegisterLock = switch (operand) {
3277 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),3279 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
...@@ -3433,7 +3435,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3433,7 +3435,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
34333435
3434fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {3436fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
3435 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3437 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3436 const slice_ty = self.air.typeOf(bin_op.lhs);3438 const slice_ty = self.typeOf(bin_op.lhs);
3437 const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {3439 const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
3438 var buf: Type.SlicePtrFieldTypeBuffer = undefined;3440 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3439 const ptr_ty = slice_ty.slicePtrFieldType(&buf);3441 const ptr_ty = slice_ty.slicePtrFieldType(&buf);
...@@ -3482,8 +3484,8 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3482,8 +3484,8 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
3482 const base_bind: ReadArg.Bind = .{ .mcv = base_mcv };3484 const base_bind: ReadArg.Bind = .{ .mcv = base_mcv };
3483 const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };3485 const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };
34843486
3485 const slice_ty = self.air.typeOf(extra.lhs);3487 const slice_ty = self.typeOf(extra.lhs);
3486 const index_ty = self.air.typeOf(extra.rhs);3488 const index_ty = self.typeOf(extra.rhs);
34873489
3488 const addr = try self.ptrArithmetic(.ptr_add, base_bind, index_bind, slice_ty, index_ty, null);3490 const addr = try self.ptrArithmetic(.ptr_add, base_bind, index_bind, slice_ty, index_ty, null);
3489 break :result addr;3491 break :result addr;
...@@ -3499,7 +3501,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -3499,7 +3501,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
34993501
3500fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {3502fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
3501 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3503 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3502 const ptr_ty = self.air.typeOf(bin_op.lhs);3504 const ptr_ty = self.typeOf(bin_op.lhs);
3503 const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {3505 const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
3504 const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };3506 const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
3505 const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };3507 const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
...@@ -3516,8 +3518,8 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3516,8 +3518,8 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
3516 const ptr_bind: ReadArg.Bind = .{ .inst = extra.lhs };3518 const ptr_bind: ReadArg.Bind = .{ .inst = extra.lhs };
3517 const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };3519 const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };
35183520
3519 const ptr_ty = self.air.typeOf(extra.lhs);3521 const ptr_ty = self.typeOf(extra.lhs);
3520 const index_ty = self.air.typeOf(extra.rhs);3522 const index_ty = self.typeOf(extra.rhs);
35213523
3522 const addr = try self.ptrArithmetic(.ptr_add, ptr_bind, index_bind, ptr_ty, index_ty, null);3524 const addr = try self.ptrArithmetic(.ptr_add, ptr_bind, index_bind, ptr_ty, index_ty, null);
3523 break :result addr;3525 break :result addr;
...@@ -3862,16 +3864,16 @@ fn genInlineMemsetCode(...@@ -3862,16 +3864,16 @@ fn genInlineMemsetCode(
3862}3864}
38633865
3864fn airLoad(self: *Self, inst: Air.Inst.Index) !void {3866fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
3865 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3866 const elem_ty = self.air.typeOfIndex(inst);
3867 const mod = self.bin_file.options.module.?;3867 const mod = self.bin_file.options.module.?;
3868 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3869 const elem_ty = self.typeOfIndex(inst);
3868 const elem_size = elem_ty.abiSize(mod);3870 const elem_size = elem_ty.abiSize(mod);
3869 const result: MCValue = result: {3871 const result: MCValue = result: {
3870 if (!elem_ty.hasRuntimeBits(mod))3872 if (!elem_ty.hasRuntimeBits(mod))
3871 break :result MCValue.none;3873 break :result MCValue.none;
38723874
3873 const ptr = try self.resolveInst(ty_op.operand);3875 const ptr = try self.resolveInst(ty_op.operand);
3874 const is_volatile = self.air.typeOf(ty_op.operand).isVolatilePtr();3876 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
3875 if (self.liveness.isUnused(inst) and !is_volatile)3877 if (self.liveness.isUnused(inst) and !is_volatile)
3876 break :result MCValue.dead;3878 break :result MCValue.dead;
38773879
...@@ -3886,7 +3888,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -3886,7 +3888,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
3886 break :blk try self.allocRegOrMem(elem_ty, true, inst);3888 break :blk try self.allocRegOrMem(elem_ty, true, inst);
3887 }3889 }
3888 };3890 };
3889 try self.load(dst_mcv, ptr, self.air.typeOf(ty_op.operand));3891 try self.load(dst_mcv, ptr, self.typeOf(ty_op.operand));
3890 break :result dst_mcv;3892 break :result dst_mcv;
3891 };3893 };
3892 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });3894 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
...@@ -4068,8 +4070,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -4068,8 +4070,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
4068 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4070 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4069 const ptr = try self.resolveInst(bin_op.lhs);4071 const ptr = try self.resolveInst(bin_op.lhs);
4070 const value = try self.resolveInst(bin_op.rhs);4072 const value = try self.resolveInst(bin_op.rhs);
4071 const ptr_ty = self.air.typeOf(bin_op.lhs);4073 const ptr_ty = self.typeOf(bin_op.lhs);
4072 const value_ty = self.air.typeOf(bin_op.rhs);4074 const value_ty = self.typeOf(bin_op.rhs);
40734075
4074 try self.store(ptr, value, ptr_ty, value_ty);4076 try self.store(ptr, value, ptr_ty, value_ty);
40754077
...@@ -4093,7 +4095,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -4093,7 +4095,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
4093 return if (self.liveness.isUnused(inst)) .dead else result: {4095 return if (self.liveness.isUnused(inst)) .dead else result: {
4094 const mod = self.bin_file.options.module.?;4096 const mod = self.bin_file.options.module.?;
4095 const mcv = try self.resolveInst(operand);4097 const mcv = try self.resolveInst(operand);
4096 const ptr_ty = self.air.typeOf(operand);4098 const ptr_ty = self.typeOf(operand);
4097 const struct_ty = ptr_ty.childType();4099 const struct_ty = ptr_ty.childType();
4098 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));4100 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
4099 switch (mcv) {4101 switch (mcv) {
...@@ -4118,7 +4120,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4118,7 +4120,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
4118 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4120 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4119 const mod = self.bin_file.options.module.?;4121 const mod = self.bin_file.options.module.?;
4120 const mcv = try self.resolveInst(operand);4122 const mcv = try self.resolveInst(operand);
4121 const struct_ty = self.air.typeOf(operand);4123 const struct_ty = self.typeOf(operand);
4122 const struct_field_ty = struct_ty.structFieldType(index);4124 const struct_field_ty = struct_ty.structFieldType(index);
4123 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));4125 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
41244126
...@@ -4194,7 +4196,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4194,7 +4196,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4194 while (self.args[arg_index] == .none) arg_index += 1;4196 while (self.args[arg_index] == .none) arg_index += 1;
4195 self.arg_index = arg_index + 1;4197 self.arg_index = arg_index + 1;
41964198
4197 const ty = self.air.typeOfIndex(inst);4199 const ty = self.typeOfIndex(inst);
4198 const tag = self.air.instructions.items(.tag)[inst];4200 const tag = self.air.instructions.items(.tag)[inst];
4199 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;4201 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
4200 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);4202 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
...@@ -4247,7 +4249,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4247,7 +4249,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4247 const callee = pl_op.operand;4249 const callee = pl_op.operand;
4248 const extra = self.air.extraData(Air.Call, pl_op.payload);4250 const extra = self.air.extraData(Air.Call, pl_op.payload);
4249 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);4251 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
4250 const ty = self.air.typeOf(callee);4252 const ty = self.typeOf(callee);
4251 const mod = self.bin_file.options.module.?;4253 const mod = self.bin_file.options.module.?;
42524254
4253 const fn_ty = switch (ty.zigTypeTag(mod)) {4255 const fn_ty = switch (ty.zigTypeTag(mod)) {
...@@ -4294,7 +4296,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4294,7 +4296,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42944296
4295 for (info.args, 0..) |mc_arg, arg_i| {4297 for (info.args, 0..) |mc_arg, arg_i| {
4296 const arg = args[arg_i];4298 const arg = args[arg_i];
4297 const arg_ty = self.air.typeOf(arg);4299 const arg_ty = self.typeOf(arg);
4298 const arg_mcv = try self.resolveInst(args[arg_i]);4300 const arg_mcv = try self.resolveInst(args[arg_i]);
42994301
4300 switch (mc_arg) {4302 switch (mc_arg) {
...@@ -4470,7 +4472,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -4470,7 +4472,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4470fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {4472fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4471 const un_op = self.air.instructions.items(.data)[inst].un_op;4473 const un_op = self.air.instructions.items(.data)[inst].un_op;
4472 const ptr = try self.resolveInst(un_op);4474 const ptr = try self.resolveInst(un_op);
4473 const ptr_ty = self.air.typeOf(un_op);4475 const ptr_ty = self.typeOf(un_op);
4474 const ret_ty = self.fn_type.fnReturnType();4476 const ret_ty = self.fn_type.fnReturnType();
44754477
4476 switch (self.ret_mcv) {4478 switch (self.ret_mcv) {
...@@ -4512,7 +4514,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -4512,7 +4514,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
45124514
4513fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {4515fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
4514 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4516 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4515 const lhs_ty = self.air.typeOf(bin_op.lhs);4517 const lhs_ty = self.typeOf(bin_op.lhs);
45164518
4517 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {4519 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
4518 break :blk try self.cmp(.{ .inst = bin_op.lhs }, .{ .inst = bin_op.rhs }, lhs_ty, op);4520 break :blk try self.cmp(.{ .inst = bin_op.lhs }, .{ .inst = bin_op.rhs }, lhs_ty, op);
...@@ -4652,7 +4654,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {...@@ -4652,7 +4654,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
4652 const pl_op = self.air.instructions.items(.data)[inst].pl_op;4654 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
4653 const operand = pl_op.operand;4655 const operand = pl_op.operand;
4654 const tag = self.air.instructions.items(.tag)[inst];4656 const tag = self.air.instructions.items(.tag)[inst];
4655 const ty = self.air.typeOf(operand);4657 const ty = self.typeOf(operand);
4656 const mcv = try self.resolveInst(operand);4658 const mcv = try self.resolveInst(operand);
4657 const name = self.air.nullTerminatedString(pl_op.payload);4659 const name = self.air.nullTerminatedString(pl_op.payload);
46584660
...@@ -4804,7 +4806,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4804,7 +4806,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
4804 log.debug("consolidating else_entry {d} {}=>{}", .{ else_key, else_value, canon_mcv });4806 log.debug("consolidating else_entry {d} {}=>{}", .{ else_key, else_value, canon_mcv });
4805 // TODO make sure the destination stack offset / register does not already have something4807 // TODO make sure the destination stack offset / register does not already have something
4806 // going on there.4808 // going on there.
4807 try self.setRegOrMem(self.air.typeOfIndex(else_key), canon_mcv, else_value);4809 try self.setRegOrMem(self.typeOfIndex(else_key), canon_mcv, else_value);
4808 // TODO track the new register / stack allocation4810 // TODO track the new register / stack allocation
4809 }4811 }
4810 try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, saved_then_branch.inst_table.count());4812 try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, saved_then_branch.inst_table.count());
...@@ -4831,7 +4833,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4831,7 +4833,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
4831 log.debug("consolidating then_entry {d} {}=>{}", .{ then_key, parent_mcv, then_value });4833 log.debug("consolidating then_entry {d} {}=>{}", .{ then_key, parent_mcv, then_value });
4832 // TODO make sure the destination stack offset / register does not already have something4834 // TODO make sure the destination stack offset / register does not already have something
4833 // going on there.4835 // going on there.
4834 try self.setRegOrMem(self.air.typeOfIndex(then_key), parent_mcv, then_value);4836 try self.setRegOrMem(self.typeOfIndex(then_key), parent_mcv, then_value);
4835 // TODO track the new register / stack allocation4837 // TODO track the new register / stack allocation
4836 }4838 }
48374839
...@@ -4936,7 +4938,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -4936,7 +4938,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
4936 const un_op = self.air.instructions.items(.data)[inst].un_op;4938 const un_op = self.air.instructions.items(.data)[inst].un_op;
4937 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4939 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4938 const operand = try self.resolveInst(un_op);4940 const operand = try self.resolveInst(un_op);
4939 const operand_ty = self.air.typeOf(un_op);4941 const operand_ty = self.typeOf(un_op);
49404942
4941 break :result try self.isNull(.{ .mcv = operand }, operand_ty);4943 break :result try self.isNull(.{ .mcv = operand }, operand_ty);
4942 };4944 };
...@@ -4947,7 +4949,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4947,7 +4949,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4947 const un_op = self.air.instructions.items(.data)[inst].un_op;4949 const un_op = self.air.instructions.items(.data)[inst].un_op;
4948 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4950 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4949 const operand_ptr = try self.resolveInst(un_op);4951 const operand_ptr = try self.resolveInst(un_op);
4950 const ptr_ty = self.air.typeOf(un_op);4952 const ptr_ty = self.typeOf(un_op);
4951 const elem_ty = ptr_ty.elemType();4953 const elem_ty = ptr_ty.elemType();
49524954
4953 const operand = try self.allocRegOrMem(elem_ty, true, null);4955 const operand = try self.allocRegOrMem(elem_ty, true, null);
...@@ -4962,7 +4964,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -4962,7 +4964,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
4962 const un_op = self.air.instructions.items(.data)[inst].un_op;4964 const un_op = self.air.instructions.items(.data)[inst].un_op;
4963 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4965 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4964 const operand = try self.resolveInst(un_op);4966 const operand = try self.resolveInst(un_op);
4965 const operand_ty = self.air.typeOf(un_op);4967 const operand_ty = self.typeOf(un_op);
49664968
4967 break :result try self.isNonNull(.{ .mcv = operand }, operand_ty);4969 break :result try self.isNonNull(.{ .mcv = operand }, operand_ty);
4968 };4970 };
...@@ -4973,7 +4975,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4973,7 +4975,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4973 const un_op = self.air.instructions.items(.data)[inst].un_op;4975 const un_op = self.air.instructions.items(.data)[inst].un_op;
4974 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4976 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4975 const operand_ptr = try self.resolveInst(un_op);4977 const operand_ptr = try self.resolveInst(un_op);
4976 const ptr_ty = self.air.typeOf(un_op);4978 const ptr_ty = self.typeOf(un_op);
4977 const elem_ty = ptr_ty.elemType();4979 const elem_ty = ptr_ty.elemType();
49784980
4979 const operand = try self.allocRegOrMem(elem_ty, true, null);4981 const operand = try self.allocRegOrMem(elem_ty, true, null);
...@@ -4988,7 +4990,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4988,7 +4990,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
4988 const un_op = self.air.instructions.items(.data)[inst].un_op;4990 const un_op = self.air.instructions.items(.data)[inst].un_op;
4989 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4991 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4990 const error_union_bind: ReadArg.Bind = .{ .inst = un_op };4992 const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
4991 const error_union_ty = self.air.typeOf(un_op);4993 const error_union_ty = self.typeOf(un_op);
49924994
4993 break :result try self.isErr(error_union_bind, error_union_ty);4995 break :result try self.isErr(error_union_bind, error_union_ty);
4994 };4996 };
...@@ -4999,7 +5001,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4999,7 +5001,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4999 const un_op = self.air.instructions.items(.data)[inst].un_op;5001 const un_op = self.air.instructions.items(.data)[inst].un_op;
5000 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {5002 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
5001 const operand_ptr = try self.resolveInst(un_op);5003 const operand_ptr = try self.resolveInst(un_op);
5002 const ptr_ty = self.air.typeOf(un_op);5004 const ptr_ty = self.typeOf(un_op);
5003 const elem_ty = ptr_ty.elemType();5005 const elem_ty = ptr_ty.elemType();
50045006
5005 const operand = try self.allocRegOrMem(elem_ty, true, null);5007 const operand = try self.allocRegOrMem(elem_ty, true, null);
...@@ -5014,7 +5016,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5014,7 +5016,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
5014 const un_op = self.air.instructions.items(.data)[inst].un_op;5016 const un_op = self.air.instructions.items(.data)[inst].un_op;
5015 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {5017 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
5016 const error_union_bind: ReadArg.Bind = .{ .inst = un_op };5018 const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
5017 const error_union_ty = self.air.typeOf(un_op);5019 const error_union_ty = self.typeOf(un_op);
50185020
5019 break :result try self.isNonErr(error_union_bind, error_union_ty);5021 break :result try self.isNonErr(error_union_bind, error_union_ty);
5020 };5022 };
...@@ -5025,7 +5027,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5025,7 +5027,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
5025 const un_op = self.air.instructions.items(.data)[inst].un_op;5027 const un_op = self.air.instructions.items(.data)[inst].un_op;
5026 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {5028 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
5027 const operand_ptr = try self.resolveInst(un_op);5029 const operand_ptr = try self.resolveInst(un_op);
5028 const ptr_ty = self.air.typeOf(un_op);5030 const ptr_ty = self.typeOf(un_op);
5029 const elem_ty = ptr_ty.elemType();5031 const elem_ty = ptr_ty.elemType();
50305032
5031 const operand = try self.allocRegOrMem(elem_ty, true, null);5033 const operand = try self.allocRegOrMem(elem_ty, true, null);
...@@ -5093,7 +5095,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -5093,7 +5095,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
50935095
5094fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {5096fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
5095 const pl_op = self.air.instructions.items(.data)[inst].pl_op;5097 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
5096 const condition_ty = self.air.typeOf(pl_op.operand);5098 const condition_ty = self.typeOf(pl_op.operand);
5097 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);5099 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
5098 const liveness = try self.liveness.getSwitchBr(5100 const liveness = try self.liveness.getSwitchBr(
5099 self.gpa,5101 self.gpa,
...@@ -5241,7 +5243,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {...@@ -5241,7 +5243,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5241 const mod = self.bin_file.options.module.?;5243 const mod = self.bin_file.options.module.?;
5242 const block_data = self.blocks.getPtr(block).?;5244 const block_data = self.blocks.getPtr(block).?;
52435245
5244 if (self.air.typeOf(operand).hasRuntimeBits(mod)) {5246 if (self.typeOf(operand).hasRuntimeBits(mod)) {
5245 const operand_mcv = try self.resolveInst(operand);5247 const operand_mcv = try self.resolveInst(operand);
5246 const block_mcv = block_data.mcv;5248 const block_mcv = block_data.mcv;
5247 if (block_mcv == .none) {5249 if (block_mcv == .none) {
...@@ -5249,14 +5251,14 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {...@@ -5249,14 +5251,14 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5249 .none, .dead, .unreach => unreachable,5251 .none, .dead, .unreach => unreachable,
5250 .register, .stack_offset, .memory => operand_mcv,5252 .register, .stack_offset, .memory => operand_mcv,
5251 .immediate, .stack_argument_offset, .compare_flags => blk: {5253 .immediate, .stack_argument_offset, .compare_flags => blk: {
5252 const new_mcv = try self.allocRegOrMem(self.air.typeOfIndex(block), true, block);5254 const new_mcv = try self.allocRegOrMem(self.typeOfIndex(block), true, block);
5253 try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv);5255 try self.setRegOrMem(self.typeOfIndex(block), new_mcv, operand_mcv);
5254 break :blk new_mcv;5256 break :blk new_mcv;
5255 },5257 },
5256 else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),5258 else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),
5257 };5259 };
5258 } else {5260 } else {
5259 try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv);5261 try self.setRegOrMem(self.typeOfIndex(block), block_mcv, operand_mcv);
5260 }5262 }
5261 }5263 }
5262 return self.brVoid(block);5264 return self.brVoid(block);
...@@ -5322,7 +5324,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -5322,7 +5324,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
53225324
5323 const arg_mcv = try self.resolveInst(input);5325 const arg_mcv = try self.resolveInst(input);
5324 try self.register_manager.getReg(reg, null);5326 try self.register_manager.getReg(reg, null);
5325 try self.genSetReg(self.air.typeOf(input), reg, arg_mcv);5327 try self.genSetReg(self.typeOf(input), reg, arg_mcv);
5326 }5328 }
53275329
5328 {5330 {
...@@ -5945,7 +5947,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -5945,7 +5947,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
5945 };5947 };
5946 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);5948 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
59475949
5948 const dest_ty = self.air.typeOfIndex(inst);5950 const dest_ty = self.typeOfIndex(inst);
5949 const dest = try self.allocRegOrMem(dest_ty, true, inst);5951 const dest = try self.allocRegOrMem(dest_ty, true, inst);
5950 try self.setRegOrMem(dest_ty, dest, operand);5952 try self.setRegOrMem(dest_ty, dest, operand);
5951 break :result dest;5953 break :result dest;
...@@ -5956,7 +5958,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -5956,7 +5958,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
5956fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {5958fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
5957 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5959 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5958 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {5960 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
5959 const ptr_ty = self.air.typeOf(ty_op.operand);5961 const ptr_ty = self.typeOf(ty_op.operand);
5960 const ptr = try self.resolveInst(ty_op.operand);5962 const ptr = try self.resolveInst(ty_op.operand);
5961 const array_ty = ptr_ty.childType();5963 const array_ty = ptr_ty.childType();
5962 const array_len = @intCast(u32, array_ty.arrayLen());5964 const array_len = @intCast(u32, array_ty.arrayLen());
...@@ -6076,7 +6078,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {...@@ -6076,7 +6078,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
6076}6078}
60776079
6078fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {6080fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
6079 const vector_ty = self.air.typeOfIndex(inst);6081 const vector_ty = self.typeOfIndex(inst);
6080 const len = vector_ty.vectorLen();6082 const len = vector_ty.vectorLen();
6081 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6083 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
6082 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);6084 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
...@@ -6125,7 +6127,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {...@@ -6125,7 +6127,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
6125 const body = self.air.extra[extra.end..][0..extra.data.body_len];6127 const body = self.air.extra[extra.end..][0..extra.data.body_len];
6126 const result: MCValue = result: {6128 const result: MCValue = result: {
6127 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };6129 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
6128 const error_union_ty = self.air.typeOf(pl_op.operand);6130 const error_union_ty = self.typeOf(pl_op.operand);
6129 const error_union_size = @intCast(u32, error_union_ty.abiSize(mod));6131 const error_union_size = @intCast(u32, error_union_ty.abiSize(mod));
6130 const error_union_align = error_union_ty.abiAlignment(mod);6132 const error_union_align = error_union_ty.abiAlignment(mod);
61316133
...@@ -6159,7 +6161,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {...@@ -6159,7 +6161,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
6159 const mod = self.bin_file.options.module.?;6161 const mod = self.bin_file.options.module.?;
61606162
6161 // If the type has no codegen bits, no need to store it.6163 // If the type has no codegen bits, no need to store it.
6162 const inst_ty = self.air.typeOf(inst);6164 const inst_ty = self.typeOf(inst);
6163 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))6165 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))
6164 return MCValue{ .none = {} };6166 return MCValue{ .none = {} };
61656167
...@@ -6428,3 +6430,13 @@ fn registerAlias(self: *Self, reg: Register, ty: Type) Register {...@@ -6428,3 +6430,13 @@ fn registerAlias(self: *Self, reg: Register, ty: Type) Register {
6428 },6430 },
6429 }6431 }
6430}6432}
6433
6434fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
6435 const mod = self.bin_file.options.module.?;
6436 return self.air.typeOf(inst, mod.intern_pool);
6437}
6438
6439fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
6440 const mod = self.bin_file.options.module.?;
6441 return self.air.typeOfIndex(inst, mod.intern_pool);
6442}
src/arch/arm/CodeGen.zig+89-77
...@@ -477,6 +477,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {...@@ -477,6 +477,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
477}477}
478478
479fn gen(self: *Self) !void {479fn gen(self: *Self) !void {
480 const mod = self.bin_file.options.module.?;
480 const cc = self.fn_type.fnCallingConvention();481 const cc = self.fn_type.fnCallingConvention();
481 if (cc != .Naked) {482 if (cc != .Naked) {
482 // push {fp, lr}483 // push {fp, lr}
...@@ -518,9 +519,8 @@ fn gen(self: *Self) !void {...@@ -518,9 +519,8 @@ fn gen(self: *Self) !void {
518 const inst = self.air.getMainBody()[arg_index];519 const inst = self.air.getMainBody()[arg_index];
519 assert(self.air.instructions.items(.tag)[inst] == .arg);520 assert(self.air.instructions.items(.tag)[inst] == .arg);
520521
521 const ty = self.air.typeOfIndex(inst);522 const ty = self.typeOfIndex(inst);
522523
523 const mod = self.bin_file.options.module.?;
524 const abi_size = @intCast(u32, ty.abiSize(mod));524 const abi_size = @intCast(u32, ty.abiSize(mod));
525 const abi_align = ty.abiAlignment(mod);525 const abi_align = ty.abiAlignment(mod);
526 const stack_offset = try self.allocMem(abi_size, abi_align, inst);526 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
...@@ -637,13 +637,14 @@ fn gen(self: *Self) !void {...@@ -637,13 +637,14 @@ fn gen(self: *Self) !void {
637}637}
638638
639fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {639fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
640 const mod = self.bin_file.options.module.?;
641 const ip = &mod.intern_pool;
640 const air_tags = self.air.instructions.items(.tag);642 const air_tags = self.air.instructions.items(.tag);
641643
642 for (body) |inst| {644 for (body) |inst| {
643 // TODO: remove now-redundant isUnused calls from AIR handler functions645 // TODO: remove now-redundant isUnused calls from AIR handler functions
644 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {646 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
645 continue;647 continue;
646 }
647648
648 const old_air_bookkeeping = self.air_bookkeeping;649 const old_air_bookkeeping = self.air_bookkeeping;
649 try self.ensureProcessDeathCapacity(Liveness.bpi);650 try self.ensureProcessDeathCapacity(Liveness.bpi);
...@@ -829,6 +830,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -829,6 +830,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
829830
830 .constant => unreachable, // excluded from function bodies831 .constant => unreachable, // excluded from function bodies
831 .const_ty => unreachable, // excluded from function bodies832 .const_ty => unreachable, // excluded from function bodies
833 .interned => unreachable, // excluded from function bodies
832 .unreach => self.finishAirBookkeeping(),834 .unreach => self.finishAirBookkeeping(),
833835
834 .optional_payload => try self.airOptionalPayload(inst),836 .optional_payload => try self.airOptionalPayload(inst),
...@@ -1008,7 +1010,7 @@ fn allocMem(...@@ -1008,7 +1010,7 @@ fn allocMem(
1008/// Use a pointer instruction as the basis for allocating stack memory.1010/// Use a pointer instruction as the basis for allocating stack memory.
1009fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {1011fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1010 const mod = self.bin_file.options.module.?;1012 const mod = self.bin_file.options.module.?;
1011 const elem_ty = self.air.typeOfIndex(inst).elemType();1013 const elem_ty = self.typeOfIndex(inst).elemType();
10121014
1013 if (!elem_ty.hasRuntimeBits(mod)) {1015 if (!elem_ty.hasRuntimeBits(mod)) {
1014 // As this stack item will never be dereferenced at runtime,1016 // As this stack item will never be dereferenced at runtime,
...@@ -1050,7 +1052,7 @@ fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst...@@ -1050,7 +1052,7 @@ fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst
1050}1052}
10511053
1052pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {1054pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {
1053 const stack_mcv = try self.allocRegOrMem(self.air.typeOfIndex(inst), false, inst);1055 const stack_mcv = try self.allocRegOrMem(self.typeOfIndex(inst), false, inst);
1054 log.debug("spilling {} (%{d}) to stack mcv {any}", .{ reg, inst, stack_mcv });1056 log.debug("spilling {} (%{d}) to stack mcv {any}", .{ reg, inst, stack_mcv });
10551057
1056 const reg_mcv = self.getResolvedInstValue(inst);1058 const reg_mcv = self.getResolvedInstValue(inst);
...@@ -1064,14 +1066,14 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void...@@ -1064,14 +1066,14 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
10641066
1065 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];1067 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
1066 try branch.inst_table.put(self.gpa, inst, stack_mcv);1068 try branch.inst_table.put(self.gpa, inst, stack_mcv);
1067 try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);1069 try self.genSetStack(self.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
1068}1070}
10691071
1070/// Save the current instruction stored in the compare flags if1072/// Save the current instruction stored in the compare flags if
1071/// occupied1073/// occupied
1072fn spillCompareFlagsIfOccupied(self: *Self) !void {1074fn spillCompareFlagsIfOccupied(self: *Self) !void {
1073 if (self.cpsr_flags_inst) |inst_to_save| {1075 if (self.cpsr_flags_inst) |inst_to_save| {
1074 const ty = self.air.typeOfIndex(inst_to_save);1076 const ty = self.typeOfIndex(inst_to_save);
1075 const mcv = self.getResolvedInstValue(inst_to_save);1077 const mcv = self.getResolvedInstValue(inst_to_save);
1076 const new_mcv = switch (mcv) {1078 const new_mcv = switch (mcv) {
1077 .cpsr_flags => try self.allocRegOrMem(ty, true, inst_to_save),1079 .cpsr_flags => try self.allocRegOrMem(ty, true, inst_to_save),
...@@ -1081,7 +1083,7 @@ fn spillCompareFlagsIfOccupied(self: *Self) !void {...@@ -1081,7 +1083,7 @@ fn spillCompareFlagsIfOccupied(self: *Self) !void {
1081 else => unreachable, // mcv doesn't occupy the compare flags1083 else => unreachable, // mcv doesn't occupy the compare flags
1082 };1084 };
10831085
1084 try self.setRegOrMem(self.air.typeOfIndex(inst_to_save), new_mcv, mcv);1086 try self.setRegOrMem(self.typeOfIndex(inst_to_save), new_mcv, mcv);
1085 log.debug("spilling {d} to mcv {any}", .{ inst_to_save, new_mcv });1087 log.debug("spilling {d} to mcv {any}", .{ inst_to_save, new_mcv });
10861088
1087 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];1089 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
...@@ -1151,15 +1153,15 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {...@@ -1151,15 +1153,15 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
1151}1153}
11521154
1153fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {1155fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1156 const mod = self.bin_file.options.module.?;
1154 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1157 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1155 if (self.liveness.isUnused(inst))1158 if (self.liveness.isUnused(inst))
1156 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });1159 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
11571160
1158 const operand = try self.resolveInst(ty_op.operand);1161 const operand = try self.resolveInst(ty_op.operand);
1159 const operand_ty = self.air.typeOf(ty_op.operand);1162 const operand_ty = self.typeOf(ty_op.operand);
1160 const dest_ty = self.air.typeOfIndex(inst);1163 const dest_ty = self.typeOfIndex(inst);
11611164
1162 const mod = self.bin_file.options.module.?;
1163 const operand_abi_size = operand_ty.abiSize(mod);1165 const operand_abi_size = operand_ty.abiSize(mod);
1164 const dest_abi_size = dest_ty.abiSize(mod);1166 const dest_abi_size = dest_ty.abiSize(mod);
1165 const info_a = operand_ty.intInfo(mod);1167 const info_a = operand_ty.intInfo(mod);
...@@ -1262,8 +1264,8 @@ fn trunc(...@@ -1262,8 +1264,8 @@ fn trunc(
1262fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {1264fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
1263 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1265 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1264 const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };1266 const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
1265 const operand_ty = self.air.typeOf(ty_op.operand);1267 const operand_ty = self.typeOf(ty_op.operand);
1266 const dest_ty = self.air.typeOfIndex(inst);1268 const dest_ty = self.typeOfIndex(inst);
12671269
1268 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {1270 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
1269 break :blk try self.trunc(inst, operand_bind, operand_ty, dest_ty);1271 break :blk try self.trunc(inst, operand_bind, operand_ty, dest_ty);
...@@ -1284,7 +1286,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -1284,7 +1286,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1284 const mod = self.bin_file.options.module.?;1286 const mod = self.bin_file.options.module.?;
1285 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1287 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1286 const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };1288 const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
1287 const operand_ty = self.air.typeOf(ty_op.operand);1289 const operand_ty = self.typeOf(ty_op.operand);
1288 switch (try operand_bind.resolveToMcv(self)) {1290 switch (try operand_bind.resolveToMcv(self)) {
1289 .dead => unreachable,1291 .dead => unreachable,
1290 .unreach => unreachable,1292 .unreach => unreachable,
...@@ -1467,8 +1469,8 @@ fn minMax(...@@ -1467,8 +1469,8 @@ fn minMax(
1467fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {1469fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {
1468 const tag = self.air.instructions.items(.tag)[inst];1470 const tag = self.air.instructions.items(.tag)[inst];
1469 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1471 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1470 const lhs_ty = self.air.typeOf(bin_op.lhs);1472 const lhs_ty = self.typeOf(bin_op.lhs);
1471 const rhs_ty = self.air.typeOf(bin_op.rhs);1473 const rhs_ty = self.typeOf(bin_op.rhs);
14721474
1473 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1475 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1474 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };1476 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
...@@ -1487,9 +1489,9 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -1487,9 +1489,9 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
1487 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;1489 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
1488 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1490 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1489 const ptr = try self.resolveInst(bin_op.lhs);1491 const ptr = try self.resolveInst(bin_op.lhs);
1490 const ptr_ty = self.air.typeOf(bin_op.lhs);1492 const ptr_ty = self.typeOf(bin_op.lhs);
1491 const len = try self.resolveInst(bin_op.rhs);1493 const len = try self.resolveInst(bin_op.rhs);
1492 const len_ty = self.air.typeOf(bin_op.rhs);1494 const len_ty = self.typeOf(bin_op.rhs);
14931495
1494 const stack_offset = try self.allocMem(8, 4, inst);1496 const stack_offset = try self.allocMem(8, 4, inst);
1495 try self.genSetStack(ptr_ty, stack_offset, ptr);1497 try self.genSetStack(ptr_ty, stack_offset, ptr);
...@@ -1501,8 +1503,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -1501,8 +1503,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
15011503
1502fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {1504fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
1503 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1505 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1504 const lhs_ty = self.air.typeOf(bin_op.lhs);1506 const lhs_ty = self.typeOf(bin_op.lhs);
1505 const rhs_ty = self.air.typeOf(bin_op.rhs);1507 const rhs_ty = self.typeOf(bin_op.rhs);
15061508
1507 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1509 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1508 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };1510 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
...@@ -1552,8 +1554,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {...@@ -1552,8 +1554,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
1552fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {1554fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
1553 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;1555 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1554 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;1556 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
1555 const lhs_ty = self.air.typeOf(bin_op.lhs);1557 const lhs_ty = self.typeOf(bin_op.lhs);
1556 const rhs_ty = self.air.typeOf(bin_op.rhs);1558 const rhs_ty = self.typeOf(bin_op.rhs);
15571559
1558 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1560 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1559 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };1561 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
...@@ -1590,10 +1592,10 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1590,10 +1592,10 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
1590 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1592 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1591 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };1593 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
1592 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };1594 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
1593 const lhs_ty = self.air.typeOf(extra.lhs);1595 const lhs_ty = self.typeOf(extra.lhs);
1594 const rhs_ty = self.air.typeOf(extra.rhs);1596 const rhs_ty = self.typeOf(extra.rhs);
15951597
1596 const tuple_ty = self.air.typeOfIndex(inst);1598 const tuple_ty = self.typeOfIndex(inst);
1597 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));1599 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
1598 const tuple_align = tuple_ty.abiAlignment(mod);1600 const tuple_align = tuple_ty.abiAlignment(mod);
1599 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));1601 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
...@@ -1703,10 +1705,10 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1703,10 +1705,10 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1703 const result: MCValue = result: {1705 const result: MCValue = result: {
1704 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };1706 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
1705 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };1707 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
1706 const lhs_ty = self.air.typeOf(extra.lhs);1708 const lhs_ty = self.typeOf(extra.lhs);
1707 const rhs_ty = self.air.typeOf(extra.rhs);1709 const rhs_ty = self.typeOf(extra.rhs);
17081710
1709 const tuple_ty = self.air.typeOfIndex(inst);1711 const tuple_ty = self.typeOfIndex(inst);
1710 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));1712 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
1711 const tuple_align = tuple_ty.abiAlignment(mod);1713 const tuple_align = tuple_ty.abiAlignment(mod);
1712 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));1714 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
...@@ -1865,10 +1867,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1865,10 +1867,10 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1865 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });1867 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
1866 const mod = self.bin_file.options.module.?;1868 const mod = self.bin_file.options.module.?;
1867 const result: MCValue = result: {1869 const result: MCValue = result: {
1868 const lhs_ty = self.air.typeOf(extra.lhs);1870 const lhs_ty = self.typeOf(extra.lhs);
1869 const rhs_ty = self.air.typeOf(extra.rhs);1871 const rhs_ty = self.typeOf(extra.rhs);
18701872
1871 const tuple_ty = self.air.typeOfIndex(inst);1873 const tuple_ty = self.typeOfIndex(inst);
1872 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));1874 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
1873 const tuple_align = tuple_ty.abiAlignment(mod);1875 const tuple_align = tuple_ty.abiAlignment(mod);
1874 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));1876 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
...@@ -2019,10 +2021,10 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -2019,10 +2021,10 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
2019}2021}
20202022
2021fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {2023fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
2024 const mod = self.bin_file.options.module.?;
2022 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2025 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2023 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2026 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2024 const optional_ty = self.air.typeOfIndex(inst);2027 const optional_ty = self.typeOfIndex(inst);
2025 const mod = self.bin_file.options.module.?;
2026 const abi_size = @intCast(u32, optional_ty.abiSize(mod));2028 const abi_size = @intCast(u32, optional_ty.abiSize(mod));
20272029
2028 // Optional with a zero-bit payload type is just a boolean true2030 // Optional with a zero-bit payload type is just a boolean true
...@@ -2105,7 +2107,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2105,7 +2107,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2105 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2107 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2106 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2108 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2107 const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };2109 const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
2108 const error_union_ty = self.air.typeOf(ty_op.operand);2110 const error_union_ty = self.typeOf(ty_op.operand);
21092111
2110 break :result try self.errUnionErr(error_union_bind, error_union_ty, inst);2112 break :result try self.errUnionErr(error_union_bind, error_union_ty, inst);
2111 };2113 };
...@@ -2182,7 +2184,7 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -2182,7 +2184,7 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
2182 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2184 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2183 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2185 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2184 const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };2186 const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
2185 const error_union_ty = self.air.typeOf(ty_op.operand);2187 const error_union_ty = self.typeOf(ty_op.operand);
21862188
2187 break :result try self.errUnionPayload(error_union_bind, error_union_ty, inst);2189 break :result try self.errUnionPayload(error_union_bind, error_union_ty, inst);
2188 };2190 };
...@@ -2430,7 +2432,7 @@ fn ptrElemVal(...@@ -2430,7 +2432,7 @@ fn ptrElemVal(
24302432
2431fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {2433fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2432 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2434 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2433 const slice_ty = self.air.typeOf(bin_op.lhs);2435 const slice_ty = self.typeOf(bin_op.lhs);
2434 const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {2436 const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
2435 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2437 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
2436 const ptr_ty = slice_ty.slicePtrFieldType(&buf);2438 const ptr_ty = slice_ty.slicePtrFieldType(&buf);
...@@ -2456,8 +2458,8 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2456,8 +2458,8 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
2456 const base_bind: ReadArg.Bind = .{ .mcv = base_mcv };2458 const base_bind: ReadArg.Bind = .{ .mcv = base_mcv };
2457 const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };2459 const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };
24582460
2459 const slice_ty = self.air.typeOf(extra.lhs);2461 const slice_ty = self.typeOf(extra.lhs);
2460 const index_ty = self.air.typeOf(extra.rhs);2462 const index_ty = self.typeOf(extra.rhs);
24612463
2462 const addr = try self.ptrArithmetic(.ptr_add, base_bind, index_bind, slice_ty, index_ty, null);2464 const addr = try self.ptrArithmetic(.ptr_add, base_bind, index_bind, slice_ty, index_ty, null);
2463 break :result addr;2465 break :result addr;
...@@ -2523,7 +2525,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2523,7 +2525,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
2523 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2525 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2524 const array_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };2526 const array_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
2525 const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };2527 const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
2526 const array_ty = self.air.typeOf(bin_op.lhs);2528 const array_ty = self.typeOf(bin_op.lhs);
25272529
2528 break :result try self.arrayElemVal(array_bind, index_bind, array_ty, inst);2530 break :result try self.arrayElemVal(array_bind, index_bind, array_ty, inst);
2529 };2531 };
...@@ -2532,7 +2534,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2532,7 +2534,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
25322534
2533fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {2535fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
2534 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2536 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2535 const ptr_ty = self.air.typeOf(bin_op.lhs);2537 const ptr_ty = self.typeOf(bin_op.lhs);
2536 const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {2538 const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
2537 const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };2539 const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
2538 const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };2540 const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
...@@ -2549,8 +2551,8 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2549,8 +2551,8 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
2549 const ptr_bind: ReadArg.Bind = .{ .inst = extra.lhs };2551 const ptr_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2550 const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };2552 const index_bind: ReadArg.Bind = .{ .inst = extra.rhs };
25512553
2552 const ptr_ty = self.air.typeOf(extra.lhs);2554 const ptr_ty = self.typeOf(extra.lhs);
2553 const index_ty = self.air.typeOf(extra.rhs);2555 const index_ty = self.typeOf(extra.rhs);
25542556
2555 const addr = try self.ptrArithmetic(.ptr_add, ptr_bind, index_bind, ptr_ty, index_ty, null);2557 const addr = try self.ptrArithmetic(.ptr_add, ptr_bind, index_bind, ptr_ty, index_ty, null);
2556 break :result addr;2558 break :result addr;
...@@ -2736,13 +2738,13 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -2736,13 +2738,13 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
2736fn airLoad(self: *Self, inst: Air.Inst.Index) !void {2738fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
2737 const mod = self.bin_file.options.module.?;2739 const mod = self.bin_file.options.module.?;
2738 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2740 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2739 const elem_ty = self.air.typeOfIndex(inst);2741 const elem_ty = self.typeOfIndex(inst);
2740 const result: MCValue = result: {2742 const result: MCValue = result: {
2741 if (!elem_ty.hasRuntimeBits(mod))2743 if (!elem_ty.hasRuntimeBits(mod))
2742 break :result MCValue.none;2744 break :result MCValue.none;
27432745
2744 const ptr = try self.resolveInst(ty_op.operand);2746 const ptr = try self.resolveInst(ty_op.operand);
2745 const is_volatile = self.air.typeOf(ty_op.operand).isVolatilePtr();2747 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
2746 if (self.liveness.isUnused(inst) and !is_volatile)2748 if (self.liveness.isUnused(inst) and !is_volatile)
2747 break :result MCValue.dead;2749 break :result MCValue.dead;
27482750
...@@ -2755,7 +2757,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -2755,7 +2757,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
2755 break :blk try self.allocRegOrMem(elem_ty, true, inst);2757 break :blk try self.allocRegOrMem(elem_ty, true, inst);
2756 }2758 }
2757 };2759 };
2758 try self.load(dest_mcv, ptr, self.air.typeOf(ty_op.operand));2760 try self.load(dest_mcv, ptr, self.typeOf(ty_op.operand));
27592761
2760 break :result dest_mcv;2762 break :result dest_mcv;
2761 };2763 };
...@@ -2860,8 +2862,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -2860,8 +2862,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
2860 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2862 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2861 const ptr = try self.resolveInst(bin_op.lhs);2863 const ptr = try self.resolveInst(bin_op.lhs);
2862 const value = try self.resolveInst(bin_op.rhs);2864 const value = try self.resolveInst(bin_op.rhs);
2863 const ptr_ty = self.air.typeOf(bin_op.lhs);2865 const ptr_ty = self.typeOf(bin_op.lhs);
2864 const value_ty = self.air.typeOf(bin_op.rhs);2866 const value_ty = self.typeOf(bin_op.rhs);
28652867
2866 try self.store(ptr, value, ptr_ty, value_ty);2868 try self.store(ptr, value, ptr_ty, value_ty);
28672869
...@@ -2885,7 +2887,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -2885,7 +2887,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
2885 return if (self.liveness.isUnused(inst)) .dead else result: {2887 return if (self.liveness.isUnused(inst)) .dead else result: {
2886 const mod = self.bin_file.options.module.?;2888 const mod = self.bin_file.options.module.?;
2887 const mcv = try self.resolveInst(operand);2889 const mcv = try self.resolveInst(operand);
2888 const ptr_ty = self.air.typeOf(operand);2890 const ptr_ty = self.typeOf(operand);
2889 const struct_ty = ptr_ty.childType();2891 const struct_ty = ptr_ty.childType();
2890 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));2892 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
2891 switch (mcv) {2893 switch (mcv) {
...@@ -2910,7 +2912,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2910,7 +2912,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2910 const mod = self.bin_file.options.module.?;2912 const mod = self.bin_file.options.module.?;
2911 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2913 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2912 const mcv = try self.resolveInst(operand);2914 const mcv = try self.resolveInst(operand);
2913 const struct_ty = self.air.typeOf(operand);2915 const struct_ty = self.typeOf(operand);
2914 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));2916 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
2915 const struct_field_ty = struct_ty.structFieldType(index);2917 const struct_field_ty = struct_ty.structFieldType(index);
29162918
...@@ -4169,7 +4171,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4169,7 +4171,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4169 while (self.args[arg_index] == .none) arg_index += 1;4171 while (self.args[arg_index] == .none) arg_index += 1;
4170 self.arg_index = arg_index + 1;4172 self.arg_index = arg_index + 1;
41714173
4172 const ty = self.air.typeOfIndex(inst);4174 const ty = self.typeOfIndex(inst);
4173 const tag = self.air.instructions.items(.tag)[inst];4175 const tag = self.air.instructions.items(.tag)[inst];
4174 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;4176 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
4175 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);4177 const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
...@@ -4222,7 +4224,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4222,7 +4224,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4222 const callee = pl_op.operand;4224 const callee = pl_op.operand;
4223 const extra = self.air.extraData(Air.Call, pl_op.payload);4225 const extra = self.air.extraData(Air.Call, pl_op.payload);
4224 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);4226 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
4225 const ty = self.air.typeOf(callee);4227 const ty = self.typeOf(callee);
4226 const mod = self.bin_file.options.module.?;4228 const mod = self.bin_file.options.module.?;
42274229
4228 const fn_ty = switch (ty.zigTypeTag(mod)) {4230 const fn_ty = switch (ty.zigTypeTag(mod)) {
...@@ -4276,7 +4278,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4276,7 +4278,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42764278
4277 for (info.args, 0..) |mc_arg, arg_i| {4279 for (info.args, 0..) |mc_arg, arg_i| {
4278 const arg = args[arg_i];4280 const arg = args[arg_i];
4279 const arg_ty = self.air.typeOf(arg);4281 const arg_ty = self.typeOf(arg);
4280 const arg_mcv = try self.resolveInst(args[arg_i]);4282 const arg_mcv = try self.resolveInst(args[arg_i]);
42814283
4282 switch (mc_arg) {4284 switch (mc_arg) {
...@@ -4418,7 +4420,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -4418,7 +4420,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4418fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {4420fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4419 const un_op = self.air.instructions.items(.data)[inst].un_op;4421 const un_op = self.air.instructions.items(.data)[inst].un_op;
4420 const ptr = try self.resolveInst(un_op);4422 const ptr = try self.resolveInst(un_op);
4421 const ptr_ty = self.air.typeOf(un_op);4423 const ptr_ty = self.typeOf(un_op);
4422 const ret_ty = self.fn_type.fnReturnType();4424 const ret_ty = self.fn_type.fnReturnType();
44234425
4424 switch (self.ret_mcv) {4426 switch (self.ret_mcv) {
...@@ -4461,7 +4463,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -4461,7 +4463,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
44614463
4462fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {4464fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
4463 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4465 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4464 const lhs_ty = self.air.typeOf(bin_op.lhs);4466 const lhs_ty = self.typeOf(bin_op.lhs);
44654467
4466 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {4468 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
4467 break :blk try self.cmp(.{ .inst = bin_op.lhs }, .{ .inst = bin_op.rhs }, lhs_ty, op);4469 break :blk try self.cmp(.{ .inst = bin_op.lhs }, .{ .inst = bin_op.rhs }, lhs_ty, op);
...@@ -4600,7 +4602,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {...@@ -4600,7 +4602,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
4600 const pl_op = self.air.instructions.items(.data)[inst].pl_op;4602 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
4601 const operand = pl_op.operand;4603 const operand = pl_op.operand;
4602 const tag = self.air.instructions.items(.tag)[inst];4604 const tag = self.air.instructions.items(.tag)[inst];
4603 const ty = self.air.typeOf(operand);4605 const ty = self.typeOf(operand);
4604 const mcv = try self.resolveInst(operand);4606 const mcv = try self.resolveInst(operand);
4605 const name = self.air.nullTerminatedString(pl_op.payload);4607 const name = self.air.nullTerminatedString(pl_op.payload);
46064608
...@@ -4755,7 +4757,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4755,7 +4757,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
4755 log.debug("consolidating else_entry {d} {}=>{}", .{ else_key, else_value, canon_mcv });4757 log.debug("consolidating else_entry {d} {}=>{}", .{ else_key, else_value, canon_mcv });
4756 // TODO make sure the destination stack offset / register does not already have something4758 // TODO make sure the destination stack offset / register does not already have something
4757 // going on there.4759 // going on there.
4758 try self.setRegOrMem(self.air.typeOfIndex(else_key), canon_mcv, else_value);4760 try self.setRegOrMem(self.typeOfIndex(else_key), canon_mcv, else_value);
4759 // TODO track the new register / stack allocation4761 // TODO track the new register / stack allocation
4760 }4762 }
4761 try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, saved_then_branch.inst_table.count());4763 try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, saved_then_branch.inst_table.count());
...@@ -4782,7 +4784,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4782,7 +4784,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
4782 log.debug("consolidating then_entry {d} {}=>{}", .{ then_key, parent_mcv, then_value });4784 log.debug("consolidating then_entry {d} {}=>{}", .{ then_key, parent_mcv, then_value });
4783 // TODO make sure the destination stack offset / register does not already have something4785 // TODO make sure the destination stack offset / register does not already have something
4784 // going on there.4786 // going on there.
4785 try self.setRegOrMem(self.air.typeOfIndex(then_key), parent_mcv, then_value);4787 try self.setRegOrMem(self.typeOfIndex(then_key), parent_mcv, then_value);
4786 // TODO track the new register / stack allocation4788 // TODO track the new register / stack allocation
4787 }4789 }
47884790
...@@ -4827,7 +4829,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -4827,7 +4829,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
4827 const un_op = self.air.instructions.items(.data)[inst].un_op;4829 const un_op = self.air.instructions.items(.data)[inst].un_op;
4828 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4830 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4829 const operand_bind: ReadArg.Bind = .{ .inst = un_op };4831 const operand_bind: ReadArg.Bind = .{ .inst = un_op };
4830 const operand_ty = self.air.typeOf(un_op);4832 const operand_ty = self.typeOf(un_op);
48314833
4832 break :result try self.isNull(operand_bind, operand_ty);4834 break :result try self.isNull(operand_bind, operand_ty);
4833 };4835 };
...@@ -4838,7 +4840,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4838,7 +4840,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4838 const un_op = self.air.instructions.items(.data)[inst].un_op;4840 const un_op = self.air.instructions.items(.data)[inst].un_op;
4839 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4841 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4840 const operand_ptr = try self.resolveInst(un_op);4842 const operand_ptr = try self.resolveInst(un_op);
4841 const ptr_ty = self.air.typeOf(un_op);4843 const ptr_ty = self.typeOf(un_op);
4842 const elem_ty = ptr_ty.elemType();4844 const elem_ty = ptr_ty.elemType();
48434845
4844 const operand = try self.allocRegOrMem(elem_ty, true, null);4846 const operand = try self.allocRegOrMem(elem_ty, true, null);
...@@ -4853,7 +4855,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -4853,7 +4855,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
4853 const un_op = self.air.instructions.items(.data)[inst].un_op;4855 const un_op = self.air.instructions.items(.data)[inst].un_op;
4854 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4856 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4855 const operand_bind: ReadArg.Bind = .{ .inst = un_op };4857 const operand_bind: ReadArg.Bind = .{ .inst = un_op };
4856 const operand_ty = self.air.typeOf(un_op);4858 const operand_ty = self.typeOf(un_op);
48574859
4858 break :result try self.isNonNull(operand_bind, operand_ty);4860 break :result try self.isNonNull(operand_bind, operand_ty);
4859 };4861 };
...@@ -4864,7 +4866,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4864,7 +4866,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4864 const un_op = self.air.instructions.items(.data)[inst].un_op;4866 const un_op = self.air.instructions.items(.data)[inst].un_op;
4865 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4867 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4866 const operand_ptr = try self.resolveInst(un_op);4868 const operand_ptr = try self.resolveInst(un_op);
4867 const ptr_ty = self.air.typeOf(un_op);4869 const ptr_ty = self.typeOf(un_op);
4868 const elem_ty = ptr_ty.elemType();4870 const elem_ty = ptr_ty.elemType();
48694871
4870 const operand = try self.allocRegOrMem(elem_ty, true, null);4872 const operand = try self.allocRegOrMem(elem_ty, true, null);
...@@ -4913,7 +4915,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4913,7 +4915,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
4913 const un_op = self.air.instructions.items(.data)[inst].un_op;4915 const un_op = self.air.instructions.items(.data)[inst].un_op;
4914 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4916 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4915 const error_union_bind: ReadArg.Bind = .{ .inst = un_op };4917 const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
4916 const error_union_ty = self.air.typeOf(un_op);4918 const error_union_ty = self.typeOf(un_op);
49174919
4918 break :result try self.isErr(error_union_bind, error_union_ty);4920 break :result try self.isErr(error_union_bind, error_union_ty);
4919 };4921 };
...@@ -4924,7 +4926,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4924,7 +4926,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4924 const un_op = self.air.instructions.items(.data)[inst].un_op;4926 const un_op = self.air.instructions.items(.data)[inst].un_op;
4925 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4927 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4926 const operand_ptr = try self.resolveInst(un_op);4928 const operand_ptr = try self.resolveInst(un_op);
4927 const ptr_ty = self.air.typeOf(un_op);4929 const ptr_ty = self.typeOf(un_op);
4928 const elem_ty = ptr_ty.elemType();4930 const elem_ty = ptr_ty.elemType();
49294931
4930 const operand = try self.allocRegOrMem(elem_ty, true, null);4932 const operand = try self.allocRegOrMem(elem_ty, true, null);
...@@ -4939,7 +4941,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4939,7 +4941,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
4939 const un_op = self.air.instructions.items(.data)[inst].un_op;4941 const un_op = self.air.instructions.items(.data)[inst].un_op;
4940 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4942 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4941 const error_union_bind: ReadArg.Bind = .{ .inst = un_op };4943 const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
4942 const error_union_ty = self.air.typeOf(un_op);4944 const error_union_ty = self.typeOf(un_op);
49434945
4944 break :result try self.isNonErr(error_union_bind, error_union_ty);4946 break :result try self.isNonErr(error_union_bind, error_union_ty);
4945 };4947 };
...@@ -4950,7 +4952,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4950,7 +4952,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4950 const un_op = self.air.instructions.items(.data)[inst].un_op;4952 const un_op = self.air.instructions.items(.data)[inst].un_op;
4951 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4953 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4952 const operand_ptr = try self.resolveInst(un_op);4954 const operand_ptr = try self.resolveInst(un_op);
4953 const ptr_ty = self.air.typeOf(un_op);4955 const ptr_ty = self.typeOf(un_op);
4954 const elem_ty = ptr_ty.elemType();4956 const elem_ty = ptr_ty.elemType();
49554957
4956 const operand = try self.allocRegOrMem(elem_ty, true, null);4958 const operand = try self.allocRegOrMem(elem_ty, true, null);
...@@ -5018,7 +5020,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -5018,7 +5020,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
50185020
5019fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {5021fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
5020 const pl_op = self.air.instructions.items(.data)[inst].pl_op;5022 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
5021 const condition_ty = self.air.typeOf(pl_op.operand);5023 const condition_ty = self.typeOf(pl_op.operand);
5022 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);5024 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
5023 const liveness = try self.liveness.getSwitchBr(5025 const liveness = try self.liveness.getSwitchBr(
5024 self.gpa,5026 self.gpa,
...@@ -5164,7 +5166,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {...@@ -5164,7 +5166,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5164 const mod = self.bin_file.options.module.?;5166 const mod = self.bin_file.options.module.?;
5165 const block_data = self.blocks.getPtr(block).?;5167 const block_data = self.blocks.getPtr(block).?;
51665168
5167 if (self.air.typeOf(operand).hasRuntimeBits(mod)) {5169 if (self.typeOf(operand).hasRuntimeBits(mod)) {
5168 const operand_mcv = try self.resolveInst(operand);5170 const operand_mcv = try self.resolveInst(operand);
5169 const block_mcv = block_data.mcv;5171 const block_mcv = block_data.mcv;
5170 if (block_mcv == .none) {5172 if (block_mcv == .none) {
...@@ -5172,14 +5174,14 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {...@@ -5172,14 +5174,14 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5172 .none, .dead, .unreach => unreachable,5174 .none, .dead, .unreach => unreachable,
5173 .register, .stack_offset, .memory => operand_mcv,5175 .register, .stack_offset, .memory => operand_mcv,
5174 .immediate, .stack_argument_offset, .cpsr_flags => blk: {5176 .immediate, .stack_argument_offset, .cpsr_flags => blk: {
5175 const new_mcv = try self.allocRegOrMem(self.air.typeOfIndex(block), true, block);5177 const new_mcv = try self.allocRegOrMem(self.typeOfIndex(block), true, block);
5176 try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv);5178 try self.setRegOrMem(self.typeOfIndex(block), new_mcv, operand_mcv);
5177 break :blk new_mcv;5179 break :blk new_mcv;
5178 },5180 },
5179 else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),5181 else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),
5180 };5182 };
5181 } else {5183 } else {
5182 try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv);5184 try self.setRegOrMem(self.typeOfIndex(block), block_mcv, operand_mcv);
5183 }5185 }
5184 }5186 }
5185 return self.brVoid(block);5187 return self.brVoid(block);
...@@ -5243,7 +5245,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -5243,7 +5245,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
52435245
5244 const arg_mcv = try self.resolveInst(input);5246 const arg_mcv = try self.resolveInst(input);
5245 try self.register_manager.getReg(reg, null);5247 try self.register_manager.getReg(reg, null);
5246 try self.genSetReg(self.air.typeOf(input), reg, arg_mcv);5248 try self.genSetReg(self.typeOf(input), reg, arg_mcv);
5247 }5249 }
52485250
5249 {5251 {
...@@ -5896,7 +5898,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -5896,7 +5898,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
5896 };5898 };
5897 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);5899 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
58985900
5899 const dest_ty = self.air.typeOfIndex(inst);5901 const dest_ty = self.typeOfIndex(inst);
5900 const dest = try self.allocRegOrMem(dest_ty, true, inst);5902 const dest = try self.allocRegOrMem(dest_ty, true, inst);
5901 try self.setRegOrMem(dest_ty, dest, operand);5903 try self.setRegOrMem(dest_ty, dest, operand);
5902 break :result dest;5904 break :result dest;
...@@ -5907,7 +5909,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -5907,7 +5909,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
5907fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {5909fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
5908 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5910 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5909 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {5911 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
5910 const ptr_ty = self.air.typeOf(ty_op.operand);5912 const ptr_ty = self.typeOf(ty_op.operand);
5911 const ptr = try self.resolveInst(ty_op.operand);5913 const ptr = try self.resolveInst(ty_op.operand);
5912 const array_ty = ptr_ty.childType();5914 const array_ty = ptr_ty.childType();
5913 const array_len = @intCast(u32, array_ty.arrayLen());5915 const array_len = @intCast(u32, array_ty.arrayLen());
...@@ -6023,7 +6025,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {...@@ -6023,7 +6025,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
6023}6025}
60246026
6025fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {6027fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
6026 const vector_ty = self.air.typeOfIndex(inst);6028 const vector_ty = self.typeOfIndex(inst);
6027 const len = vector_ty.vectorLen();6029 const len = vector_ty.vectorLen();
6028 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;6030 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
6029 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);6031 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
...@@ -6072,7 +6074,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {...@@ -6072,7 +6074,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
6072 const body = self.air.extra[extra.end..][0..extra.data.body_len];6074 const body = self.air.extra[extra.end..][0..extra.data.body_len];
6073 const result: MCValue = result: {6075 const result: MCValue = result: {
6074 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };6076 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
6075 const error_union_ty = self.air.typeOf(pl_op.operand);6077 const error_union_ty = self.typeOf(pl_op.operand);
6076 const mod = self.bin_file.options.module.?;6078 const mod = self.bin_file.options.module.?;
6077 const error_union_size = @intCast(u32, error_union_ty.abiSize(mod));6079 const error_union_size = @intCast(u32, error_union_ty.abiSize(mod));
6078 const error_union_align = error_union_ty.abiAlignment(mod);6080 const error_union_align = error_union_ty.abiAlignment(mod);
...@@ -6107,7 +6109,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {...@@ -6107,7 +6109,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
6107 const mod = self.bin_file.options.module.?;6109 const mod = self.bin_file.options.module.?;
61086110
6109 // If the type has no codegen bits, no need to store it.6111 // If the type has no codegen bits, no need to store it.
6110 const inst_ty = self.air.typeOf(inst);6112 const inst_ty = self.typeOf(inst);
6111 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))6113 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))
6112 return MCValue{ .none = {} };6114 return MCValue{ .none = {} };
61136115
...@@ -6333,3 +6335,13 @@ fn parseRegName(name: []const u8) ?Register {...@@ -6333,3 +6335,13 @@ fn parseRegName(name: []const u8) ?Register {
6333 }6335 }
6334 return std.meta.stringToEnum(Register, name);6336 return std.meta.stringToEnum(Register, name);
6335}6337}
6338
6339fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
6340 const mod = self.bin_file.options.module.?;
6341 return self.air.typeOf(inst, mod.intern_pool);
6342}
6343
6344fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
6345 const mod = self.bin_file.options.module.?;
6346 return self.air.typeOfIndex(inst, mod.intern_pool);
6347}
src/arch/riscv64/CodeGen.zig+46-34
...@@ -470,13 +470,14 @@ fn gen(self: *Self) !void {...@@ -470,13 +470,14 @@ fn gen(self: *Self) !void {
470}470}
471471
472fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {472fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
473 const mod = self.bin_file.options.module.?;
474 const ip = &mod.intern_pool;
473 const air_tags = self.air.instructions.items(.tag);475 const air_tags = self.air.instructions.items(.tag);
474476
475 for (body) |inst| {477 for (body) |inst| {
476 // TODO: remove now-redundant isUnused calls from AIR handler functions478 // TODO: remove now-redundant isUnused calls from AIR handler functions
477 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {479 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
478 continue;480 continue;
479 }
480481
481 const old_air_bookkeeping = self.air_bookkeeping;482 const old_air_bookkeeping = self.air_bookkeeping;
482 try self.ensureProcessDeathCapacity(Liveness.bpi);483 try self.ensureProcessDeathCapacity(Liveness.bpi);
...@@ -658,6 +659,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -658,6 +659,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
658659
659 .constant => unreachable, // excluded from function bodies660 .constant => unreachable, // excluded from function bodies
660 .const_ty => unreachable, // excluded from function bodies661 .const_ty => unreachable, // excluded from function bodies
662 .interned => unreachable, // excluded from function bodies
661 .unreach => self.finishAirBookkeeping(),663 .unreach => self.finishAirBookkeeping(),
662664
663 .optional_payload => try self.airOptionalPayload(inst),665 .optional_payload => try self.airOptionalPayload(inst),
...@@ -804,8 +806,8 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u...@@ -804,8 +806,8 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
804806
805/// Use a pointer instruction as the basis for allocating stack memory.807/// Use a pointer instruction as the basis for allocating stack memory.
806fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {808fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
807 const elem_ty = self.air.typeOfIndex(inst).elemType();
808 const mod = self.bin_file.options.module.?;809 const mod = self.bin_file.options.module.?;
810 const elem_ty = self.typeOfIndex(inst).elemType();
809 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {811 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
810 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});812 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
811 };813 };
...@@ -815,8 +817,8 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -815,8 +817,8 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
815}817}
816818
817fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {819fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
818 const elem_ty = self.air.typeOfIndex(inst);
819 const mod = self.bin_file.options.module.?;820 const mod = self.bin_file.options.module.?;
821 const elem_ty = self.typeOfIndex(inst);
820 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {822 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
821 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});823 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
822 };824 };
...@@ -845,7 +847,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void...@@ -845,7 +847,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
845 assert(reg == reg_mcv.register);847 assert(reg == reg_mcv.register);
846 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];848 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
847 try branch.inst_table.put(self.gpa, inst, stack_mcv);849 try branch.inst_table.put(self.gpa, inst, stack_mcv);
848 try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);850 try self.genSetStack(self.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
849}851}
850852
851/// Copies a value to a register without tracking the register. The register is not considered853/// Copies a value to a register without tracking the register. The register is not considered
...@@ -862,7 +864,7 @@ fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register {...@@ -862,7 +864,7 @@ fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register {
862/// This can have a side effect of spilling instructions to the stack to free up a register.864/// This can have a side effect of spilling instructions to the stack to free up a register.
863fn copyToNewRegister(self: *Self, reg_owner: Air.Inst.Index, mcv: MCValue) !MCValue {865fn copyToNewRegister(self: *Self, reg_owner: Air.Inst.Index, mcv: MCValue) !MCValue {
864 const reg = try self.register_manager.allocReg(reg_owner, gp);866 const reg = try self.register_manager.allocReg(reg_owner, gp);
865 try self.genSetReg(self.air.typeOfIndex(reg_owner), reg, mcv);867 try self.genSetReg(self.typeOfIndex(reg_owner), reg, mcv);
866 return MCValue{ .register = reg };868 return MCValue{ .register = reg };
867}869}
868870
...@@ -894,10 +896,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -894,10 +896,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
894 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });896 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
895897
896 const mod = self.bin_file.options.module.?;898 const mod = self.bin_file.options.module.?;
897 const operand_ty = self.air.typeOf(ty_op.operand);899 const operand_ty = self.typeOf(ty_op.operand);
898 const operand = try self.resolveInst(ty_op.operand);900 const operand = try self.resolveInst(ty_op.operand);
899 const info_a = operand_ty.intInfo(mod);901 const info_a = operand_ty.intInfo(mod);
900 const info_b = self.air.typeOfIndex(inst).intInfo(mod);902 const info_b = self.typeOfIndex(inst).intInfo(mod);
901 if (info_a.signedness != info_b.signedness)903 if (info_a.signedness != info_b.signedness)
902 return self.fail("TODO gen intcast sign safety in semantic analysis", .{});904 return self.fail("TODO gen intcast sign safety in semantic analysis", .{});
903905
...@@ -1126,8 +1128,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {...@@ -1126,8 +1128,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
1126 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1128 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1127 const lhs = try self.resolveInst(bin_op.lhs);1129 const lhs = try self.resolveInst(bin_op.lhs);
1128 const rhs = try self.resolveInst(bin_op.rhs);1130 const rhs = try self.resolveInst(bin_op.rhs);
1129 const lhs_ty = self.air.typeOf(bin_op.lhs);1131 const lhs_ty = self.typeOf(bin_op.lhs);
1130 const rhs_ty = self.air.typeOf(bin_op.rhs);1132 const rhs_ty = self.typeOf(bin_op.rhs);
11311133
1132 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.binOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);1134 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.binOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);
1133 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1135 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
...@@ -1138,8 +1140,8 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -1138,8 +1140,8 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
1138 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;1140 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
1139 const lhs = try self.resolveInst(bin_op.lhs);1141 const lhs = try self.resolveInst(bin_op.lhs);
1140 const rhs = try self.resolveInst(bin_op.rhs);1142 const rhs = try self.resolveInst(bin_op.rhs);
1141 const lhs_ty = self.air.typeOf(bin_op.lhs);1143 const lhs_ty = self.typeOf(bin_op.lhs);
1142 const rhs_ty = self.air.typeOf(bin_op.rhs);1144 const rhs_ty = self.typeOf(bin_op.rhs);
11431145
1144 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.binOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);1146 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.binOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);
1145 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1147 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
...@@ -1333,7 +1335,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -1333,7 +1335,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
1333 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1335 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1334 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1336 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1335 const mod = self.bin_file.options.module.?;1337 const mod = self.bin_file.options.module.?;
1336 const optional_ty = self.air.typeOfIndex(inst);1338 const optional_ty = self.typeOfIndex(inst);
13371339
1338 // Optional with a zero-bit payload type is just a boolean true1340 // Optional with a zero-bit payload type is just a boolean true
1339 if (optional_ty.abiSize(mod) == 1)1341 if (optional_ty.abiSize(mod) == 1)
...@@ -1525,15 +1527,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -1525,15 +1527,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
1525}1527}
15261528
1527fn airLoad(self: *Self, inst: Air.Inst.Index) !void {1529fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1530 const mod = self.bin_file.options.module.?;
1528 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1531 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1529 const elem_ty = self.air.typeOfIndex(inst);1532 const elem_ty = self.typeOfIndex(inst);
1530 const result: MCValue = result: {1533 const result: MCValue = result: {
1531 const mod = self.bin_file.options.module.?;
1532 if (!elem_ty.hasRuntimeBits(mod))1534 if (!elem_ty.hasRuntimeBits(mod))
1533 break :result MCValue.none;1535 break :result MCValue.none;
15341536
1535 const ptr = try self.resolveInst(ty_op.operand);1537 const ptr = try self.resolveInst(ty_op.operand);
1536 const is_volatile = self.air.typeOf(ty_op.operand).isVolatilePtr();1538 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
1537 if (self.liveness.isUnused(inst) and !is_volatile)1539 if (self.liveness.isUnused(inst) and !is_volatile)
1538 break :result MCValue.dead;1540 break :result MCValue.dead;
15391541
...@@ -1545,7 +1547,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -1545,7 +1547,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1545 break :blk try self.allocRegOrMem(inst, true);1547 break :blk try self.allocRegOrMem(inst, true);
1546 }1548 }
1547 };1549 };
1548 try self.load(dst_mcv, ptr, self.air.typeOf(ty_op.operand));1550 try self.load(dst_mcv, ptr, self.typeOf(ty_op.operand));
1549 break :result dst_mcv;1551 break :result dst_mcv;
1550 };1552 };
1551 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1553 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
...@@ -1586,8 +1588,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -1586,8 +1588,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
1586 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1588 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1587 const ptr = try self.resolveInst(bin_op.lhs);1589 const ptr = try self.resolveInst(bin_op.lhs);
1588 const value = try self.resolveInst(bin_op.rhs);1590 const value = try self.resolveInst(bin_op.rhs);
1589 const ptr_ty = self.air.typeOf(bin_op.lhs);1591 const ptr_ty = self.typeOf(bin_op.lhs);
1590 const value_ty = self.air.typeOf(bin_op.rhs);1592 const value_ty = self.typeOf(bin_op.rhs);
15911593
1592 try self.store(ptr, value, ptr_ty, value_ty);1594 try self.store(ptr, value, ptr_ty, value_ty);
15931595
...@@ -1647,7 +1649,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -1647,7 +1649,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1647 const arg_index = self.arg_index;1649 const arg_index = self.arg_index;
1648 self.arg_index += 1;1650 self.arg_index += 1;
16491651
1650 const ty = self.air.typeOfIndex(inst);1652 const ty = self.typeOfIndex(inst);
1651 _ = ty;1653 _ = ty;
16521654
1653 const result = self.args[arg_index];1655 const result = self.args[arg_index];
...@@ -1704,7 +1706,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1704,7 +1706,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
1704 const mod = self.bin_file.options.module.?;1706 const mod = self.bin_file.options.module.?;
1705 if (modifier == .always_tail) return self.fail("TODO implement tail calls for riscv64", .{});1707 if (modifier == .always_tail) return self.fail("TODO implement tail calls for riscv64", .{});
1706 const pl_op = self.air.instructions.items(.data)[inst].pl_op;1708 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
1707 const fn_ty = self.air.typeOf(pl_op.operand);1709 const fn_ty = self.typeOf(pl_op.operand);
1708 const callee = pl_op.operand;1710 const callee = pl_op.operand;
1709 const extra = self.air.extraData(Air.Call, pl_op.payload);1711 const extra = self.air.extraData(Air.Call, pl_op.payload);
1710 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);1712 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
...@@ -1717,7 +1719,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1717,7 +1719,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
1717 if (self.bin_file.cast(link.File.Elf)) |elf_file| {1719 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
1718 for (info.args, 0..) |mc_arg, arg_i| {1720 for (info.args, 0..) |mc_arg, arg_i| {
1719 const arg = args[arg_i];1721 const arg = args[arg_i];
1720 const arg_ty = self.air.typeOf(arg);1722 const arg_ty = self.typeOf(arg);
1721 const arg_mcv = try self.resolveInst(args[arg_i]);1723 const arg_mcv = try self.resolveInst(args[arg_i]);
17221724
1723 switch (mc_arg) {1725 switch (mc_arg) {
...@@ -1829,9 +1831,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -1829,9 +1831,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1829 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1831 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1830 if (self.liveness.isUnused(inst))1832 if (self.liveness.isUnused(inst))
1831 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });1833 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
1832 const ty = self.air.typeOf(bin_op.lhs);1834 const ty = self.typeOf(bin_op.lhs);
1833 const mod = self.bin_file.options.module.?;1835 const mod = self.bin_file.options.module.?;
1834 assert(ty.eql(self.air.typeOf(bin_op.rhs), mod));1836 assert(ty.eql(self.typeOf(bin_op.rhs), mod));
1835 if (ty.zigTypeTag(mod) == .ErrorSet)1837 if (ty.zigTypeTag(mod) == .ErrorSet)
1836 return self.fail("TODO implement cmp for errors", .{});1838 return self.fail("TODO implement cmp for errors", .{});
18371839
...@@ -1950,7 +1952,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1950,7 +1952,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
1950 break :blk try self.allocRegOrMem(inst, true);1952 break :blk try self.allocRegOrMem(inst, true);
1951 }1953 }
1952 };1954 };
1953 try self.load(operand, operand_ptr, self.air.typeOf(un_op));1955 try self.load(operand, operand_ptr, self.typeOf(un_op));
1954 break :result try self.isNull(operand);1956 break :result try self.isNull(operand);
1955 };1957 };
1956 return self.finishAir(inst, result, .{ un_op, .none, .none });1958 return self.finishAir(inst, result, .{ un_op, .none, .none });
...@@ -1977,7 +1979,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1977,7 +1979,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
1977 break :blk try self.allocRegOrMem(inst, true);1979 break :blk try self.allocRegOrMem(inst, true);
1978 }1980 }
1979 };1981 };
1980 try self.load(operand, operand_ptr, self.air.typeOf(un_op));1982 try self.load(operand, operand_ptr, self.typeOf(un_op));
1981 break :result try self.isNonNull(operand);1983 break :result try self.isNonNull(operand);
1982 };1984 };
1983 return self.finishAir(inst, result, .{ un_op, .none, .none });1985 return self.finishAir(inst, result, .{ un_op, .none, .none });
...@@ -2004,7 +2006,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2004,7 +2006,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
2004 break :blk try self.allocRegOrMem(inst, true);2006 break :blk try self.allocRegOrMem(inst, true);
2005 }2007 }
2006 };2008 };
2007 try self.load(operand, operand_ptr, self.air.typeOf(un_op));2009 try self.load(operand, operand_ptr, self.typeOf(un_op));
2008 break :result try self.isErr(operand);2010 break :result try self.isErr(operand);
2009 };2011 };
2010 return self.finishAir(inst, result, .{ un_op, .none, .none });2012 return self.finishAir(inst, result, .{ un_op, .none, .none });
...@@ -2031,7 +2033,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2031,7 +2033,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
2031 break :blk try self.allocRegOrMem(inst, true);2033 break :blk try self.allocRegOrMem(inst, true);
2032 }2034 }
2033 };2035 };
2034 try self.load(operand, operand_ptr, self.air.typeOf(un_op));2036 try self.load(operand, operand_ptr, self.typeOf(un_op));
2035 break :result try self.isNonErr(operand);2037 break :result try self.isNonErr(operand);
2036 };2038 };
2037 return self.finishAir(inst, result, .{ un_op, .none, .none });2039 return self.finishAir(inst, result, .{ un_op, .none, .none });
...@@ -2112,13 +2114,13 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {...@@ -2112,13 +2114,13 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
2112 const block_data = self.blocks.getPtr(block).?;2114 const block_data = self.blocks.getPtr(block).?;
21132115
2114 const mod = self.bin_file.options.module.?;2116 const mod = self.bin_file.options.module.?;
2115 if (self.air.typeOf(operand).hasRuntimeBits(mod)) {2117 if (self.typeOf(operand).hasRuntimeBits(mod)) {
2116 const operand_mcv = try self.resolveInst(operand);2118 const operand_mcv = try self.resolveInst(operand);
2117 const block_mcv = block_data.mcv;2119 const block_mcv = block_data.mcv;
2118 if (block_mcv == .none) {2120 if (block_mcv == .none) {
2119 block_data.mcv = operand_mcv;2121 block_data.mcv = operand_mcv;
2120 } else {2122 } else {
2121 try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv);2123 try self.setRegOrMem(self.typeOfIndex(block), block_mcv, operand_mcv);
2122 }2124 }
2123 }2125 }
2124 return self.brVoid(block);2126 return self.brVoid(block);
...@@ -2181,7 +2183,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -2181,7 +2183,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
21812183
2182 const arg_mcv = try self.resolveInst(input);2184 const arg_mcv = try self.resolveInst(input);
2183 try self.register_manager.getReg(reg, null);2185 try self.register_manager.getReg(reg, null);
2184 try self.genSetReg(self.air.typeOf(input), reg, arg_mcv);2186 try self.genSetReg(self.typeOf(input), reg, arg_mcv);
2185 }2187 }
21862188
2187 {2189 {
...@@ -2377,7 +2379,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -2377,7 +2379,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
2377 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);2379 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
23782380
2379 const dest = try self.allocRegOrMem(inst, true);2381 const dest = try self.allocRegOrMem(inst, true);
2380 try self.setRegOrMem(self.air.typeOfIndex(inst), dest, operand);2382 try self.setRegOrMem(self.typeOfIndex(inst), dest, operand);
2381 break :result dest;2383 break :result dest;
2382 };2384 };
2383 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });2385 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
...@@ -2494,7 +2496,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {...@@ -2494,7 +2496,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
2494}2496}
24952497
2496fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {2498fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
2497 const vector_ty = self.air.typeOfIndex(inst);2499 const vector_ty = self.typeOfIndex(inst);
2498 const len = vector_ty.vectorLen();2500 const len = vector_ty.vectorLen();
2499 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2501 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2500 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);2502 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
...@@ -2541,7 +2543,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {...@@ -2541,7 +2543,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
2541 const mod = self.bin_file.options.module.?;2543 const mod = self.bin_file.options.module.?;
25422544
2543 // If the type has no codegen bits, no need to store it.2545 // If the type has no codegen bits, no need to store it.
2544 const inst_ty = self.air.typeOf(inst);2546 const inst_ty = self.typeOf(inst);
2545 if (!inst_ty.hasRuntimeBits(mod))2547 if (!inst_ty.hasRuntimeBits(mod))
2546 return MCValue{ .none = {} };2548 return MCValue{ .none = {} };
25472549
...@@ -2733,3 +2735,13 @@ fn parseRegName(name: []const u8) ?Register {...@@ -2733,3 +2735,13 @@ fn parseRegName(name: []const u8) ?Register {
2733 }2735 }
2734 return std.meta.stringToEnum(Register, name);2736 return std.meta.stringToEnum(Register, name);
2735}2737}
2738
2739fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
2740 const mod = self.bin_file.options.module.?;
2741 return self.air.typeOf(inst, mod.intern_pool);
2742}
2743
2744fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
2745 const mod = self.bin_file.options.module.?;
2746 return self.air.typeOfIndex(inst, mod.intern_pool);
2747}
src/arch/sparc64/CodeGen.zig+74-62
...@@ -490,13 +490,14 @@ fn gen(self: *Self) !void {...@@ -490,13 +490,14 @@ fn gen(self: *Self) !void {
490}490}
491491
492fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {492fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
493 const mod = self.bin_file.options.module.?;
494 const ip = &mod.intern_pool;
493 const air_tags = self.air.instructions.items(.tag);495 const air_tags = self.air.instructions.items(.tag);
494496
495 for (body) |inst| {497 for (body) |inst| {
496 // TODO: remove now-redundant isUnused calls from AIR handler functions498 // TODO: remove now-redundant isUnused calls from AIR handler functions
497 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {499 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
498 continue;500 continue;
499 }
500501
501 const old_air_bookkeeping = self.air_bookkeeping;502 const old_air_bookkeeping = self.air_bookkeeping;
502 try self.ensureProcessDeathCapacity(Liveness.bpi);503 try self.ensureProcessDeathCapacity(Liveness.bpi);
...@@ -678,6 +679,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -678,6 +679,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
678679
679 .constant => unreachable, // excluded from function bodies680 .constant => unreachable, // excluded from function bodies
680 .const_ty => unreachable, // excluded from function bodies681 .const_ty => unreachable, // excluded from function bodies
682 .interned => unreachable, // excluded from function bodies
681 .unreach => self.finishAirBookkeeping(),683 .unreach => self.finishAirBookkeeping(),
682684
683 .optional_payload => try self.airOptionalPayload(inst),685 .optional_payload => try self.airOptionalPayload(inst),
...@@ -762,8 +764,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -762,8 +764,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
762 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {764 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
763 const lhs = try self.resolveInst(extra.lhs);765 const lhs = try self.resolveInst(extra.lhs);
764 const rhs = try self.resolveInst(extra.rhs);766 const rhs = try self.resolveInst(extra.rhs);
765 const lhs_ty = self.air.typeOf(extra.lhs);767 const lhs_ty = self.typeOf(extra.lhs);
766 const rhs_ty = self.air.typeOf(extra.rhs);768 const rhs_ty = self.typeOf(extra.rhs);
767769
768 switch (lhs_ty.zigTypeTag(mod)) {770 switch (lhs_ty.zigTypeTag(mod)) {
769 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),771 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
...@@ -836,7 +838,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -836,7 +838,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
836}838}
837839
838fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {840fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
839 const vector_ty = self.air.typeOfIndex(inst);841 const vector_ty = self.typeOfIndex(inst);
840 const len = vector_ty.vectorLen();842 const len = vector_ty.vectorLen();
841 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;843 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
842 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);844 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
...@@ -871,7 +873,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -871,7 +873,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
871fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {873fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
872 const ty_op = self.air.instructions.items(.data)[inst].ty_op;874 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
873 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {875 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
874 const ptr_ty = self.air.typeOf(ty_op.operand);876 const ptr_ty = self.typeOf(ty_op.operand);
875 const ptr = try self.resolveInst(ty_op.operand);877 const ptr = try self.resolveInst(ty_op.operand);
876 const array_ty = ptr_ty.childType();878 const array_ty = ptr_ty.childType();
877 const array_len = @intCast(u32, array_ty.arrayLen());879 const array_len = @intCast(u32, array_ty.arrayLen());
...@@ -935,7 +937,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -935,7 +937,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
935937
936 const arg_mcv = try self.resolveInst(input);938 const arg_mcv = try self.resolveInst(input);
937 try self.register_manager.getReg(reg, null);939 try self.register_manager.getReg(reg, null);
938 try self.genSetReg(self.air.typeOf(input), reg, arg_mcv);940 try self.genSetReg(self.typeOf(input), reg, arg_mcv);
939 }941 }
940942
941 {943 {
...@@ -1008,16 +1010,16 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -1008,16 +1010,16 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
1008}1010}
10091011
1010fn airArg(self: *Self, inst: Air.Inst.Index) !void {1012fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1013 const mod = self.bin_file.options.module.?;
1011 const arg_index = self.arg_index;1014 const arg_index = self.arg_index;
1012 self.arg_index += 1;1015 self.arg_index += 1;
10131016
1014 const ty = self.air.typeOfIndex(inst);1017 const ty = self.typeOfIndex(inst);
10151018
1016 const arg = self.args[arg_index];1019 const arg = self.args[arg_index];
1017 const mcv = blk: {1020 const mcv = blk: {
1018 switch (arg) {1021 switch (arg) {
1019 .stack_offset => |off| {1022 .stack_offset => |off| {
1020 const mod = self.bin_file.options.module.?;
1021 const abi_size = math.cast(u32, ty.abiSize(mod)) orelse {1023 const abi_size = math.cast(u32, ty.abiSize(mod)) orelse {
1022 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});1024 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});
1023 };1025 };
...@@ -1063,8 +1065,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {...@@ -1063,8 +1065,8 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
1063 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1065 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1064 const lhs = try self.resolveInst(bin_op.lhs);1066 const lhs = try self.resolveInst(bin_op.lhs);
1065 const rhs = try self.resolveInst(bin_op.rhs);1067 const rhs = try self.resolveInst(bin_op.rhs);
1066 const lhs_ty = self.air.typeOf(bin_op.lhs);1068 const lhs_ty = self.typeOf(bin_op.lhs);
1067 const rhs_ty = self.air.typeOf(bin_op.rhs);1069 const rhs_ty = self.typeOf(bin_op.rhs);
1068 const result: MCValue = if (self.liveness.isUnused(inst))1070 const result: MCValue = if (self.liveness.isUnused(inst))
1069 .dead1071 .dead
1070 else1072 else
...@@ -1088,8 +1090,8 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void...@@ -1088,8 +1090,8 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
1088 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;1090 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
1089 const lhs = try self.resolveInst(bin_op.lhs);1091 const lhs = try self.resolveInst(bin_op.lhs);
1090 const rhs = try self.resolveInst(bin_op.rhs);1092 const rhs = try self.resolveInst(bin_op.rhs);
1091 const lhs_ty = self.air.typeOf(bin_op.lhs);1093 const lhs_ty = self.typeOf(bin_op.lhs);
1092 const rhs_ty = self.air.typeOf(bin_op.rhs);1094 const rhs_ty = self.typeOf(bin_op.rhs);
1093 const result: MCValue = if (self.liveness.isUnused(inst))1095 const result: MCValue = if (self.liveness.isUnused(inst))
1094 .dead1096 .dead
1095 else1097 else
...@@ -1115,7 +1117,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -1115,7 +1117,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
1115 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);1117 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
11161118
1117 const dest = try self.allocRegOrMem(inst, true);1119 const dest = try self.allocRegOrMem(inst, true);
1118 try self.setRegOrMem(self.air.typeOfIndex(inst), dest, operand);1120 try self.setRegOrMem(self.typeOfIndex(inst), dest, operand);
1119 break :result dest;1121 break :result dest;
1120 };1122 };
1121 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1123 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
...@@ -1218,7 +1220,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {...@@ -1218,7 +1220,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
1218 // TODO: Fold byteswap+store into a single ST*A and load+byteswap into a single LD*A.1220 // TODO: Fold byteswap+store into a single ST*A and load+byteswap into a single LD*A.
1219 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1221 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1220 const operand = try self.resolveInst(ty_op.operand);1222 const operand = try self.resolveInst(ty_op.operand);
1221 const operand_ty = self.air.typeOf(ty_op.operand);1223 const operand_ty = self.typeOf(ty_op.operand);
1222 switch (operand_ty.zigTypeTag(mod)) {1224 switch (operand_ty.zigTypeTag(mod)) {
1223 .Vector => return self.fail("TODO byteswap for vectors", .{}),1225 .Vector => return self.fail("TODO byteswap for vectors", .{}),
1224 .Int => {1226 .Int => {
...@@ -1294,7 +1296,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1294,7 +1296,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
1294 const callee = pl_op.operand;1296 const callee = pl_op.operand;
1295 const extra = self.air.extraData(Air.Call, pl_op.payload);1297 const extra = self.air.extraData(Air.Call, pl_op.payload);
1296 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end .. extra.end + extra.data.args_len]);1298 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end .. extra.end + extra.data.args_len]);
1297 const ty = self.air.typeOf(callee);1299 const ty = self.typeOf(callee);
1298 const mod = self.bin_file.options.module.?;1300 const mod = self.bin_file.options.module.?;
1299 const fn_ty = switch (ty.zigTypeTag(mod)) {1301 const fn_ty = switch (ty.zigTypeTag(mod)) {
1300 .Fn => ty,1302 .Fn => ty,
...@@ -1318,7 +1320,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1318,7 +1320,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
13181320
1319 for (info.args, 0..) |mc_arg, arg_i| {1321 for (info.args, 0..) |mc_arg, arg_i| {
1320 const arg = args[arg_i];1322 const arg = args[arg_i];
1321 const arg_ty = self.air.typeOf(arg);1323 const arg_ty = self.typeOf(arg);
1322 const arg_mcv = try self.resolveInst(arg);1324 const arg_mcv = try self.resolveInst(arg);
13231325
1324 switch (mc_arg) {1326 switch (mc_arg) {
...@@ -1428,7 +1430,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -1428,7 +1430,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1428 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1430 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1429 const lhs = try self.resolveInst(bin_op.lhs);1431 const lhs = try self.resolveInst(bin_op.lhs);
1430 const rhs = try self.resolveInst(bin_op.rhs);1432 const rhs = try self.resolveInst(bin_op.rhs);
1431 const lhs_ty = self.air.typeOf(bin_op.lhs);1433 const lhs_ty = self.typeOf(bin_op.lhs);
14321434
1433 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {1435 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
1434 .Vector => unreachable, // Handled by cmp_vector.1436 .Vector => unreachable, // Handled by cmp_vector.
...@@ -1605,7 +1607,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1605,7 +1607,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
1605 log.debug("consolidating else_entry {d} {}=>{}", .{ else_key, else_value, canon_mcv });1607 log.debug("consolidating else_entry {d} {}=>{}", .{ else_key, else_value, canon_mcv });
1606 // TODO make sure the destination stack offset / register does not already have something1608 // TODO make sure the destination stack offset / register does not already have something
1607 // going on there.1609 // going on there.
1608 try self.setRegOrMem(self.air.typeOfIndex(else_key), canon_mcv, else_value);1610 try self.setRegOrMem(self.typeOfIndex(else_key), canon_mcv, else_value);
1609 // TODO track the new register / stack allocation1611 // TODO track the new register / stack allocation
1610 }1612 }
1611 try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, saved_then_branch.inst_table.count());1613 try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, saved_then_branch.inst_table.count());
...@@ -1632,7 +1634,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1632,7 +1634,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
1632 log.debug("consolidating then_entry {d} {}=>{}", .{ then_key, parent_mcv, then_value });1634 log.debug("consolidating then_entry {d} {}=>{}", .{ then_key, parent_mcv, then_value });
1633 // TODO make sure the destination stack offset / register does not already have something1635 // TODO make sure the destination stack offset / register does not already have something
1634 // going on there.1636 // going on there.
1635 try self.setRegOrMem(self.air.typeOfIndex(then_key), parent_mcv, then_value);1637 try self.setRegOrMem(self.typeOfIndex(then_key), parent_mcv, then_value);
1636 // TODO track the new register / stack allocation1638 // TODO track the new register / stack allocation
1637 }1639 }
16381640
...@@ -1755,10 +1757,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -1755,10 +1757,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1755 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });1757 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
17561758
1757 const mod = self.bin_file.options.module.?;1759 const mod = self.bin_file.options.module.?;
1758 const operand_ty = self.air.typeOf(ty_op.operand);1760 const operand_ty = self.typeOf(ty_op.operand);
1759 const operand = try self.resolveInst(ty_op.operand);1761 const operand = try self.resolveInst(ty_op.operand);
1760 const info_a = operand_ty.intInfo(mod);1762 const info_a = operand_ty.intInfo(mod);
1761 const info_b = self.air.typeOfIndex(inst).intInfo(mod);1763 const info_b = self.typeOfIndex(inst).intInfo(mod);
1762 if (info_a.signedness != info_b.signedness)1764 if (info_a.signedness != info_b.signedness)
1763 return self.fail("TODO gen intcast sign safety in semantic analysis", .{});1765 return self.fail("TODO gen intcast sign safety in semantic analysis", .{});
17641766
...@@ -1780,7 +1782,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1780,7 +1782,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
1780 const un_op = self.air.instructions.items(.data)[inst].un_op;1782 const un_op = self.air.instructions.items(.data)[inst].un_op;
1781 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1783 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1782 const operand = try self.resolveInst(un_op);1784 const operand = try self.resolveInst(un_op);
1783 const ty = self.air.typeOf(un_op);1785 const ty = self.typeOf(un_op);
1784 break :result try self.isErr(ty, operand);1786 break :result try self.isErr(ty, operand);
1785 };1787 };
1786 return self.finishAir(inst, result, .{ un_op, .none, .none });1788 return self.finishAir(inst, result, .{ un_op, .none, .none });
...@@ -1790,7 +1792,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1790,7 +1792,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
1790 const un_op = self.air.instructions.items(.data)[inst].un_op;1792 const un_op = self.air.instructions.items(.data)[inst].un_op;
1791 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1793 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1792 const operand = try self.resolveInst(un_op);1794 const operand = try self.resolveInst(un_op);
1793 const ty = self.air.typeOf(un_op);1795 const ty = self.typeOf(un_op);
1794 break :result try self.isNonErr(ty, operand);1796 break :result try self.isNonErr(ty, operand);
1795 };1797 };
1796 return self.finishAir(inst, result, .{ un_op, .none, .none });1798 return self.finishAir(inst, result, .{ un_op, .none, .none });
...@@ -1815,16 +1817,16 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -1815,16 +1817,16 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
1815}1817}
18161818
1817fn airLoad(self: *Self, inst: Air.Inst.Index) !void {1819fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1818 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1819 const elem_ty = self.air.typeOfIndex(inst);
1820 const mod = self.bin_file.options.module.?;1820 const mod = self.bin_file.options.module.?;
1821 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1822 const elem_ty = self.typeOfIndex(inst);
1821 const elem_size = elem_ty.abiSize(mod);1823 const elem_size = elem_ty.abiSize(mod);
1822 const result: MCValue = result: {1824 const result: MCValue = result: {
1823 if (!elem_ty.hasRuntimeBits(mod))1825 if (!elem_ty.hasRuntimeBits(mod))
1824 break :result MCValue.none;1826 break :result MCValue.none;
18251827
1826 const ptr = try self.resolveInst(ty_op.operand);1828 const ptr = try self.resolveInst(ty_op.operand);
1827 const is_volatile = self.air.typeOf(ty_op.operand).isVolatilePtr();1829 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
1828 if (self.liveness.isUnused(inst) and !is_volatile)1830 if (self.liveness.isUnused(inst) and !is_volatile)
1829 break :result MCValue.dead;1831 break :result MCValue.dead;
18301832
...@@ -1839,7 +1841,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -1839,7 +1841,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1839 break :blk try self.allocRegOrMem(inst, true);1841 break :blk try self.allocRegOrMem(inst, true);
1840 }1842 }
1841 };1843 };
1842 try self.load(dst_mcv, ptr, self.air.typeOf(ty_op.operand));1844 try self.load(dst_mcv, ptr, self.typeOf(ty_op.operand));
1843 break :result dst_mcv;1845 break :result dst_mcv;
1844 };1846 };
1845 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1847 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
...@@ -1882,8 +1884,8 @@ fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {...@@ -1882,8 +1884,8 @@ fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {
1882 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1884 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1883 const lhs = try self.resolveInst(bin_op.lhs);1885 const lhs = try self.resolveInst(bin_op.lhs);
1884 const rhs = try self.resolveInst(bin_op.rhs);1886 const rhs = try self.resolveInst(bin_op.rhs);
1885 const lhs_ty = self.air.typeOf(bin_op.lhs);1887 const lhs_ty = self.typeOf(bin_op.lhs);
1886 const rhs_ty = self.air.typeOf(bin_op.rhs);1888 const rhs_ty = self.typeOf(bin_op.rhs);
18871889
1888 const result: MCValue = if (self.liveness.isUnused(inst))1890 const result: MCValue = if (self.liveness.isUnused(inst))
1889 .dead1891 .dead
...@@ -1897,8 +1899,8 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {...@@ -1897,8 +1899,8 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {
1897 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1899 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1898 const lhs = try self.resolveInst(bin_op.lhs);1900 const lhs = try self.resolveInst(bin_op.lhs);
1899 const rhs = try self.resolveInst(bin_op.rhs);1901 const rhs = try self.resolveInst(bin_op.rhs);
1900 const lhs_ty = self.air.typeOf(bin_op.lhs);1902 const lhs_ty = self.typeOf(bin_op.lhs);
1901 const rhs_ty = self.air.typeOf(bin_op.rhs);1903 const rhs_ty = self.typeOf(bin_op.rhs);
1902 assert(lhs_ty.eql(rhs_ty, self.bin_file.options.module.?));1904 assert(lhs_ty.eql(rhs_ty, self.bin_file.options.module.?));
19031905
1904 if (self.liveness.isUnused(inst))1906 if (self.liveness.isUnused(inst))
...@@ -2045,8 +2047,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2045,8 +2047,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2045 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2047 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2046 const lhs = try self.resolveInst(extra.lhs);2048 const lhs = try self.resolveInst(extra.lhs);
2047 const rhs = try self.resolveInst(extra.rhs);2049 const rhs = try self.resolveInst(extra.rhs);
2048 const lhs_ty = self.air.typeOf(extra.lhs);2050 const lhs_ty = self.typeOf(extra.lhs);
2049 const rhs_ty = self.air.typeOf(extra.rhs);2051 const rhs_ty = self.typeOf(extra.rhs);
20502052
2051 switch (lhs_ty.zigTypeTag(mod)) {2053 switch (lhs_ty.zigTypeTag(mod)) {
2052 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),2054 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
...@@ -2108,7 +2110,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {...@@ -2108,7 +2110,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
2108 const mod = self.bin_file.options.module.?;2110 const mod = self.bin_file.options.module.?;
2109 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2111 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2110 const operand = try self.resolveInst(ty_op.operand);2112 const operand = try self.resolveInst(ty_op.operand);
2111 const operand_ty = self.air.typeOf(ty_op.operand);2113 const operand_ty = self.typeOf(ty_op.operand);
2112 switch (operand) {2114 switch (operand) {
2113 .dead => unreachable,2115 .dead => unreachable,
2114 .unreach => unreachable,2116 .unreach => unreachable,
...@@ -2285,8 +2287,8 @@ fn airRem(self: *Self, inst: Air.Inst.Index) !void {...@@ -2285,8 +2287,8 @@ fn airRem(self: *Self, inst: Air.Inst.Index) !void {
2285 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2287 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2286 const lhs = try self.resolveInst(bin_op.lhs);2288 const lhs = try self.resolveInst(bin_op.lhs);
2287 const rhs = try self.resolveInst(bin_op.rhs);2289 const rhs = try self.resolveInst(bin_op.rhs);
2288 const lhs_ty = self.air.typeOf(bin_op.lhs);2290 const lhs_ty = self.typeOf(bin_op.lhs);
2289 const rhs_ty = self.air.typeOf(bin_op.rhs);2291 const rhs_ty = self.typeOf(bin_op.rhs);
22902292
2291 // TODO add safety check2293 // TODO add safety check
22922294
...@@ -2341,8 +2343,8 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2341,8 +2343,8 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
2341 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2343 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2342 const lhs = try self.resolveInst(extra.lhs);2344 const lhs = try self.resolveInst(extra.lhs);
2343 const rhs = try self.resolveInst(extra.rhs);2345 const rhs = try self.resolveInst(extra.rhs);
2344 const lhs_ty = self.air.typeOf(extra.lhs);2346 const lhs_ty = self.typeOf(extra.lhs);
2345 const rhs_ty = self.air.typeOf(extra.rhs);2347 const rhs_ty = self.typeOf(extra.rhs);
23462348
2347 switch (lhs_ty.zigTypeTag(mod)) {2349 switch (lhs_ty.zigTypeTag(mod)) {
2348 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),2350 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
...@@ -2429,9 +2431,9 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -2429,9 +2431,9 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
2429 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;2431 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
2430 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2432 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2431 const ptr = try self.resolveInst(bin_op.lhs);2433 const ptr = try self.resolveInst(bin_op.lhs);
2432 const ptr_ty = self.air.typeOf(bin_op.lhs);2434 const ptr_ty = self.typeOf(bin_op.lhs);
2433 const len = try self.resolveInst(bin_op.rhs);2435 const len = try self.resolveInst(bin_op.rhs);
2434 const len_ty = self.air.typeOf(bin_op.rhs);2436 const len_ty = self.typeOf(bin_op.rhs);
24352437
2436 const ptr_bits = self.target.ptrBitWidth();2438 const ptr_bits = self.target.ptrBitWidth();
2437 const ptr_bytes = @divExact(ptr_bits, 8);2439 const ptr_bytes = @divExact(ptr_bits, 8);
...@@ -2453,7 +2455,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2453,7 +2455,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2453 const slice_mcv = try self.resolveInst(bin_op.lhs);2455 const slice_mcv = try self.resolveInst(bin_op.lhs);
2454 const index_mcv = try self.resolveInst(bin_op.rhs);2456 const index_mcv = try self.resolveInst(bin_op.rhs);
24552457
2456 const slice_ty = self.air.typeOf(bin_op.lhs);2458 const slice_ty = self.typeOf(bin_op.lhs);
2457 const elem_ty = slice_ty.childType();2459 const elem_ty = slice_ty.childType();
2458 const mod = self.bin_file.options.module.?;2460 const mod = self.bin_file.options.module.?;
2459 const elem_size = elem_ty.abiSize(mod);2461 const elem_size = elem_ty.abiSize(mod);
...@@ -2544,8 +2546,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -2544,8 +2546,8 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
2544 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2546 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2545 const ptr = try self.resolveInst(bin_op.lhs);2547 const ptr = try self.resolveInst(bin_op.lhs);
2546 const value = try self.resolveInst(bin_op.rhs);2548 const value = try self.resolveInst(bin_op.rhs);
2547 const ptr_ty = self.air.typeOf(bin_op.lhs);2549 const ptr_ty = self.typeOf(bin_op.lhs);
2548 const value_ty = self.air.typeOf(bin_op.rhs);2550 const value_ty = self.typeOf(bin_op.rhs);
25492551
2550 try self.store(ptr, value, ptr_ty, value_ty);2552 try self.store(ptr, value, ptr_ty, value_ty);
25512553
...@@ -2573,7 +2575,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2573,7 +2575,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2573 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2575 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2574 const mod = self.bin_file.options.module.?;2576 const mod = self.bin_file.options.module.?;
2575 const mcv = try self.resolveInst(operand);2577 const mcv = try self.resolveInst(operand);
2576 const struct_ty = self.air.typeOf(operand);2578 const struct_ty = self.typeOf(operand);
2577 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));2579 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
25782580
2579 switch (mcv) {2581 switch (mcv) {
...@@ -2659,8 +2661,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {...@@ -2659,8 +2661,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
2659fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {2661fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2660 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2662 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2661 const operand = try self.resolveInst(ty_op.operand);2663 const operand = try self.resolveInst(ty_op.operand);
2662 const operand_ty = self.air.typeOf(ty_op.operand);2664 const operand_ty = self.typeOf(ty_op.operand);
2663 const dest_ty = self.air.typeOfIndex(inst);2665 const dest_ty = self.typeOfIndex(inst);
26642666
2665 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {2667 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
2666 break :blk try self.trunc(inst, operand, operand_ty, dest_ty);2668 break :blk try self.trunc(inst, operand, operand_ty, dest_ty);
...@@ -2674,7 +2676,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {...@@ -2674,7 +2676,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
2674 const extra = self.air.extraData(Air.Try, pl_op.payload);2676 const extra = self.air.extraData(Air.Try, pl_op.payload);
2675 const body = self.air.extra[extra.end..][0..extra.data.body_len];2677 const body = self.air.extra[extra.end..][0..extra.data.body_len];
2676 const result: MCValue = result: {2678 const result: MCValue = result: {
2677 const error_union_ty = self.air.typeOf(pl_op.operand);2679 const error_union_ty = self.typeOf(pl_op.operand);
2678 const error_union = try self.resolveInst(pl_op.operand);2680 const error_union = try self.resolveInst(pl_op.operand);
2679 const is_err_result = try self.isErr(error_union_ty, error_union);2681 const is_err_result = try self.isErr(error_union_ty, error_union);
2680 const reloc = try self.condBr(is_err_result);2682 const reloc = try self.condBr(is_err_result);
...@@ -2706,7 +2708,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -2706,7 +2708,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
2706fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {2708fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2707 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2709 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2708 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2710 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2709 const error_union_ty = self.air.typeOf(ty_op.operand);2711 const error_union_ty = self.typeOf(ty_op.operand);
2710 const payload_ty = error_union_ty.errorUnionPayload();2712 const payload_ty = error_union_ty.errorUnionPayload();
2711 const mcv = try self.resolveInst(ty_op.operand);2713 const mcv = try self.resolveInst(ty_op.operand);
2712 const mod = self.bin_file.options.module.?;2714 const mod = self.bin_file.options.module.?;
...@@ -2720,7 +2722,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2720,7 +2722,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2720fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {2722fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
2721 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2723 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2722 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2724 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2723 const error_union_ty = self.air.typeOf(ty_op.operand);2725 const error_union_ty = self.typeOf(ty_op.operand);
2724 const payload_ty = error_union_ty.errorUnionPayload();2726 const payload_ty = error_union_ty.errorUnionPayload();
2725 const mod = self.bin_file.options.module.?;2727 const mod = self.bin_file.options.module.?;
2726 if (!payload_ty.hasRuntimeBits(mod)) break :result MCValue.none;2728 if (!payload_ty.hasRuntimeBits(mod)) break :result MCValue.none;
...@@ -2753,12 +2755,12 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -2753,12 +2755,12 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
2753}2755}
27542756
2755fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {2757fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
2758 const mod = self.bin_file.options.module.?;
2756 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2759 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2757 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2760 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2758 const optional_ty = self.air.typeOfIndex(inst);2761 const optional_ty = self.typeOfIndex(inst);
27592762
2760 // Optional with a zero-bit payload type is just a boolean true2763 // Optional with a zero-bit payload type is just a boolean true
2761 const mod = self.bin_file.options.module.?;
2762 if (optional_ty.abiSize(mod) == 1)2764 if (optional_ty.abiSize(mod) == 1)
2763 break :result MCValue{ .immediate = 1 };2765 break :result MCValue{ .immediate = 1 };
27642766
...@@ -2794,9 +2796,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u...@@ -2794,9 +2796,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
27942796
2795/// Use a pointer instruction as the basis for allocating stack memory.2797/// Use a pointer instruction as the basis for allocating stack memory.
2796fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {2798fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
2797 const elem_ty = self.air.typeOfIndex(inst).elemType();
2798
2799 const mod = self.bin_file.options.module.?;2799 const mod = self.bin_file.options.module.?;
2800 const elem_ty = self.typeOfIndex(inst).elemType();
2801
2800 if (!elem_ty.hasRuntimeBits(mod)) {2802 if (!elem_ty.hasRuntimeBits(mod)) {
2801 // As this stack item will never be dereferenced at runtime,2803 // As this stack item will never be dereferenced at runtime,
2802 // return the stack offset 0. Stack offset 0 will be where all2804 // return the stack offset 0. Stack offset 0 will be where all
...@@ -2814,8 +2816,8 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -2814,8 +2816,8 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
2814}2816}
28152817
2816fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {2818fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
2817 const elem_ty = self.air.typeOfIndex(inst);
2818 const mod = self.bin_file.options.module.?;2819 const mod = self.bin_file.options.module.?;
2820 const elem_ty = self.typeOfIndex(inst);
2819 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {2821 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
2820 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});2822 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
2821 };2823 };
...@@ -3406,7 +3408,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {...@@ -3406,7 +3408,7 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
3406 const block_data = self.blocks.getPtr(block).?;3408 const block_data = self.blocks.getPtr(block).?;
34073409
3408 const mod = self.bin_file.options.module.?;3410 const mod = self.bin_file.options.module.?;
3409 if (self.air.typeOf(operand).hasRuntimeBits(mod)) {3411 if (self.typeOf(operand).hasRuntimeBits(mod)) {
3410 const operand_mcv = try self.resolveInst(operand);3412 const operand_mcv = try self.resolveInst(operand);
3411 const block_mcv = block_data.mcv;3413 const block_mcv = block_data.mcv;
3412 if (block_mcv == .none) {3414 if (block_mcv == .none) {
...@@ -3415,13 +3417,13 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {...@@ -3415,13 +3417,13 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
3415 .register, .stack_offset, .memory => operand_mcv,3417 .register, .stack_offset, .memory => operand_mcv,
3416 .immediate => blk: {3418 .immediate => blk: {
3417 const new_mcv = try self.allocRegOrMem(block, true);3419 const new_mcv = try self.allocRegOrMem(block, true);
3418 try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv);3420 try self.setRegOrMem(self.typeOfIndex(block), new_mcv, operand_mcv);
3419 break :blk new_mcv;3421 break :blk new_mcv;
3420 },3422 },
3421 else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),3423 else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}),
3422 };3424 };
3423 } else {3425 } else {
3424 try self.setRegOrMem(self.air.typeOfIndex(block), block_mcv, operand_mcv);3426 try self.setRegOrMem(self.typeOfIndex(block), block_mcv, operand_mcv);
3425 }3427 }
3426 }3428 }
3427 return self.brVoid(block);3429 return self.brVoid(block);
...@@ -4549,7 +4551,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)...@@ -4549,7 +4551,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
45494551
4550fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {4552fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
4551 const mod = self.bin_file.options.module.?;4553 const mod = self.bin_file.options.module.?;
4552 const ty = self.air.typeOf(ref);4554 const ty = self.typeOf(ref);
45534555
4554 // If the type has no codegen bits, no need to store it.4556 // If the type has no codegen bits, no need to store it.
4555 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;4557 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;
...@@ -4654,7 +4656,7 @@ fn spillConditionFlagsIfOccupied(self: *Self) !void {...@@ -4654,7 +4656,7 @@ fn spillConditionFlagsIfOccupied(self: *Self) !void {
4654 else => unreachable, // mcv doesn't occupy the compare flags4656 else => unreachable, // mcv doesn't occupy the compare flags
4655 };4657 };
46564658
4657 try self.setRegOrMem(self.air.typeOfIndex(inst_to_save), new_mcv, mcv);4659 try self.setRegOrMem(self.typeOfIndex(inst_to_save), new_mcv, mcv);
4658 log.debug("spilling {d} to mcv {any}", .{ inst_to_save, new_mcv });4660 log.debug("spilling {d} to mcv {any}", .{ inst_to_save, new_mcv });
46594661
4660 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];4662 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
...@@ -4678,7 +4680,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void...@@ -4678,7 +4680,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
4678 assert(reg == reg_mcv.register);4680 assert(reg == reg_mcv.register);
4679 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];4681 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
4680 try branch.inst_table.put(self.gpa, inst, stack_mcv);4682 try branch.inst_table.put(self.gpa, inst, stack_mcv);
4681 try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);4683 try self.genSetStack(self.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv);
4682}4684}
46834685
4684fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {4686fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
...@@ -4726,7 +4728,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -4726,7 +4728,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
4726 return if (self.liveness.isUnused(inst)) .dead else result: {4728 return if (self.liveness.isUnused(inst)) .dead else result: {
4727 const mod = self.bin_file.options.module.?;4729 const mod = self.bin_file.options.module.?;
4728 const mcv = try self.resolveInst(operand);4730 const mcv = try self.resolveInst(operand);
4729 const ptr_ty = self.air.typeOf(operand);4731 const ptr_ty = self.typeOf(operand);
4730 const struct_ty = ptr_ty.childType();4732 const struct_ty = ptr_ty.childType();
4731 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));4733 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
4732 switch (mcv) {4734 switch (mcv) {
...@@ -4885,3 +4887,13 @@ fn wantSafety(self: *Self) bool {...@@ -4885,3 +4887,13 @@ fn wantSafety(self: *Self) bool {
4885 .ReleaseSmall => false,4887 .ReleaseSmall => false,
4886 };4888 };
4887}4889}
4890
4891fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
4892 const mod = self.bin_file.options.module.?;
4893 return self.air.typeOf(inst, mod.intern_pool);
4894}
4895
4896fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
4897 const mod = self.bin_file.options.module.?;
4898 return self.air.typeOfIndex(inst, mod.intern_pool);
4899}
src/arch/wasm/CodeGen.zig+127-113
...@@ -790,7 +790,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {...@@ -790,7 +790,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
790790
791 const mod = func.bin_file.base.options.module.?;791 const mod = func.bin_file.base.options.module.?;
792 const val = func.air.value(ref, mod).?;792 const val = func.air.value(ref, mod).?;
793 const ty = func.air.typeOf(ref);793 const ty = func.typeOf(ref);
794 if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) {794 if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) {
795 gop.value_ptr.* = WValue{ .none = {} };795 gop.value_ptr.* = WValue{ .none = {} };
796 return gop.value_ptr.*;796 return gop.value_ptr.*;
...@@ -1260,7 +1260,7 @@ fn genFunc(func: *CodeGen) InnerError!void {...@@ -1260,7 +1260,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
1260 // we emit an unreachable instruction to tell the stack validator that part will never be reached.1260 // we emit an unreachable instruction to tell the stack validator that part will never be reached.
1261 if (func_type.returns.len != 0 and func.air.instructions.len > 0) {1261 if (func_type.returns.len != 0 and func.air.instructions.len > 0) {
1262 const inst = @intCast(u32, func.air.instructions.len - 1);1262 const inst = @intCast(u32, func.air.instructions.len - 1);
1263 const last_inst_ty = func.air.typeOfIndex(inst);1263 const last_inst_ty = func.typeOfIndex(inst);
1264 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn()) {1264 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn()) {
1265 try func.addTag(.@"unreachable");1265 try func.addTag(.@"unreachable");
1266 }1266 }
...@@ -1541,7 +1541,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {...@@ -1541,7 +1541,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {
1541/// if it is set, to ensure the stack alignment will be set correctly.1541/// if it is set, to ensure the stack alignment will be set correctly.
1542fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {1542fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
1543 const mod = func.bin_file.base.options.module.?;1543 const mod = func.bin_file.base.options.module.?;
1544 const ptr_ty = func.air.typeOfIndex(inst);1544 const ptr_ty = func.typeOfIndex(inst);
1545 const pointee_ty = ptr_ty.childType();1545 const pointee_ty = ptr_ty.childType();
15461546
1547 if (func.initial_stack_value == .none) {1547 if (func.initial_stack_value == .none) {
...@@ -1834,6 +1834,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1834,6 +1834,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1834 return switch (air_tags[inst]) {1834 return switch (air_tags[inst]) {
1835 .constant => unreachable,1835 .constant => unreachable,
1836 .const_ty => unreachable,1836 .const_ty => unreachable,
1837 .interned => unreachable,
18371838
1838 .add => func.airBinOp(inst, .add),1839 .add => func.airBinOp(inst, .add),
1839 .add_sat => func.airSatBinOp(inst, .add),1840 .add_sat => func.airSatBinOp(inst, .add),
...@@ -2073,8 +2074,11 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2073,8 +2074,11 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2073}2074}
20742075
2075fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {2076fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2077 const mod = func.bin_file.base.options.module.?;
2078 const ip = &mod.intern_pool;
2079
2076 for (body) |inst| {2080 for (body) |inst| {
2077 if (func.liveness.isUnused(inst) and !func.air.mustLower(inst)) {2081 if (func.liveness.isUnused(inst) and !func.air.mustLower(inst, ip.*)) {
2078 continue;2082 continue;
2079 }2083 }
2080 const old_bookkeeping_value = func.air_bookkeeping;2084 const old_bookkeeping_value = func.air_bookkeeping;
...@@ -2134,8 +2138,8 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2134,8 +2138,8 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2134}2138}
21352139
2136fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2140fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2137 const child_type = func.air.typeOfIndex(inst).childType();
2138 const mod = func.bin_file.base.options.module.?;2141 const mod = func.bin_file.base.options.module.?;
2142 const child_type = func.typeOfIndex(inst).childType();
21392143
2140 var result = result: {2144 var result = result: {
2141 if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {2145 if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
...@@ -2157,7 +2161,7 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2157,7 +2161,7 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2157 const mod = func.bin_file.base.options.module.?;2161 const mod = func.bin_file.base.options.module.?;
2158 const un_op = func.air.instructions.items(.data)[inst].un_op;2162 const un_op = func.air.instructions.items(.data)[inst].un_op;
2159 const operand = try func.resolveInst(un_op);2163 const operand = try func.resolveInst(un_op);
2160 const ret_ty = func.air.typeOf(un_op).childType();2164 const ret_ty = func.typeOf(un_op).childType();
21612165
2162 const fn_info = func.decl.ty.fnInfo();2166 const fn_info = func.decl.ty.fnInfo();
2163 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {2167 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -2179,7 +2183,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2179,7 +2183,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2179 const pl_op = func.air.instructions.items(.data)[inst].pl_op;2183 const pl_op = func.air.instructions.items(.data)[inst].pl_op;
2180 const extra = func.air.extraData(Air.Call, pl_op.payload);2184 const extra = func.air.extraData(Air.Call, pl_op.payload);
2181 const args = @ptrCast([]const Air.Inst.Ref, func.air.extra[extra.end..][0..extra.data.args_len]);2185 const args = @ptrCast([]const Air.Inst.Ref, func.air.extra[extra.end..][0..extra.data.args_len]);
2182 const ty = func.air.typeOf(pl_op.operand);2186 const ty = func.typeOf(pl_op.operand);
21832187
2184 const mod = func.bin_file.base.options.module.?;2188 const mod = func.bin_file.base.options.module.?;
2185 const fn_ty = switch (ty.zigTypeTag(mod)) {2189 const fn_ty = switch (ty.zigTypeTag(mod)) {
...@@ -2228,7 +2232,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2228,7 +2232,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2228 for (args) |arg| {2232 for (args) |arg| {
2229 const arg_val = try func.resolveInst(arg);2233 const arg_val = try func.resolveInst(arg);
22302234
2231 const arg_ty = func.air.typeOf(arg);2235 const arg_ty = func.typeOf(arg);
2232 if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;2236 if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
22332237
2234 try func.lowerArg(fn_ty.fnInfo().cc, arg_ty, arg_val);2238 try func.lowerArg(fn_ty.fnInfo().cc, arg_ty, arg_val);
...@@ -2296,7 +2300,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -2296,7 +2300,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
22962300
2297 const lhs = try func.resolveInst(bin_op.lhs);2301 const lhs = try func.resolveInst(bin_op.lhs);
2298 const rhs = try func.resolveInst(bin_op.rhs);2302 const rhs = try func.resolveInst(bin_op.rhs);
2299 const ptr_ty = func.air.typeOf(bin_op.lhs);2303 const ptr_ty = func.typeOf(bin_op.lhs);
2300 const ptr_info = ptr_ty.ptrInfo().data;2304 const ptr_info = ptr_ty.ptrInfo().data;
2301 const ty = ptr_ty.childType();2305 const ty = ptr_ty.childType();
23022306
...@@ -2449,7 +2453,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2449,7 +2453,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2449 const ty_op = func.air.instructions.items(.data)[inst].ty_op;2453 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
2450 const operand = try func.resolveInst(ty_op.operand);2454 const operand = try func.resolveInst(ty_op.operand);
2451 const ty = func.air.getRefType(ty_op.ty);2455 const ty = func.air.getRefType(ty_op.ty);
2452 const ptr_ty = func.air.typeOf(ty_op.operand);2456 const ptr_ty = func.typeOf(ty_op.operand);
2453 const ptr_info = ptr_ty.ptrInfo().data;2457 const ptr_info = ptr_ty.ptrInfo().data;
24542458
2455 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return func.finishAir(inst, .none, &.{ty_op.operand});2459 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return func.finishAir(inst, .none, &.{ty_op.operand});
...@@ -2522,11 +2526,11 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu...@@ -2522,11 +2526,11 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
2522}2526}
25232527
2524fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {2528fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2529 const mod = func.bin_file.base.options.module.?;
2525 const arg_index = func.arg_index;2530 const arg_index = func.arg_index;
2526 const arg = func.args[arg_index];2531 const arg = func.args[arg_index];
2527 const cc = func.decl.ty.fnInfo().cc;2532 const cc = func.decl.ty.fnInfo().cc;
2528 const arg_ty = func.air.typeOfIndex(inst);2533 const arg_ty = func.typeOfIndex(inst);
2529 const mod = func.bin_file.base.options.module.?;
2530 if (cc == .C) {2534 if (cc == .C) {
2531 const arg_classes = abi.classifyType(arg_ty, mod);2535 const arg_classes = abi.classifyType(arg_ty, mod);
2532 for (arg_classes) |class| {2536 for (arg_classes) |class| {
...@@ -2572,8 +2576,8 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -2572,8 +2576,8 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2572 const bin_op = func.air.instructions.items(.data)[inst].bin_op;2576 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
2573 const lhs = try func.resolveInst(bin_op.lhs);2577 const lhs = try func.resolveInst(bin_op.lhs);
2574 const rhs = try func.resolveInst(bin_op.rhs);2578 const rhs = try func.resolveInst(bin_op.rhs);
2575 const lhs_ty = func.air.typeOf(bin_op.lhs);2579 const lhs_ty = func.typeOf(bin_op.lhs);
2576 const rhs_ty = func.air.typeOf(bin_op.rhs);2580 const rhs_ty = func.typeOf(bin_op.rhs);
25772581
2578 // For certain operations, such as shifting, the types are different.2582 // For certain operations, such as shifting, the types are different.
2579 // When converting this to a WebAssembly type, they *must* match to perform2583 // When converting this to a WebAssembly type, they *must* match to perform
...@@ -2770,7 +2774,7 @@ const FloatOp = enum {...@@ -2770,7 +2774,7 @@ const FloatOp = enum {
2770fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError!void {2774fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError!void {
2771 const un_op = func.air.instructions.items(.data)[inst].un_op;2775 const un_op = func.air.instructions.items(.data)[inst].un_op;
2772 const operand = try func.resolveInst(un_op);2776 const operand = try func.resolveInst(un_op);
2773 const ty = func.air.typeOf(un_op);2777 const ty = func.typeOf(un_op);
27742778
2775 const result = try (try func.floatOp(op, ty, &.{operand})).toLocal(func, ty);2779 const result = try (try func.floatOp(op, ty, &.{operand})).toLocal(func, ty);
2776 func.finishAir(inst, result, &.{un_op});2780 func.finishAir(inst, result, &.{un_op});
...@@ -2847,8 +2851,8 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -2847,8 +2851,8 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
28472851
2848 const lhs = try func.resolveInst(bin_op.lhs);2852 const lhs = try func.resolveInst(bin_op.lhs);
2849 const rhs = try func.resolveInst(bin_op.rhs);2853 const rhs = try func.resolveInst(bin_op.rhs);
2850 const lhs_ty = func.air.typeOf(bin_op.lhs);2854 const lhs_ty = func.typeOf(bin_op.lhs);
2851 const rhs_ty = func.air.typeOf(bin_op.rhs);2855 const rhs_ty = func.typeOf(bin_op.rhs);
28522856
2853 if (lhs_ty.zigTypeTag(mod) == .Vector or rhs_ty.zigTypeTag(mod) == .Vector) {2857 if (lhs_ty.zigTypeTag(mod) == .Vector or rhs_ty.zigTypeTag(mod) == .Vector) {
2854 return func.fail("TODO: Implement wrapping arithmetic for vectors", .{});2858 return func.fail("TODO: Implement wrapping arithmetic for vectors", .{});
...@@ -3387,7 +3391,7 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In...@@ -3387,7 +3391,7 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In
33873391
3388 const lhs = try func.resolveInst(bin_op.lhs);3392 const lhs = try func.resolveInst(bin_op.lhs);
3389 const rhs = try func.resolveInst(bin_op.rhs);3393 const rhs = try func.resolveInst(bin_op.rhs);
3390 const operand_ty = func.air.typeOf(bin_op.lhs);3394 const operand_ty = func.typeOf(bin_op.lhs);
3391 const result = try (try func.cmp(lhs, rhs, operand_ty, op)).toLocal(func, Type.u32); // comparison result is always 32 bits3395 const result = try (try func.cmp(lhs, rhs, operand_ty, op)).toLocal(func, Type.u32); // comparison result is always 32 bits
3392 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });3396 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
3393}3397}
...@@ -3488,7 +3492,7 @@ fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3488,7 +3492,7 @@ fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3488 const block = func.blocks.get(br.block_inst).?;3492 const block = func.blocks.get(br.block_inst).?;
34893493
3490 // if operand has codegen bits we should break with a value3494 // if operand has codegen bits we should break with a value
3491 if (func.air.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(mod)) {3495 if (func.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(mod)) {
3492 const operand = try func.resolveInst(br.operand);3496 const operand = try func.resolveInst(br.operand);
3493 try func.lowerToStack(operand);3497 try func.lowerToStack(operand);
34943498
...@@ -3509,7 +3513,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3509,7 +3513,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3509 const ty_op = func.air.instructions.items(.data)[inst].ty_op;3513 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
35103514
3511 const operand = try func.resolveInst(ty_op.operand);3515 const operand = try func.resolveInst(ty_op.operand);
3512 const operand_ty = func.air.typeOf(ty_op.operand);3516 const operand_ty = func.typeOf(ty_op.operand);
3513 const mod = func.bin_file.base.options.module.?;3517 const mod = func.bin_file.base.options.module.?;
35143518
3515 const result = result: {3519 const result = result: {
...@@ -3575,8 +3579,8 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3575,8 +3579,8 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3575 const ty_op = func.air.instructions.items(.data)[inst].ty_op;3579 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
3576 const result = result: {3580 const result = result: {
3577 const operand = try func.resolveInst(ty_op.operand);3581 const operand = try func.resolveInst(ty_op.operand);
3578 const wanted_ty = func.air.typeOfIndex(inst);3582 const wanted_ty = func.typeOfIndex(inst);
3579 const given_ty = func.air.typeOf(ty_op.operand);3583 const given_ty = func.typeOf(ty_op.operand);
3580 if (given_ty.isAnyFloat() or wanted_ty.isAnyFloat()) {3584 if (given_ty.isAnyFloat() or wanted_ty.isAnyFloat()) {
3581 const bitcast_result = try func.bitcast(wanted_ty, given_ty, operand);3585 const bitcast_result = try func.bitcast(wanted_ty, given_ty, operand);
3582 break :result try bitcast_result.toLocal(func, wanted_ty);3586 break :result try bitcast_result.toLocal(func, wanted_ty);
...@@ -3609,7 +3613,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3609,7 +3613,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3609 const extra = func.air.extraData(Air.StructField, ty_pl.payload);3613 const extra = func.air.extraData(Air.StructField, ty_pl.payload);
36103614
3611 const struct_ptr = try func.resolveInst(extra.data.struct_operand);3615 const struct_ptr = try func.resolveInst(extra.data.struct_operand);
3612 const struct_ty = func.air.typeOf(extra.data.struct_operand).childType();3616 const struct_ty = func.typeOf(extra.data.struct_operand).childType();
3613 const result = try func.structFieldPtr(inst, extra.data.struct_operand, struct_ptr, struct_ty, extra.data.field_index);3617 const result = try func.structFieldPtr(inst, extra.data.struct_operand, struct_ptr, struct_ty, extra.data.field_index);
3614 func.finishAir(inst, result, &.{extra.data.struct_operand});3618 func.finishAir(inst, result, &.{extra.data.struct_operand});
3615}3619}
...@@ -3617,7 +3621,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3617,7 +3621,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3617fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void {3621fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void {
3618 const ty_op = func.air.instructions.items(.data)[inst].ty_op;3622 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
3619 const struct_ptr = try func.resolveInst(ty_op.operand);3623 const struct_ptr = try func.resolveInst(ty_op.operand);
3620 const struct_ty = func.air.typeOf(ty_op.operand).childType();3624 const struct_ty = func.typeOf(ty_op.operand).childType();
36213625
3622 const result = try func.structFieldPtr(inst, ty_op.operand, struct_ptr, struct_ty, index);3626 const result = try func.structFieldPtr(inst, ty_op.operand, struct_ptr, struct_ty, index);
3623 func.finishAir(inst, result, &.{ty_op.operand});3627 func.finishAir(inst, result, &.{ty_op.operand});
...@@ -3632,7 +3636,7 @@ fn structFieldPtr(...@@ -3632,7 +3636,7 @@ fn structFieldPtr(
3632 index: u32,3636 index: u32,
3633) InnerError!WValue {3637) InnerError!WValue {
3634 const mod = func.bin_file.base.options.module.?;3638 const mod = func.bin_file.base.options.module.?;
3635 const result_ty = func.air.typeOfIndex(inst);3639 const result_ty = func.typeOfIndex(inst);
3636 const offset = switch (struct_ty.containerLayout()) {3640 const offset = switch (struct_ty.containerLayout()) {
3637 .Packed => switch (struct_ty.zigTypeTag(mod)) {3641 .Packed => switch (struct_ty.zigTypeTag(mod)) {
3638 .Struct => offset: {3642 .Struct => offset: {
...@@ -3663,7 +3667,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3663,7 +3667,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3663 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;3667 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
3664 const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data;3668 const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data;
36653669
3666 const struct_ty = func.air.typeOf(struct_field.struct_operand);3670 const struct_ty = func.typeOf(struct_field.struct_operand);
3667 const operand = try func.resolveInst(struct_field.struct_operand);3671 const operand = try func.resolveInst(struct_field.struct_operand);
3668 const field_index = struct_field.field_index;3672 const field_index = struct_field.field_index;
3669 const field_ty = struct_ty.structFieldType(field_index);3673 const field_ty = struct_ty.structFieldType(field_index);
...@@ -3762,7 +3766,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3762,7 +3766,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3762 const blocktype = wasm.block_empty;3766 const blocktype = wasm.block_empty;
3763 const pl_op = func.air.instructions.items(.data)[inst].pl_op;3767 const pl_op = func.air.instructions.items(.data)[inst].pl_op;
3764 const target = try func.resolveInst(pl_op.operand);3768 const target = try func.resolveInst(pl_op.operand);
3765 const target_ty = func.air.typeOf(pl_op.operand);3769 const target_ty = func.typeOf(pl_op.operand);
3766 const switch_br = func.air.extraData(Air.SwitchBr, pl_op.payload);3770 const switch_br = func.air.extraData(Air.SwitchBr, pl_op.payload);
3767 const liveness = try func.liveness.getSwitchBr(func.gpa, inst, switch_br.data.cases_len + 1);3771 const liveness = try func.liveness.getSwitchBr(func.gpa, inst, switch_br.data.cases_len + 1);
3768 defer func.gpa.free(liveness.deaths);3772 defer func.gpa.free(liveness.deaths);
...@@ -3940,7 +3944,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro...@@ -3940,7 +3944,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
3940 const mod = func.bin_file.base.options.module.?;3944 const mod = func.bin_file.base.options.module.?;
3941 const un_op = func.air.instructions.items(.data)[inst].un_op;3945 const un_op = func.air.instructions.items(.data)[inst].un_op;
3942 const operand = try func.resolveInst(un_op);3946 const operand = try func.resolveInst(un_op);
3943 const err_union_ty = func.air.typeOf(un_op);3947 const err_union_ty = func.typeOf(un_op);
3944 const pl_ty = err_union_ty.errorUnionPayload();3948 const pl_ty = err_union_ty.errorUnionPayload();
39453949
3946 const result = result: {3950 const result = result: {
...@@ -3976,7 +3980,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo...@@ -3976,7 +3980,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
3976 const ty_op = func.air.instructions.items(.data)[inst].ty_op;3980 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
39773981
3978 const operand = try func.resolveInst(ty_op.operand);3982 const operand = try func.resolveInst(ty_op.operand);
3979 const op_ty = func.air.typeOf(ty_op.operand);3983 const op_ty = func.typeOf(ty_op.operand);
3980 const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;3984 const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;
3981 const payload_ty = err_ty.errorUnionPayload();3985 const payload_ty = err_ty.errorUnionPayload();
39823986
...@@ -4004,7 +4008,7 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)...@@ -4004,7 +4008,7 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
4004 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4008 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
40054009
4006 const operand = try func.resolveInst(ty_op.operand);4010 const operand = try func.resolveInst(ty_op.operand);
4007 const op_ty = func.air.typeOf(ty_op.operand);4011 const op_ty = func.typeOf(ty_op.operand);
4008 const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;4012 const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;
4009 const payload_ty = err_ty.errorUnionPayload();4013 const payload_ty = err_ty.errorUnionPayload();
40104014
...@@ -4028,9 +4032,9 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void...@@ -4028,9 +4032,9 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
4028 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4032 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
40294033
4030 const operand = try func.resolveInst(ty_op.operand);4034 const operand = try func.resolveInst(ty_op.operand);
4031 const err_ty = func.air.typeOfIndex(inst);4035 const err_ty = func.typeOfIndex(inst);
40324036
4033 const pl_ty = func.air.typeOf(ty_op.operand);4037 const pl_ty = func.typeOf(ty_op.operand);
4034 const result = result: {4038 const result = result: {
4035 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {4039 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4036 break :result func.reuseOperand(ty_op.operand, operand);4040 break :result func.reuseOperand(ty_op.operand, operand);
...@@ -4082,7 +4086,7 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4082,7 +4086,7 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40824086
4083 const ty = func.air.getRefType(ty_op.ty);4087 const ty = func.air.getRefType(ty_op.ty);
4084 const operand = try func.resolveInst(ty_op.operand);4088 const operand = try func.resolveInst(ty_op.operand);
4085 const operand_ty = func.air.typeOf(ty_op.operand);4089 const operand_ty = func.typeOf(ty_op.operand);
4086 const mod = func.bin_file.base.options.module.?;4090 const mod = func.bin_file.base.options.module.?;
4087 if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) {4091 if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) {
4088 return func.fail("todo Wasm intcast for vectors", .{});4092 return func.fail("todo Wasm intcast for vectors", .{});
...@@ -4155,7 +4159,7 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind:...@@ -4155,7 +4159,7 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind:
4155 const un_op = func.air.instructions.items(.data)[inst].un_op;4159 const un_op = func.air.instructions.items(.data)[inst].un_op;
4156 const operand = try func.resolveInst(un_op);4160 const operand = try func.resolveInst(un_op);
41574161
4158 const op_ty = func.air.typeOf(un_op);4162 const op_ty = func.typeOf(un_op);
4159 const optional_ty = if (op_kind == .ptr) op_ty.childType() else op_ty;4163 const optional_ty = if (op_kind == .ptr) op_ty.childType() else op_ty;
4160 const is_null = try func.isNull(operand, optional_ty, opcode);4164 const is_null = try func.isNull(operand, optional_ty, opcode);
4161 const result = try is_null.toLocal(func, optional_ty);4165 const result = try is_null.toLocal(func, optional_ty);
...@@ -4196,8 +4200,8 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod...@@ -4196,8 +4200,8 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod
4196fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4200fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4197 const mod = func.bin_file.base.options.module.?;4201 const mod = func.bin_file.base.options.module.?;
4198 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4202 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
4199 const opt_ty = func.air.typeOf(ty_op.operand);4203 const opt_ty = func.typeOf(ty_op.operand);
4200 const payload_ty = func.air.typeOfIndex(inst);4204 const payload_ty = func.typeOfIndex(inst);
4201 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4205 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4202 return func.finishAir(inst, .none, &.{ty_op.operand});4206 return func.finishAir(inst, .none, &.{ty_op.operand});
4203 }4207 }
...@@ -4219,7 +4223,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4219,7 +4223,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4219fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4223fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4220 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4224 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
4221 const operand = try func.resolveInst(ty_op.operand);4225 const operand = try func.resolveInst(ty_op.operand);
4222 const opt_ty = func.air.typeOf(ty_op.operand).childType();4226 const opt_ty = func.typeOf(ty_op.operand).childType();
42234227
4224 const mod = func.bin_file.base.options.module.?;4228 const mod = func.bin_file.base.options.module.?;
4225 const result = result: {4229 const result = result: {
...@@ -4238,7 +4242,7 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi...@@ -4238,7 +4242,7 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
4238 const mod = func.bin_file.base.options.module.?;4242 const mod = func.bin_file.base.options.module.?;
4239 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4243 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
4240 const operand = try func.resolveInst(ty_op.operand);4244 const operand = try func.resolveInst(ty_op.operand);
4241 const opt_ty = func.air.typeOf(ty_op.operand).childType();4245 const opt_ty = func.typeOf(ty_op.operand).childType();
4242 var buf: Type.Payload.ElemType = undefined;4246 var buf: Type.Payload.ElemType = undefined;
4243 const payload_ty = opt_ty.optionalChild(&buf);4247 const payload_ty = opt_ty.optionalChild(&buf);
4244 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4248 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -4263,7 +4267,7 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi...@@ -4263,7 +4267,7 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
42634267
4264fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4268fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4265 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4269 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
4266 const payload_ty = func.air.typeOf(ty_op.operand);4270 const payload_ty = func.typeOf(ty_op.operand);
4267 const mod = func.bin_file.base.options.module.?;4271 const mod = func.bin_file.base.options.module.?;
42684272
4269 const result = result: {4273 const result = result: {
...@@ -4276,7 +4280,7 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4276,7 +4280,7 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4276 }4280 }
42774281
4278 const operand = try func.resolveInst(ty_op.operand);4282 const operand = try func.resolveInst(ty_op.operand);
4279 const op_ty = func.air.typeOfIndex(inst);4283 const op_ty = func.typeOfIndex(inst);
4280 if (op_ty.optionalReprIsPayload(mod)) {4284 if (op_ty.optionalReprIsPayload(mod)) {
4281 break :result func.reuseOperand(ty_op.operand, operand);4285 break :result func.reuseOperand(ty_op.operand, operand);
4282 }4286 }
...@@ -4304,7 +4308,7 @@ fn airSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4304,7 +4308,7 @@ fn airSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
43044308
4305 const lhs = try func.resolveInst(bin_op.lhs);4309 const lhs = try func.resolveInst(bin_op.lhs);
4306 const rhs = try func.resolveInst(bin_op.rhs);4310 const rhs = try func.resolveInst(bin_op.rhs);
4307 const slice_ty = func.air.typeOfIndex(inst);4311 const slice_ty = func.typeOfIndex(inst);
43084312
4309 const slice = try func.allocStack(slice_ty);4313 const slice = try func.allocStack(slice_ty);
4310 try func.store(slice, lhs, Type.usize, 0);4314 try func.store(slice, lhs, Type.usize, 0);
...@@ -4323,7 +4327,7 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4323,7 +4327,7 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4323fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4327fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4324 const bin_op = func.air.instructions.items(.data)[inst].bin_op;4328 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
43254329
4326 const slice_ty = func.air.typeOf(bin_op.lhs);4330 const slice_ty = func.typeOf(bin_op.lhs);
4327 const slice = try func.resolveInst(bin_op.lhs);4331 const slice = try func.resolveInst(bin_op.lhs);
4328 const index = try func.resolveInst(bin_op.rhs);4332 const index = try func.resolveInst(bin_op.rhs);
4329 const elem_ty = slice_ty.childType();4333 const elem_ty = slice_ty.childType();
...@@ -4395,7 +4399,7 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4395,7 +4399,7 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
43954399
4396 const operand = try func.resolveInst(ty_op.operand);4400 const operand = try func.resolveInst(ty_op.operand);
4397 const wanted_ty = func.air.getRefType(ty_op.ty);4401 const wanted_ty = func.air.getRefType(ty_op.ty);
4398 const op_ty = func.air.typeOf(ty_op.operand);4402 const op_ty = func.typeOf(ty_op.operand);
43994403
4400 const result = try func.trunc(operand, wanted_ty, op_ty);4404 const result = try func.trunc(operand, wanted_ty, op_ty);
4401 func.finishAir(inst, try result.toLocal(func, wanted_ty), &.{ty_op.operand});4405 func.finishAir(inst, try result.toLocal(func, wanted_ty), &.{ty_op.operand});
...@@ -4432,7 +4436,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4432,7 +4436,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4432 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4436 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
44334437
4434 const operand = try func.resolveInst(ty_op.operand);4438 const operand = try func.resolveInst(ty_op.operand);
4435 const array_ty = func.air.typeOf(ty_op.operand).childType();4439 const array_ty = func.typeOf(ty_op.operand).childType();
4436 const slice_ty = func.air.getRefType(ty_op.ty);4440 const slice_ty = func.air.getRefType(ty_op.ty);
44374441
4438 // create a slice on the stack4442 // create a slice on the stack
...@@ -4453,7 +4457,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4453,7 +4457,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4453fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4457fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4454 const un_op = func.air.instructions.items(.data)[inst].un_op;4458 const un_op = func.air.instructions.items(.data)[inst].un_op;
4455 const operand = try func.resolveInst(un_op);4459 const operand = try func.resolveInst(un_op);
4456 const ptr_ty = func.air.typeOf(un_op);4460 const ptr_ty = func.typeOf(un_op);
4457 const result = if (ptr_ty.isSlice())4461 const result = if (ptr_ty.isSlice())
4458 try func.slicePtr(operand)4462 try func.slicePtr(operand)
4459 else switch (operand) {4463 else switch (operand) {
...@@ -4467,7 +4471,7 @@ fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4467,7 +4471,7 @@ fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4467fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4471fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4468 const bin_op = func.air.instructions.items(.data)[inst].bin_op;4472 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
44694473
4470 const ptr_ty = func.air.typeOf(bin_op.lhs);4474 const ptr_ty = func.typeOf(bin_op.lhs);
4471 const ptr = try func.resolveInst(bin_op.lhs);4475 const ptr = try func.resolveInst(bin_op.lhs);
4472 const index = try func.resolveInst(bin_op.rhs);4476 const index = try func.resolveInst(bin_op.rhs);
4473 const elem_ty = ptr_ty.childType();4477 const elem_ty = ptr_ty.childType();
...@@ -4505,7 +4509,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4505,7 +4509,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4505 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;4509 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
4506 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;4510 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
45074511
4508 const ptr_ty = func.air.typeOf(bin_op.lhs);4512 const ptr_ty = func.typeOf(bin_op.lhs);
4509 const elem_ty = func.air.getRefType(ty_pl.ty).childType();4513 const elem_ty = func.air.getRefType(ty_pl.ty).childType();
4510 const mod = func.bin_file.base.options.module.?;4514 const mod = func.bin_file.base.options.module.?;
4511 const elem_size = elem_ty.abiSize(mod);4515 const elem_size = elem_ty.abiSize(mod);
...@@ -4538,7 +4542,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -4538,7 +4542,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
45384542
4539 const ptr = try func.resolveInst(bin_op.lhs);4543 const ptr = try func.resolveInst(bin_op.lhs);
4540 const offset = try func.resolveInst(bin_op.rhs);4544 const offset = try func.resolveInst(bin_op.rhs);
4541 const ptr_ty = func.air.typeOf(bin_op.lhs);4545 const ptr_ty = func.typeOf(bin_op.lhs);
4542 const pointee_ty = switch (ptr_ty.ptrSize()) {4546 const pointee_ty = switch (ptr_ty.ptrSize()) {
4543 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type4547 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type
4544 else => ptr_ty.childType(),4548 else => ptr_ty.childType(),
...@@ -4568,7 +4572,7 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void...@@ -4568,7 +4572,7 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
4568 const bin_op = func.air.instructions.items(.data)[inst].bin_op;4572 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
45694573
4570 const ptr = try func.resolveInst(bin_op.lhs);4574 const ptr = try func.resolveInst(bin_op.lhs);
4571 const ptr_ty = func.air.typeOf(bin_op.lhs);4575 const ptr_ty = func.typeOf(bin_op.lhs);
4572 const value = try func.resolveInst(bin_op.rhs);4576 const value = try func.resolveInst(bin_op.rhs);
4573 const len = switch (ptr_ty.ptrSize()) {4577 const len = switch (ptr_ty.ptrSize()) {
4574 .Slice => try func.sliceLen(ptr),4578 .Slice => try func.sliceLen(ptr),
...@@ -4683,7 +4687,7 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue...@@ -4683,7 +4687,7 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
4683fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4687fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4684 const bin_op = func.air.instructions.items(.data)[inst].bin_op;4688 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
46854689
4686 const array_ty = func.air.typeOf(bin_op.lhs);4690 const array_ty = func.typeOf(bin_op.lhs);
4687 const array = try func.resolveInst(bin_op.lhs);4691 const array = try func.resolveInst(bin_op.lhs);
4688 const index = try func.resolveInst(bin_op.rhs);4692 const index = try func.resolveInst(bin_op.rhs);
4689 const elem_ty = array_ty.childType();4693 const elem_ty = array_ty.childType();
...@@ -4750,12 +4754,12 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4750,12 +4754,12 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4750}4754}
47514755
4752fn airFloatToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4756fn airFloatToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4757 const mod = func.bin_file.base.options.module.?;
4753 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4758 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
47544759
4755 const operand = try func.resolveInst(ty_op.operand);4760 const operand = try func.resolveInst(ty_op.operand);
4756 const dest_ty = func.air.typeOfIndex(inst);4761 const dest_ty = func.typeOfIndex(inst);
4757 const op_ty = func.air.typeOf(ty_op.operand);4762 const op_ty = func.typeOf(ty_op.operand);
4758 const mod = func.bin_file.base.options.module.?;
47594763
4760 if (op_ty.abiSize(mod) > 8) {4764 if (op_ty.abiSize(mod) > 8) {
4761 return func.fail("TODO: floatToInt for integers/floats with bitsize larger than 64 bits", .{});4765 return func.fail("TODO: floatToInt for integers/floats with bitsize larger than 64 bits", .{});
...@@ -4775,12 +4779,12 @@ fn airFloatToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4775,12 +4779,12 @@ fn airFloatToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4775}4779}
47764780
4777fn airIntToFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4781fn airIntToFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4782 const mod = func.bin_file.base.options.module.?;
4778 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4783 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
47794784
4780 const operand = try func.resolveInst(ty_op.operand);4785 const operand = try func.resolveInst(ty_op.operand);
4781 const dest_ty = func.air.typeOfIndex(inst);4786 const dest_ty = func.typeOfIndex(inst);
4782 const op_ty = func.air.typeOf(ty_op.operand);4787 const op_ty = func.typeOf(ty_op.operand);
4783 const mod = func.bin_file.base.options.module.?;
47844788
4785 if (op_ty.abiSize(mod) > 8) {4789 if (op_ty.abiSize(mod) > 8) {
4786 return func.fail("TODO: intToFloat for integers/floats with bitsize larger than 64 bits", .{});4790 return func.fail("TODO: intToFloat for integers/floats with bitsize larger than 64 bits", .{});
...@@ -4804,7 +4808,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4804,7 +4808,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4804 const mod = func.bin_file.base.options.module.?;4808 const mod = func.bin_file.base.options.module.?;
4805 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4809 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
4806 const operand = try func.resolveInst(ty_op.operand);4810 const operand = try func.resolveInst(ty_op.operand);
4807 const ty = func.air.typeOfIndex(inst);4811 const ty = func.typeOfIndex(inst);
4808 const elem_ty = ty.childType();4812 const elem_ty = ty.childType();
48094813
4810 if (determineSimdStoreStrategy(ty, mod) == .direct) blk: {4814 if (determineSimdStoreStrategy(ty, mod) == .direct) blk: {
...@@ -4881,7 +4885,7 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4881,7 +4885,7 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48814885
4882fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4886fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4883 const mod = func.bin_file.base.options.module.?;4887 const mod = func.bin_file.base.options.module.?;
4884 const inst_ty = func.air.typeOfIndex(inst);4888 const inst_ty = func.typeOfIndex(inst);
4885 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;4889 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
4886 const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data;4890 const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data;
48874891
...@@ -4894,7 +4898,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4894,7 +4898,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4894 const elem_size = child_ty.abiSize(mod);4898 const elem_size = child_ty.abiSize(mod);
48954899
4896 // TODO: One of them could be by ref; handle in loop4900 // TODO: One of them could be by ref; handle in loop
4897 if (isByRef(func.air.typeOf(extra.a), mod) or isByRef(inst_ty, mod)) {4901 if (isByRef(func.typeOf(extra.a), mod) or isByRef(inst_ty, mod)) {
4898 const result = try func.allocStack(inst_ty);4902 const result = try func.allocStack(inst_ty);
48994903
4900 for (0..mask_len) |index| {4904 for (0..mask_len) |index| {
...@@ -4951,11 +4955,11 @@ fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4951,11 +4955,11 @@ fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4951}4955}
49524956
4953fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4957fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4958 const mod = func.bin_file.base.options.module.?;
4954 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;4959 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
4955 const result_ty = func.air.typeOfIndex(inst);4960 const result_ty = func.typeOfIndex(inst);
4956 const len = @intCast(usize, result_ty.arrayLen());4961 const len = @intCast(usize, result_ty.arrayLen());
4957 const elements = @ptrCast([]const Air.Inst.Ref, func.air.extra[ty_pl.payload..][0..len]);4962 const elements = @ptrCast([]const Air.Inst.Ref, func.air.extra[ty_pl.payload..][0..len]);
4958 const mod = func.bin_file.base.options.module.?;
49594963
4960 const result: WValue = result_value: {4964 const result: WValue = result_value: {
4961 switch (result_ty.zigTypeTag(mod)) {4965 switch (result_ty.zigTypeTag(mod)) {
...@@ -5085,7 +5089,7 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5085,7 +5089,7 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5085 const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data;5089 const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data;
50865090
5087 const result = result: {5091 const result = result: {
5088 const union_ty = func.air.typeOfIndex(inst);5092 const union_ty = func.typeOfIndex(inst);
5089 const layout = union_ty.unionGetLayout(mod);5093 const layout = union_ty.unionGetLayout(mod);
5090 const union_obj = union_ty.cast(Type.Payload.Union).?.data;5094 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
5091 const field = union_obj.fields.values()[extra.field_index];5095 const field = union_obj.fields.values()[extra.field_index];
...@@ -5164,7 +5168,7 @@ fn airPrefetch(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5164,7 +5168,7 @@ fn airPrefetch(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5164fn airWasmMemorySize(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5168fn airWasmMemorySize(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5165 const pl_op = func.air.instructions.items(.data)[inst].pl_op;5169 const pl_op = func.air.instructions.items(.data)[inst].pl_op;
51665170
5167 const result = try func.allocLocal(func.air.typeOfIndex(inst));5171 const result = try func.allocLocal(func.typeOfIndex(inst));
5168 try func.addLabel(.memory_size, pl_op.payload);5172 try func.addLabel(.memory_size, pl_op.payload);
5169 try func.addLabel(.local_set, result.local.value);5173 try func.addLabel(.local_set, result.local.value);
5170 func.finishAir(inst, result, &.{pl_op.operand});5174 func.finishAir(inst, result, &.{pl_op.operand});
...@@ -5174,7 +5178,7 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {...@@ -5174,7 +5178,7 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {
5174 const pl_op = func.air.instructions.items(.data)[inst].pl_op;5178 const pl_op = func.air.instructions.items(.data)[inst].pl_op;
51755179
5176 const operand = try func.resolveInst(pl_op.operand);5180 const operand = try func.resolveInst(pl_op.operand);
5177 const result = try func.allocLocal(func.air.typeOfIndex(inst));5181 const result = try func.allocLocal(func.typeOfIndex(inst));
5178 try func.emitWValue(operand);5182 try func.emitWValue(operand);
5179 try func.addLabel(.memory_grow, pl_op.payload);5183 try func.addLabel(.memory_grow, pl_op.payload);
5180 try func.addLabel(.local_set, result.local.value);5184 try func.addLabel(.local_set, result.local.value);
...@@ -5263,8 +5267,8 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std...@@ -5263,8 +5267,8 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
5263fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5267fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5264 const mod = func.bin_file.base.options.module.?;5268 const mod = func.bin_file.base.options.module.?;
5265 const bin_op = func.air.instructions.items(.data)[inst].bin_op;5269 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
5266 const un_ty = func.air.typeOf(bin_op.lhs).childType();5270 const un_ty = func.typeOf(bin_op.lhs).childType();
5267 const tag_ty = func.air.typeOf(bin_op.rhs);5271 const tag_ty = func.typeOf(bin_op.rhs);
5268 const layout = un_ty.unionGetLayout(mod);5272 const layout = un_ty.unionGetLayout(mod);
5269 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });5273 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
52705274
...@@ -5288,8 +5292,8 @@ fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5288,8 +5292,8 @@ fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5288 const mod = func.bin_file.base.options.module.?;5292 const mod = func.bin_file.base.options.module.?;
5289 const ty_op = func.air.instructions.items(.data)[inst].ty_op;5293 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
52905294
5291 const un_ty = func.air.typeOf(ty_op.operand);5295 const un_ty = func.typeOf(ty_op.operand);
5292 const tag_ty = func.air.typeOfIndex(inst);5296 const tag_ty = func.typeOfIndex(inst);
5293 const layout = un_ty.unionGetLayout(mod);5297 const layout = un_ty.unionGetLayout(mod);
5294 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand});5298 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand});
52955299
...@@ -5307,9 +5311,9 @@ fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5307,9 +5311,9 @@ fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5307fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5311fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5308 const ty_op = func.air.instructions.items(.data)[inst].ty_op;5312 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
53095313
5310 const dest_ty = func.air.typeOfIndex(inst);5314 const dest_ty = func.typeOfIndex(inst);
5311 const operand = try func.resolveInst(ty_op.operand);5315 const operand = try func.resolveInst(ty_op.operand);
5312 const extended = try func.fpext(operand, func.air.typeOf(ty_op.operand), dest_ty);5316 const extended = try func.fpext(operand, func.typeOf(ty_op.operand), dest_ty);
5313 const result = try extended.toLocal(func, dest_ty);5317 const result = try extended.toLocal(func, dest_ty);
5314 func.finishAir(inst, result, &.{ty_op.operand});5318 func.finishAir(inst, result, &.{ty_op.operand});
5315}5319}
...@@ -5352,9 +5356,9 @@ fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!...@@ -5352,9 +5356,9 @@ fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!
5352fn airFptrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5356fn airFptrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5353 const ty_op = func.air.instructions.items(.data)[inst].ty_op;5357 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
53545358
5355 const dest_ty = func.air.typeOfIndex(inst);5359 const dest_ty = func.typeOfIndex(inst);
5356 const operand = try func.resolveInst(ty_op.operand);5360 const operand = try func.resolveInst(ty_op.operand);
5357 const truncated = try func.fptrunc(operand, func.air.typeOf(ty_op.operand), dest_ty);5361 const truncated = try func.fptrunc(operand, func.typeOf(ty_op.operand), dest_ty);
5358 const result = try truncated.toLocal(func, dest_ty);5362 const result = try truncated.toLocal(func, dest_ty);
5359 func.finishAir(inst, result, &.{ty_op.operand});5363 func.finishAir(inst, result, &.{ty_op.operand});
5360}5364}
...@@ -5393,7 +5397,7 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi...@@ -5393,7 +5397,7 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
5393 const mod = func.bin_file.base.options.module.?;5397 const mod = func.bin_file.base.options.module.?;
5394 const ty_op = func.air.instructions.items(.data)[inst].ty_op;5398 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
53955399
5396 const err_set_ty = func.air.typeOf(ty_op.operand).childType();5400 const err_set_ty = func.typeOf(ty_op.operand).childType();
5397 const payload_ty = err_set_ty.errorUnionPayload();5401 const payload_ty = err_set_ty.errorUnionPayload();
5398 const operand = try func.resolveInst(ty_op.operand);5402 const operand = try func.resolveInst(ty_op.operand);
53995403
...@@ -5448,10 +5452,10 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5448,10 +5452,10 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5448 const mod = func.bin_file.base.options.module.?;5452 const mod = func.bin_file.base.options.module.?;
5449 const bin_op = func.air.instructions.items(.data)[inst].bin_op;5453 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
5450 const dst = try func.resolveInst(bin_op.lhs);5454 const dst = try func.resolveInst(bin_op.lhs);
5451 const dst_ty = func.air.typeOf(bin_op.lhs);5455 const dst_ty = func.typeOf(bin_op.lhs);
5452 const ptr_elem_ty = dst_ty.childType();5456 const ptr_elem_ty = dst_ty.childType();
5453 const src = try func.resolveInst(bin_op.rhs);5457 const src = try func.resolveInst(bin_op.rhs);
5454 const src_ty = func.air.typeOf(bin_op.rhs);5458 const src_ty = func.typeOf(bin_op.rhs);
5455 const len = switch (dst_ty.ptrSize()) {5459 const len = switch (dst_ty.ptrSize()) {
5456 .Slice => blk: {5460 .Slice => blk: {
5457 const slice_len = try func.sliceLen(dst);5461 const slice_len = try func.sliceLen(dst);
...@@ -5485,12 +5489,12 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5485,12 +5489,12 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5485}5489}
54865490
5487fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5491fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5492 const mod = func.bin_file.base.options.module.?;
5488 const ty_op = func.air.instructions.items(.data)[inst].ty_op;5493 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
54895494
5490 const operand = try func.resolveInst(ty_op.operand);5495 const operand = try func.resolveInst(ty_op.operand);
5491 const op_ty = func.air.typeOf(ty_op.operand);5496 const op_ty = func.typeOf(ty_op.operand);
5492 const result_ty = func.air.typeOfIndex(inst);5497 const result_ty = func.typeOfIndex(inst);
5493 const mod = func.bin_file.base.options.module.?;
54945498
5495 if (op_ty.zigTypeTag(mod) == .Vector) {5499 if (op_ty.zigTypeTag(mod) == .Vector) {
5496 return func.fail("TODO: Implement @popCount for vectors", .{});5500 return func.fail("TODO: Implement @popCount for vectors", .{});
...@@ -5585,7 +5589,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro...@@ -5585,7 +5589,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
55855589
5586 const lhs_op = try func.resolveInst(extra.lhs);5590 const lhs_op = try func.resolveInst(extra.lhs);
5587 const rhs_op = try func.resolveInst(extra.rhs);5591 const rhs_op = try func.resolveInst(extra.rhs);
5588 const lhs_ty = func.air.typeOf(extra.lhs);5592 const lhs_ty = func.typeOf(extra.lhs);
5589 const mod = func.bin_file.base.options.module.?;5593 const mod = func.bin_file.base.options.module.?;
55905594
5591 if (lhs_ty.zigTypeTag(mod) == .Vector) {5595 if (lhs_ty.zigTypeTag(mod) == .Vector) {
...@@ -5599,7 +5603,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro...@@ -5599,7 +5603,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
5599 };5603 };
56005604
5601 if (wasm_bits == 128) {5605 if (wasm_bits == 128) {
5602 const result = try func.addSubWithOverflowBigInt(lhs_op, rhs_op, lhs_ty, func.air.typeOfIndex(inst), op);5606 const result = try func.addSubWithOverflowBigInt(lhs_op, rhs_op, lhs_ty, func.typeOfIndex(inst), op);
5603 return func.finishAir(inst, result, &.{ extra.lhs, extra.rhs });5607 return func.finishAir(inst, result, &.{ extra.lhs, extra.rhs });
5604 }5608 }
56055609
...@@ -5649,7 +5653,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro...@@ -5649,7 +5653,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
5649 var overflow_local = try overflow_bit.toLocal(func, Type.u32);5653 var overflow_local = try overflow_bit.toLocal(func, Type.u32);
5650 defer overflow_local.free(func);5654 defer overflow_local.free(func);
56515655
5652 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));5656 const result_ptr = try func.allocStack(func.typeOfIndex(inst));
5653 try func.store(result_ptr, result, lhs_ty, 0);5657 try func.store(result_ptr, result, lhs_ty, 0);
5654 const offset = @intCast(u32, lhs_ty.abiSize(mod));5658 const offset = @intCast(u32, lhs_ty.abiSize(mod));
5655 try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);5659 try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);
...@@ -5729,8 +5733,8 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5729,8 +5733,8 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57295733
5730 const lhs = try func.resolveInst(extra.lhs);5734 const lhs = try func.resolveInst(extra.lhs);
5731 const rhs = try func.resolveInst(extra.rhs);5735 const rhs = try func.resolveInst(extra.rhs);
5732 const lhs_ty = func.air.typeOf(extra.lhs);5736 const lhs_ty = func.typeOf(extra.lhs);
5733 const rhs_ty = func.air.typeOf(extra.rhs);5737 const rhs_ty = func.typeOf(extra.rhs);
57345738
5735 if (lhs_ty.zigTypeTag(mod) == .Vector) {5739 if (lhs_ty.zigTypeTag(mod) == .Vector) {
5736 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});5740 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
...@@ -5771,7 +5775,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5771,7 +5775,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5771 var overflow_local = try overflow_bit.toLocal(func, Type.initTag(.u1));5775 var overflow_local = try overflow_bit.toLocal(func, Type.initTag(.u1));
5772 defer overflow_local.free(func);5776 defer overflow_local.free(func);
57735777
5774 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));5778 const result_ptr = try func.allocStack(func.typeOfIndex(inst));
5775 try func.store(result_ptr, result, lhs_ty, 0);5779 try func.store(result_ptr, result, lhs_ty, 0);
5776 const offset = @intCast(u32, lhs_ty.abiSize(mod));5780 const offset = @intCast(u32, lhs_ty.abiSize(mod));
5777 try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);5781 try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);
...@@ -5785,7 +5789,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5785,7 +5789,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57855789
5786 const lhs = try func.resolveInst(extra.lhs);5790 const lhs = try func.resolveInst(extra.lhs);
5787 const rhs = try func.resolveInst(extra.rhs);5791 const rhs = try func.resolveInst(extra.rhs);
5788 const lhs_ty = func.air.typeOf(extra.lhs);5792 const lhs_ty = func.typeOf(extra.lhs);
5789 const mod = func.bin_file.base.options.module.?;5793 const mod = func.bin_file.base.options.module.?;
57905794
5791 if (lhs_ty.zigTypeTag(mod) == .Vector) {5795 if (lhs_ty.zigTypeTag(mod) == .Vector) {
...@@ -5946,7 +5950,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5946,7 +5950,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5946 var bin_op_local = try bin_op.toLocal(func, lhs_ty);5950 var bin_op_local = try bin_op.toLocal(func, lhs_ty);
5947 defer bin_op_local.free(func);5951 defer bin_op_local.free(func);
59485952
5949 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));5953 const result_ptr = try func.allocStack(func.typeOfIndex(inst));
5950 try func.store(result_ptr, bin_op_local, lhs_ty, 0);5954 try func.store(result_ptr, bin_op_local, lhs_ty, 0);
5951 const offset = @intCast(u32, lhs_ty.abiSize(mod));5955 const offset = @intCast(u32, lhs_ty.abiSize(mod));
5952 try func.store(result_ptr, overflow_bit, Type.initTag(.u1), offset);5956 try func.store(result_ptr, overflow_bit, Type.initTag(.u1), offset);
...@@ -5955,10 +5959,10 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5955,10 +5959,10 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5955}5959}
59565960
5957fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerError!void {5961fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerError!void {
5962 const mod = func.bin_file.base.options.module.?;
5958 const bin_op = func.air.instructions.items(.data)[inst].bin_op;5963 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
59595964
5960 const ty = func.air.typeOfIndex(inst);5965 const ty = func.typeOfIndex(inst);
5961 const mod = func.bin_file.base.options.module.?;
5962 if (ty.zigTypeTag(mod) == .Vector) {5966 if (ty.zigTypeTag(mod) == .Vector) {
5963 return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{});5967 return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{});
5964 }5968 }
...@@ -5986,11 +5990,11 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerE...@@ -5986,11 +5990,11 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerE
5986}5990}
59875991
5988fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5992fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5993 const mod = func.bin_file.base.options.module.?;
5989 const pl_op = func.air.instructions.items(.data)[inst].pl_op;5994 const pl_op = func.air.instructions.items(.data)[inst].pl_op;
5990 const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;5995 const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;
59915996
5992 const ty = func.air.typeOfIndex(inst);5997 const ty = func.typeOfIndex(inst);
5993 const mod = func.bin_file.base.options.module.?;
5994 if (ty.zigTypeTag(mod) == .Vector) {5998 if (ty.zigTypeTag(mod) == .Vector) {
5995 return func.fail("TODO: `@mulAdd` for vectors", .{});5999 return func.fail("TODO: `@mulAdd` for vectors", .{});
5996 }6000 }
...@@ -6020,11 +6024,11 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6020,11 +6024,11 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6020}6024}
60216025
6022fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6026fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6027 const mod = func.bin_file.base.options.module.?;
6023 const ty_op = func.air.instructions.items(.data)[inst].ty_op;6028 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
60246029
6025 const ty = func.air.typeOf(ty_op.operand);6030 const ty = func.typeOf(ty_op.operand);
6026 const result_ty = func.air.typeOfIndex(inst);6031 const result_ty = func.typeOfIndex(inst);
6027 const mod = func.bin_file.base.options.module.?;
6028 if (ty.zigTypeTag(mod) == .Vector) {6032 if (ty.zigTypeTag(mod) == .Vector) {
6029 return func.fail("TODO: `@clz` for vectors", .{});6033 return func.fail("TODO: `@clz` for vectors", .{});
6030 }6034 }
...@@ -6073,12 +6077,12 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6073,12 +6077,12 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6073}6077}
60746078
6075fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6079fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6080 const mod = func.bin_file.base.options.module.?;
6076 const ty_op = func.air.instructions.items(.data)[inst].ty_op;6081 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
60776082
6078 const ty = func.air.typeOf(ty_op.operand);6083 const ty = func.typeOf(ty_op.operand);
6079 const result_ty = func.air.typeOfIndex(inst);6084 const result_ty = func.typeOfIndex(inst);
60806085
6081 const mod = func.bin_file.base.options.module.?;
6082 if (ty.zigTypeTag(mod) == .Vector) {6086 if (ty.zigTypeTag(mod) == .Vector) {
6083 return func.fail("TODO: `@ctz` for vectors", .{});6087 return func.fail("TODO: `@ctz` for vectors", .{});
6084 }6088 }
...@@ -6141,7 +6145,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {...@@ -6141,7 +6145,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
6141 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});6145 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
61426146
6143 const pl_op = func.air.instructions.items(.data)[inst].pl_op;6147 const pl_op = func.air.instructions.items(.data)[inst].pl_op;
6144 const ty = func.air.typeOf(pl_op.operand);6148 const ty = func.typeOf(pl_op.operand);
6145 const operand = try func.resolveInst(pl_op.operand);6149 const operand = try func.resolveInst(pl_op.operand);
61466150
6147 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand });6151 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand });
...@@ -6179,7 +6183,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6179,7 +6183,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6179 const err_union = try func.resolveInst(pl_op.operand);6183 const err_union = try func.resolveInst(pl_op.operand);
6180 const extra = func.air.extraData(Air.Try, pl_op.payload);6184 const extra = func.air.extraData(Air.Try, pl_op.payload);
6181 const body = func.air.extra[extra.end..][0..extra.data.body_len];6185 const body = func.air.extra[extra.end..][0..extra.data.body_len];
6182 const err_union_ty = func.air.typeOf(pl_op.operand);6186 const err_union_ty = func.typeOf(pl_op.operand);
6183 const result = try lowerTry(func, inst, err_union, body, err_union_ty, false);6187 const result = try lowerTry(func, inst, err_union, body, err_union_ty, false);
6184 func.finishAir(inst, result, &.{pl_op.operand});6188 func.finishAir(inst, result, &.{pl_op.operand});
6185}6189}
...@@ -6189,7 +6193,7 @@ fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6189,7 +6193,7 @@ fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6189 const extra = func.air.extraData(Air.TryPtr, ty_pl.payload);6193 const extra = func.air.extraData(Air.TryPtr, ty_pl.payload);
6190 const err_union_ptr = try func.resolveInst(extra.data.ptr);6194 const err_union_ptr = try func.resolveInst(extra.data.ptr);
6191 const body = func.air.extra[extra.end..][0..extra.data.body_len];6195 const body = func.air.extra[extra.end..][0..extra.data.body_len];
6192 const err_union_ty = func.air.typeOf(extra.data.ptr).childType();6196 const err_union_ty = func.typeOf(extra.data.ptr).childType();
6193 const result = try lowerTry(func, inst, err_union_ptr, body, err_union_ty, true);6197 const result = try lowerTry(func, inst, err_union_ptr, body, err_union_ty, true);
6194 func.finishAir(inst, result, &.{extra.data.ptr});6198 func.finishAir(inst, result, &.{extra.data.ptr});
6195}6199}
...@@ -6251,11 +6255,11 @@ fn lowerTry(...@@ -6251,11 +6255,11 @@ fn lowerTry(
6251}6255}
62526256
6253fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6257fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6258 const mod = func.bin_file.base.options.module.?;
6254 const ty_op = func.air.instructions.items(.data)[inst].ty_op;6259 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
62556260
6256 const ty = func.air.typeOfIndex(inst);6261 const ty = func.typeOfIndex(inst);
6257 const operand = try func.resolveInst(ty_op.operand);6262 const operand = try func.resolveInst(ty_op.operand);
6258 const mod = func.bin_file.base.options.module.?;
62596263
6260 if (ty.zigTypeTag(mod) == .Vector) {6264 if (ty.zigTypeTag(mod) == .Vector) {
6261 return func.fail("TODO: @byteSwap for vectors", .{});6265 return func.fail("TODO: @byteSwap for vectors", .{});
...@@ -6325,7 +6329,7 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6325,7 +6329,7 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6325 const mod = func.bin_file.base.options.module.?;6329 const mod = func.bin_file.base.options.module.?;
6326 const bin_op = func.air.instructions.items(.data)[inst].bin_op;6330 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
63276331
6328 const ty = func.air.typeOfIndex(inst);6332 const ty = func.typeOfIndex(inst);
6329 const lhs = try func.resolveInst(bin_op.lhs);6333 const lhs = try func.resolveInst(bin_op.lhs);
6330 const rhs = try func.resolveInst(bin_op.rhs);6334 const rhs = try func.resolveInst(bin_op.rhs);
63316335
...@@ -6340,7 +6344,7 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6340,7 +6344,7 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6340 const mod = func.bin_file.base.options.module.?;6344 const mod = func.bin_file.base.options.module.?;
6341 const bin_op = func.air.instructions.items(.data)[inst].bin_op;6345 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
63426346
6343 const ty = func.air.typeOfIndex(inst);6347 const ty = func.typeOfIndex(inst);
6344 const lhs = try func.resolveInst(bin_op.lhs);6348 const lhs = try func.resolveInst(bin_op.lhs);
6345 const rhs = try func.resolveInst(bin_op.rhs);6349 const rhs = try func.resolveInst(bin_op.rhs);
63466350
...@@ -6361,7 +6365,7 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6361,7 +6365,7 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6361 const bin_op = func.air.instructions.items(.data)[inst].bin_op;6365 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
63626366
6363 const mod = func.bin_file.base.options.module.?;6367 const mod = func.bin_file.base.options.module.?;
6364 const ty = func.air.typeOfIndex(inst);6368 const ty = func.typeOfIndex(inst);
6365 const lhs = try func.resolveInst(bin_op.lhs);6369 const lhs = try func.resolveInst(bin_op.lhs);
6366 const rhs = try func.resolveInst(bin_op.rhs);6370 const rhs = try func.resolveInst(bin_op.rhs);
63676371
...@@ -6512,7 +6516,7 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -6512,7 +6516,7 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
6512 const bin_op = func.air.instructions.items(.data)[inst].bin_op;6516 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
65136517
6514 const mod = func.bin_file.base.options.module.?;6518 const mod = func.bin_file.base.options.module.?;
6515 const ty = func.air.typeOfIndex(inst);6519 const ty = func.typeOfIndex(inst);
6516 const lhs = try func.resolveInst(bin_op.lhs);6520 const lhs = try func.resolveInst(bin_op.lhs);
6517 const rhs = try func.resolveInst(bin_op.rhs);6521 const rhs = try func.resolveInst(bin_op.rhs);
65186522
...@@ -6626,7 +6630,7 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6626,7 +6630,7 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6626 const bin_op = func.air.instructions.items(.data)[inst].bin_op;6630 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
66276631
6628 const mod = func.bin_file.base.options.module.?;6632 const mod = func.bin_file.base.options.module.?;
6629 const ty = func.air.typeOfIndex(inst);6633 const ty = func.typeOfIndex(inst);
6630 const int_info = ty.intInfo(mod);6634 const int_info = ty.intInfo(mod);
6631 const is_signed = int_info.signedness == .signed;6635 const is_signed = int_info.signedness == .signed;
6632 if (int_info.bits > 64) {6636 if (int_info.bits > 64) {
...@@ -6785,11 +6789,11 @@ fn callIntrinsic(...@@ -6785,11 +6789,11 @@ fn callIntrinsic(
6785fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6789fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6786 const un_op = func.air.instructions.items(.data)[inst].un_op;6790 const un_op = func.air.instructions.items(.data)[inst].un_op;
6787 const operand = try func.resolveInst(un_op);6791 const operand = try func.resolveInst(un_op);
6788 const enum_ty = func.air.typeOf(un_op);6792 const enum_ty = func.typeOf(un_op);
67896793
6790 const func_sym_index = try func.getTagNameFunction(enum_ty);6794 const func_sym_index = try func.getTagNameFunction(enum_ty);
67916795
6792 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));6796 const result_ptr = try func.allocStack(func.typeOfIndex(inst));
6793 try func.lowerToStack(result_ptr);6797 try func.lowerToStack(result_ptr);
6794 try func.emitWValue(operand);6798 try func.emitWValue(operand);
6795 try func.addLabel(.call, func_sym_index);6799 try func.addLabel(.call, func_sym_index);
...@@ -7061,9 +7065,9 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7061,9 +7065,9 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7061 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;7065 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
7062 const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data;7066 const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
70637067
7064 const ptr_ty = func.air.typeOf(extra.ptr);7068 const ptr_ty = func.typeOf(extra.ptr);
7065 const ty = ptr_ty.childType();7069 const ty = ptr_ty.childType();
7066 const result_ty = func.air.typeOfIndex(inst);7070 const result_ty = func.typeOfIndex(inst);
70677071
7068 const ptr_operand = try func.resolveInst(extra.ptr);7072 const ptr_operand = try func.resolveInst(extra.ptr);
7069 const expected_val = try func.resolveInst(extra.expected_value);7073 const expected_val = try func.resolveInst(extra.expected_value);
...@@ -7133,7 +7137,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7133,7 +7137,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7133 const mod = func.bin_file.base.options.module.?;7137 const mod = func.bin_file.base.options.module.?;
7134 const atomic_load = func.air.instructions.items(.data)[inst].atomic_load;7138 const atomic_load = func.air.instructions.items(.data)[inst].atomic_load;
7135 const ptr = try func.resolveInst(atomic_load.ptr);7139 const ptr = try func.resolveInst(atomic_load.ptr);
7136 const ty = func.air.typeOfIndex(inst);7140 const ty = func.typeOfIndex(inst);
71377141
7138 if (func.useAtomicFeature()) {7142 if (func.useAtomicFeature()) {
7139 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {7143 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {
...@@ -7163,7 +7167,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7163,7 +7167,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
71637167
7164 const ptr = try func.resolveInst(pl_op.operand);7168 const ptr = try func.resolveInst(pl_op.operand);
7165 const operand = try func.resolveInst(extra.operand);7169 const operand = try func.resolveInst(extra.operand);
7166 const ty = func.air.typeOfIndex(inst);7170 const ty = func.typeOfIndex(inst);
7167 const op: std.builtin.AtomicRmwOp = extra.op();7171 const op: std.builtin.AtomicRmwOp = extra.op();
71687172
7169 if (func.useAtomicFeature()) {7173 if (func.useAtomicFeature()) {
...@@ -7348,7 +7352,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7348,7 +7352,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
73487352
7349 const ptr = try func.resolveInst(bin_op.lhs);7353 const ptr = try func.resolveInst(bin_op.lhs);
7350 const operand = try func.resolveInst(bin_op.rhs);7354 const operand = try func.resolveInst(bin_op.rhs);
7351 const ptr_ty = func.air.typeOf(bin_op.lhs);7355 const ptr_ty = func.typeOf(bin_op.lhs);
7352 const ty = ptr_ty.childType();7356 const ty = ptr_ty.childType();
73537357
7354 if (func.useAtomicFeature()) {7358 if (func.useAtomicFeature()) {
...@@ -7380,3 +7384,13 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7380,3 +7384,13 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7380 const result = try WValue.toLocal(.stack, func, Type.usize);7384 const result = try WValue.toLocal(.stack, func, Type.usize);
7381 return func.finishAir(inst, result, &.{});7385 return func.finishAir(inst, result, &.{});
7382}7386}
7387
7388fn typeOf(func: *CodeGen, inst: Air.Inst.Ref) Type {
7389 const mod = func.bin_file.base.options.module.?;
7390 return func.air.typeOf(inst, mod.intern_pool);
7391}
7392
7393fn typeOfIndex(func: *CodeGen, inst: Air.Inst.Index) Type {
7394 const mod = func.bin_file.base.options.module.?;
7395 return func.air.typeOfIndex(inst, mod.intern_pool);
7396}
src/arch/x86_64/CodeGen.zig+150-136
...@@ -447,7 +447,7 @@ const InstTracking = struct {...@@ -447,7 +447,7 @@ const InstTracking = struct {
447 else => unreachable,447 else => unreachable,
448 }448 }
449 tracking_log.debug("spill %{d} from {} to {}", .{ inst, self.short, self.long });449 tracking_log.debug("spill %{d} from {} to {}", .{ inst, self.short, self.long });
450 try function.genCopy(function.air.typeOfIndex(inst), self.long, self.short);450 try function.genCopy(function.typeOfIndex(inst), self.long, self.short);
451 }451 }
452452
453 fn reuseFrame(self: *InstTracking) void {453 fn reuseFrame(self: *InstTracking) void {
...@@ -537,7 +537,7 @@ const InstTracking = struct {...@@ -537,7 +537,7 @@ const InstTracking = struct {
537 inst: Air.Inst.Index,537 inst: Air.Inst.Index,
538 target: InstTracking,538 target: InstTracking,
539 ) !void {539 ) !void {
540 const ty = function.air.typeOfIndex(inst);540 const ty = function.typeOfIndex(inst);
541 if ((self.long == .none or self.long == .reserved_frame) and target.long == .load_frame)541 if ((self.long == .none or self.long == .reserved_frame) and target.long == .load_frame)
542 try function.genCopy(ty, target.long, self.short);542 try function.genCopy(ty, target.long, self.short);
543 try function.genCopy(ty, target.short, self.short);543 try function.genCopy(ty, target.short, self.short);
...@@ -1725,6 +1725,8 @@ fn gen(self: *Self) InnerError!void {...@@ -1725,6 +1725,8 @@ fn gen(self: *Self) InnerError!void {
1725}1725}
17261726
1727fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {1727fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
1728 const mod = self.bin_file.options.module.?;
1729 const ip = &mod.intern_pool;
1728 const air_tags = self.air.instructions.items(.tag);1730 const air_tags = self.air.instructions.items(.tag);
17291731
1730 for (body) |inst| {1732 for (body) |inst| {
...@@ -1733,7 +1735,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -1733,7 +1735,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
1733 try self.mir_to_air_map.put(self.gpa, mir_inst, inst);1735 try self.mir_to_air_map.put(self.gpa, mir_inst, inst);
1734 }1736 }
17351737
1736 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) continue;1738 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*)) continue;
1737 wip_mir_log.debug("{}", .{self.fmtAir(inst)});1739 wip_mir_log.debug("{}", .{self.fmtAir(inst)});
1738 verbose_tracking_log.debug("{}", .{self.fmtTracking()});1740 verbose_tracking_log.debug("{}", .{self.fmtTracking()});
17391741
...@@ -1919,6 +1921,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -1919,6 +1921,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
19191921
1920 .constant => unreachable, // excluded from function bodies1922 .constant => unreachable, // excluded from function bodies
1921 .const_ty => unreachable, // excluded from function bodies1923 .const_ty => unreachable, // excluded from function bodies
1924 .interned => unreachable, // excluded from function bodies
1922 .unreach => if (self.wantSafety()) try self.airTrap() else self.finishAirBookkeeping(),1925 .unreach => if (self.wantSafety()) try self.airTrap() else self.finishAirBookkeeping(),
19231926
1924 .optional_payload => try self.airOptionalPayload(inst),1927 .optional_payload => try self.airOptionalPayload(inst),
...@@ -2255,7 +2258,7 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {...@@ -2255,7 +2258,7 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {
2255/// Use a pointer instruction as the basis for allocating stack memory.2258/// Use a pointer instruction as the basis for allocating stack memory.
2256fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {2259fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {
2257 const mod = self.bin_file.options.module.?;2260 const mod = self.bin_file.options.module.?;
2258 const ptr_ty = self.air.typeOfIndex(inst);2261 const ptr_ty = self.typeOfIndex(inst);
2259 const val_ty = ptr_ty.childType();2262 const val_ty = ptr_ty.childType();
2260 return self.allocFrameIndex(FrameAlloc.init(.{2263 return self.allocFrameIndex(FrameAlloc.init(.{
2261 .size = math.cast(u32, val_ty.abiSize(mod)) orelse {2264 .size = math.cast(u32, val_ty.abiSize(mod)) orelse {
...@@ -2266,7 +2269,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {...@@ -2266,7 +2269,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {
2266}2269}
22672270
2268fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {2271fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
2269 return self.allocRegOrMemAdvanced(self.air.typeOfIndex(inst), inst, reg_ok);2272 return self.allocRegOrMemAdvanced(self.typeOfIndex(inst), inst, reg_ok);
2270}2273}
22712274
2272fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue {2275fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue {
...@@ -2485,7 +2488,7 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2485,7 +2488,7 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
2485 .load_frame => .{ .register_offset = .{2488 .load_frame => .{ .register_offset = .{
2486 .reg = (try self.copyToRegisterWithInstTracking(2489 .reg = (try self.copyToRegisterWithInstTracking(
2487 inst,2490 inst,
2488 self.air.typeOfIndex(inst),2491 self.typeOfIndex(inst),
2489 self.ret_mcv.long,2492 self.ret_mcv.long,
2490 )).register,2493 )).register,
2491 .off = self.ret_mcv.short.indirect.off,2494 .off = self.ret_mcv.short.indirect.off,
...@@ -2496,9 +2499,9 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2496,9 +2499,9 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
24962499
2497fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {2500fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
2498 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2501 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2499 const dst_ty = self.air.typeOfIndex(inst);2502 const dst_ty = self.typeOfIndex(inst);
2500 const dst_bits = dst_ty.floatBits(self.target.*);2503 const dst_bits = dst_ty.floatBits(self.target.*);
2501 const src_ty = self.air.typeOf(ty_op.operand);2504 const src_ty = self.typeOf(ty_op.operand);
2502 const src_bits = src_ty.floatBits(self.target.*);2505 const src_bits = src_ty.floatBits(self.target.*);
25032506
2504 const src_mcv = try self.resolveInst(ty_op.operand);2507 const src_mcv = try self.resolveInst(ty_op.operand);
...@@ -2562,9 +2565,9 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2562,9 +2565,9 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
25622565
2563fn airFpext(self: *Self, inst: Air.Inst.Index) !void {2566fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
2564 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2567 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2565 const dst_ty = self.air.typeOfIndex(inst);2568 const dst_ty = self.typeOfIndex(inst);
2566 const dst_bits = dst_ty.floatBits(self.target.*);2569 const dst_bits = dst_ty.floatBits(self.target.*);
2567 const src_ty = self.air.typeOf(ty_op.operand);2570 const src_ty = self.typeOf(ty_op.operand);
2568 const src_bits = src_ty.floatBits(self.target.*);2571 const src_bits = src_ty.floatBits(self.target.*);
25692572
2570 const src_mcv = try self.resolveInst(ty_op.operand);2573 const src_mcv = try self.resolveInst(ty_op.operand);
...@@ -2625,10 +2628,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -2625,10 +2628,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
2625 const mod = self.bin_file.options.module.?;2628 const mod = self.bin_file.options.module.?;
2626 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2629 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2627 const result: MCValue = result: {2630 const result: MCValue = result: {
2628 const src_ty = self.air.typeOf(ty_op.operand);2631 const src_ty = self.typeOf(ty_op.operand);
2629 const src_int_info = src_ty.intInfo(mod);2632 const src_int_info = src_ty.intInfo(mod);
26302633
2631 const dst_ty = self.air.typeOfIndex(inst);2634 const dst_ty = self.typeOfIndex(inst);
2632 const dst_int_info = dst_ty.intInfo(mod);2635 const dst_int_info = dst_ty.intInfo(mod);
2633 const abi_size = @intCast(u32, dst_ty.abiSize(mod));2636 const abi_size = @intCast(u32, dst_ty.abiSize(mod));
26342637
...@@ -2707,9 +2710,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2707,9 +2710,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2707 const mod = self.bin_file.options.module.?;2710 const mod = self.bin_file.options.module.?;
2708 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2711 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27092712
2710 const dst_ty = self.air.typeOfIndex(inst);2713 const dst_ty = self.typeOfIndex(inst);
2711 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));2714 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
2712 const src_ty = self.air.typeOf(ty_op.operand);2715 const src_ty = self.typeOf(ty_op.operand);
2713 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));2716 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
27142717
2715 const result = result: {2718 const result = result: {
...@@ -2818,7 +2821,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {...@@ -2818,7 +2821,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
28182821
2819fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {2822fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {
2820 const un_op = self.air.instructions.items(.data)[inst].un_op;2823 const un_op = self.air.instructions.items(.data)[inst].un_op;
2821 const ty = self.air.typeOfIndex(inst);2824 const ty = self.typeOfIndex(inst);
28222825
2823 const operand = try self.resolveInst(un_op);2826 const operand = try self.resolveInst(un_op);
2824 const dst_mcv = if (self.reuseOperand(inst, un_op, 0, operand))2827 const dst_mcv = if (self.reuseOperand(inst, un_op, 0, operand))
...@@ -2834,11 +2837,11 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -2834,11 +2837,11 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
2834 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2837 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2835 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;2838 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
28362839
2837 const slice_ty = self.air.typeOfIndex(inst);2840 const slice_ty = self.typeOfIndex(inst);
2838 const ptr = try self.resolveInst(bin_op.lhs);2841 const ptr = try self.resolveInst(bin_op.lhs);
2839 const ptr_ty = self.air.typeOf(bin_op.lhs);2842 const ptr_ty = self.typeOf(bin_op.lhs);
2840 const len = try self.resolveInst(bin_op.rhs);2843 const len = try self.resolveInst(bin_op.rhs);
2841 const len_ty = self.air.typeOf(bin_op.rhs);2844 const len_ty = self.typeOf(bin_op.rhs);
28422845
2843 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(slice_ty, mod));2846 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(slice_ty, mod));
2844 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);2847 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
...@@ -2877,7 +2880,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {...@@ -2877,7 +2880,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
2877 const air_tag = self.air.instructions.items(.tag);2880 const air_tag = self.air.instructions.items(.tag);
2878 const air_data = self.air.instructions.items(.data);2881 const air_data = self.air.instructions.items(.data);
28792882
2880 const dst_ty = self.air.typeOf(dst_air);2883 const dst_ty = self.typeOf(dst_air);
2881 const dst_info = dst_ty.intInfo(mod);2884 const dst_info = dst_ty.intInfo(mod);
2882 if (Air.refToIndex(dst_air)) |inst| {2885 if (Air.refToIndex(dst_air)) |inst| {
2883 switch (air_tag[inst]) {2886 switch (air_tag[inst]) {
...@@ -2889,7 +2892,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {...@@ -2889,7 +2892,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
2889 @boolToInt(src_int.positive and dst_info.signedness == .signed);2892 @boolToInt(src_int.positive and dst_info.signedness == .signed);
2890 },2893 },
2891 .intcast => {2894 .intcast => {
2892 const src_ty = self.air.typeOf(air_data[inst].ty_op.operand);2895 const src_ty = self.typeOf(air_data[inst].ty_op.operand);
2893 const src_info = src_ty.intInfo(mod);2896 const src_info = src_ty.intInfo(mod);
2894 return @min(switch (src_info.signedness) {2897 return @min(switch (src_info.signedness) {
2895 .signed => switch (dst_info.signedness) {2898 .signed => switch (dst_info.signedness) {
...@@ -2913,7 +2916,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -2913,7 +2916,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
2913 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2916 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2914 const result = result: {2917 const result = result: {
2915 const tag = self.air.instructions.items(.tag)[inst];2918 const tag = self.air.instructions.items(.tag)[inst];
2916 const dst_ty = self.air.typeOfIndex(inst);2919 const dst_ty = self.typeOfIndex(inst);
2917 switch (dst_ty.zigTypeTag(mod)) {2920 switch (dst_ty.zigTypeTag(mod)) {
2918 .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs),2921 .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs),
2919 else => {},2922 else => {},
...@@ -2942,7 +2945,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -2942,7 +2945,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
2942fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {2945fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
2943 const mod = self.bin_file.options.module.?;2946 const mod = self.bin_file.options.module.?;
2944 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2947 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2945 const ty = self.air.typeOf(bin_op.lhs);2948 const ty = self.typeOf(bin_op.lhs);
29462949
2947 const lhs_mcv = try self.resolveInst(bin_op.lhs);2950 const lhs_mcv = try self.resolveInst(bin_op.lhs);
2948 const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))2951 const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))
...@@ -3021,7 +3024,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3021,7 +3024,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
3021fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {3024fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3022 const mod = self.bin_file.options.module.?;3025 const mod = self.bin_file.options.module.?;
3023 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3026 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3024 const ty = self.air.typeOf(bin_op.lhs);3027 const ty = self.typeOf(bin_op.lhs);
30253028
3026 const lhs_mcv = try self.resolveInst(bin_op.lhs);3029 const lhs_mcv = try self.resolveInst(bin_op.lhs);
3027 const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))3030 const dst_mcv = if (lhs_mcv.isRegister() and self.reuseOperand(inst, bin_op.lhs, 0, lhs_mcv))
...@@ -3093,7 +3096,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3093,7 +3096,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3093fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {3096fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
3094 const mod = self.bin_file.options.module.?;3097 const mod = self.bin_file.options.module.?;
3095 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3098 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3096 const ty = self.air.typeOf(bin_op.lhs);3099 const ty = self.typeOf(bin_op.lhs);
30973100
3098 try self.spillRegisters(&.{ .rax, .rdx });3101 try self.spillRegisters(&.{ .rax, .rdx });
3099 const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx });3102 const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx });
...@@ -3151,7 +3154,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3151,7 +3154,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3151 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3154 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
3152 const result: MCValue = result: {3155 const result: MCValue = result: {
3153 const tag = self.air.instructions.items(.tag)[inst];3156 const tag = self.air.instructions.items(.tag)[inst];
3154 const ty = self.air.typeOf(bin_op.lhs);3157 const ty = self.typeOf(bin_op.lhs);
3155 switch (ty.zigTypeTag(mod)) {3158 switch (ty.zigTypeTag(mod)) {
3156 .Vector => return self.fail("TODO implement add/sub with overflow for Vector type", .{}),3159 .Vector => return self.fail("TODO implement add/sub with overflow for Vector type", .{}),
3157 .Int => {3160 .Int => {
...@@ -3168,7 +3171,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3168,7 +3171,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3168 .signed => .o,3171 .signed => .o,
3169 };3172 };
31703173
3171 const tuple_ty = self.air.typeOfIndex(inst);3174 const tuple_ty = self.typeOfIndex(inst);
3172 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {3175 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {
3173 switch (partial_mcv) {3176 switch (partial_mcv) {
3174 .register => |reg| {3177 .register => |reg| {
...@@ -3211,8 +3214,8 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3211,8 +3214,8 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3211 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3214 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3212 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3215 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
3213 const result: MCValue = result: {3216 const result: MCValue = result: {
3214 const lhs_ty = self.air.typeOf(bin_op.lhs);3217 const lhs_ty = self.typeOf(bin_op.lhs);
3215 const rhs_ty = self.air.typeOf(bin_op.rhs);3218 const rhs_ty = self.typeOf(bin_op.rhs);
3216 switch (lhs_ty.zigTypeTag(mod)) {3219 switch (lhs_ty.zigTypeTag(mod)) {
3217 .Vector => return self.fail("TODO implement shl with overflow for Vector type", .{}),3220 .Vector => return self.fail("TODO implement shl with overflow for Vector type", .{}),
3218 .Int => {3221 .Int => {
...@@ -3241,7 +3244,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3241,7 +3244,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3241 try self.genBinOpMir(.{ ._, .cmp }, lhs_ty, tmp_mcv, lhs);3244 try self.genBinOpMir(.{ ._, .cmp }, lhs_ty, tmp_mcv, lhs);
3242 const cc = Condition.ne;3245 const cc = Condition.ne;
32433246
3244 const tuple_ty = self.air.typeOfIndex(inst);3247 const tuple_ty = self.typeOfIndex(inst);
3245 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {3248 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {
3246 switch (partial_mcv) {3249 switch (partial_mcv) {
3247 .register => |reg| {3250 .register => |reg| {
...@@ -3349,7 +3352,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3349,7 +3352,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3349 const mod = self.bin_file.options.module.?;3352 const mod = self.bin_file.options.module.?;
3350 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;3353 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3351 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3354 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
3352 const dst_ty = self.air.typeOf(bin_op.lhs);3355 const dst_ty = self.typeOf(bin_op.lhs);
3353 const result: MCValue = switch (dst_ty.zigTypeTag(mod)) {3356 const result: MCValue = switch (dst_ty.zigTypeTag(mod)) {
3354 .Vector => return self.fail("TODO implement mul_with_overflow for Vector type", .{}),3357 .Vector => return self.fail("TODO implement mul_with_overflow for Vector type", .{}),
3355 .Int => result: {3358 .Int => result: {
...@@ -3370,7 +3373,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3370,7 +3373,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3370 const lhs = try self.resolveInst(bin_op.lhs);3373 const lhs = try self.resolveInst(bin_op.lhs);
3371 const rhs = try self.resolveInst(bin_op.rhs);3374 const rhs = try self.resolveInst(bin_op.rhs);
33723375
3373 const tuple_ty = self.air.typeOfIndex(inst);3376 const tuple_ty = self.typeOfIndex(inst);
3374 const extra_bits = if (dst_info.bits <= 64)3377 const extra_bits = if (dst_info.bits <= 64)
3375 self.regExtraBits(dst_ty)3378 self.regExtraBits(dst_ty)
3376 else3379 else
...@@ -3525,8 +3528,8 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -3525,8 +3528,8 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
3525 try self.register_manager.getReg(.rcx, null);3528 try self.register_manager.getReg(.rcx, null);
3526 const lhs = try self.resolveInst(bin_op.lhs);3529 const lhs = try self.resolveInst(bin_op.lhs);
3527 const rhs = try self.resolveInst(bin_op.rhs);3530 const rhs = try self.resolveInst(bin_op.rhs);
3528 const lhs_ty = self.air.typeOf(bin_op.lhs);3531 const lhs_ty = self.typeOf(bin_op.lhs);
3529 const rhs_ty = self.air.typeOf(bin_op.rhs);3532 const rhs_ty = self.typeOf(bin_op.rhs);
35303533
3531 const result = try self.genShiftBinOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);3534 const result = try self.genShiftBinOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty);
35323535
...@@ -3543,7 +3546,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {...@@ -3543,7 +3546,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
3543fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {3546fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
3544 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3547 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3545 const result: MCValue = result: {3548 const result: MCValue = result: {
3546 const pl_ty = self.air.typeOfIndex(inst);3549 const pl_ty = self.typeOfIndex(inst);
3547 const opt_mcv = try self.resolveInst(ty_op.operand);3550 const opt_mcv = try self.resolveInst(ty_op.operand);
35483551
3549 if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {3552 if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
...@@ -3568,7 +3571,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -3568,7 +3571,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
3568fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {3571fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
3569 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3572 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
35703573
3571 const dst_ty = self.air.typeOfIndex(inst);3574 const dst_ty = self.typeOfIndex(inst);
3572 const opt_mcv = try self.resolveInst(ty_op.operand);3575 const opt_mcv = try self.resolveInst(ty_op.operand);
35733576
3574 const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv))3577 const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv))
...@@ -3582,8 +3585,8 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3582,8 +3585,8 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3582 const mod = self.bin_file.options.module.?;3585 const mod = self.bin_file.options.module.?;
3583 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3586 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3584 const result = result: {3587 const result = result: {
3585 const dst_ty = self.air.typeOfIndex(inst);3588 const dst_ty = self.typeOfIndex(inst);
3586 const src_ty = self.air.typeOf(ty_op.operand);3589 const src_ty = self.typeOf(ty_op.operand);
3587 const opt_ty = src_ty.childType();3590 const opt_ty = src_ty.childType();
3588 const src_mcv = try self.resolveInst(ty_op.operand);3591 const src_mcv = try self.resolveInst(ty_op.operand);
35893592
...@@ -3615,7 +3618,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3615,7 +3618,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3615fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {3618fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3616 const mod = self.bin_file.options.module.?;3619 const mod = self.bin_file.options.module.?;
3617 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3620 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3618 const err_union_ty = self.air.typeOf(ty_op.operand);3621 const err_union_ty = self.typeOf(ty_op.operand);
3619 const err_ty = err_union_ty.errorUnionSet();3622 const err_ty = err_union_ty.errorUnionSet();
3620 const payload_ty = err_union_ty.errorUnionPayload();3623 const payload_ty = err_union_ty.errorUnionPayload();
3621 const operand = try self.resolveInst(ty_op.operand);3624 const operand = try self.resolveInst(ty_op.operand);
...@@ -3662,7 +3665,7 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3662,7 +3665,7 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
36623665
3663fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {3666fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3664 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3667 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3665 const err_union_ty = self.air.typeOf(ty_op.operand);3668 const err_union_ty = self.typeOf(ty_op.operand);
3666 const operand = try self.resolveInst(ty_op.operand);3669 const operand = try self.resolveInst(ty_op.operand);
3667 const result = try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, operand);3670 const result = try self.genUnwrapErrorUnionPayloadMir(inst, err_union_ty, operand);
3668 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });3671 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
...@@ -3720,7 +3723,7 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3720,7 +3723,7 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
3720 const mod = self.bin_file.options.module.?;3723 const mod = self.bin_file.options.module.?;
3721 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3724 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
37223725
3723 const src_ty = self.air.typeOf(ty_op.operand);3726 const src_ty = self.typeOf(ty_op.operand);
3724 const src_mcv = try self.resolveInst(ty_op.operand);3727 const src_mcv = try self.resolveInst(ty_op.operand);
3725 const src_reg = switch (src_mcv) {3728 const src_reg = switch (src_mcv) {
3726 .register => |reg| reg,3729 .register => |reg| reg,
...@@ -3756,7 +3759,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3756,7 +3759,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
3756 const mod = self.bin_file.options.module.?;3759 const mod = self.bin_file.options.module.?;
3757 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3760 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
37583761
3759 const src_ty = self.air.typeOf(ty_op.operand);3762 const src_ty = self.typeOf(ty_op.operand);
3760 const src_mcv = try self.resolveInst(ty_op.operand);3763 const src_mcv = try self.resolveInst(ty_op.operand);
3761 const src_reg = switch (src_mcv) {3764 const src_reg = switch (src_mcv) {
3762 .register => |reg| reg,3765 .register => |reg| reg,
...@@ -3765,7 +3768,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3765,7 +3768,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
3765 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);3768 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
3766 defer self.register_manager.unlockReg(src_lock);3769 defer self.register_manager.unlockReg(src_lock);
37673770
3768 const dst_ty = self.air.typeOfIndex(inst);3771 const dst_ty = self.typeOfIndex(inst);
3769 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))3772 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
3770 src_reg3773 src_reg
3771 else3774 else
...@@ -3791,7 +3794,7 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3791,7 +3794,7 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3791 const mod = self.bin_file.options.module.?;3794 const mod = self.bin_file.options.module.?;
3792 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3795 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3793 const result: MCValue = result: {3796 const result: MCValue = result: {
3794 const src_ty = self.air.typeOf(ty_op.operand);3797 const src_ty = self.typeOf(ty_op.operand);
3795 const src_mcv = try self.resolveInst(ty_op.operand);3798 const src_mcv = try self.resolveInst(ty_op.operand);
3796 const src_reg = switch (src_mcv) {3799 const src_reg = switch (src_mcv) {
3797 .register => |reg| reg,3800 .register => |reg| reg,
...@@ -3816,7 +3819,7 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3816,7 +3819,7 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
38163819
3817 if (self.liveness.isUnused(inst)) break :result .unreach;3820 if (self.liveness.isUnused(inst)) break :result .unreach;
38183821
3819 const dst_ty = self.air.typeOfIndex(inst);3822 const dst_ty = self.typeOfIndex(inst);
3820 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))3823 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
3821 src_reg3824 src_reg
3822 else3825 else
...@@ -3856,10 +3859,10 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {...@@ -3856,10 +3859,10 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3856 const mod = self.bin_file.options.module.?;3859 const mod = self.bin_file.options.module.?;
3857 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3860 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3858 const result: MCValue = result: {3861 const result: MCValue = result: {
3859 const pl_ty = self.air.typeOf(ty_op.operand);3862 const pl_ty = self.typeOf(ty_op.operand);
3860 if (!pl_ty.hasRuntimeBits(mod)) break :result .{ .immediate = 1 };3863 if (!pl_ty.hasRuntimeBits(mod)) break :result .{ .immediate = 1 };
38613864
3862 const opt_ty = self.air.typeOfIndex(inst);3865 const opt_ty = self.typeOfIndex(inst);
3863 const pl_mcv = try self.resolveInst(ty_op.operand);3866 const pl_mcv = try self.resolveInst(ty_op.operand);
3864 const same_repr = opt_ty.optionalReprIsPayload(mod);3867 const same_repr = opt_ty.optionalReprIsPayload(mod);
3865 if (same_repr and self.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv;3868 if (same_repr and self.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv;
...@@ -3952,7 +3955,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3952,7 +3955,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
3952 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv;3955 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv;
39533956
3954 const dst_mcv = try self.allocRegOrMem(inst, true);3957 const dst_mcv = try self.allocRegOrMem(inst, true);
3955 const dst_ty = self.air.typeOfIndex(inst);3958 const dst_ty = self.typeOfIndex(inst);
3956 try self.genCopy(dst_ty, dst_mcv, src_mcv);3959 try self.genCopy(dst_ty, dst_mcv, src_mcv);
3957 break :result dst_mcv;3960 break :result dst_mcv;
3958 };3961 };
...@@ -3980,7 +3983,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3980,7 +3983,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
3980 const mod = self.bin_file.options.module.?;3983 const mod = self.bin_file.options.module.?;
3981 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3984 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39823985
3983 const src_ty = self.air.typeOf(ty_op.operand);3986 const src_ty = self.typeOf(ty_op.operand);
3984 const src_mcv = try self.resolveInst(ty_op.operand);3987 const src_mcv = try self.resolveInst(ty_op.operand);
3985 const src_reg = switch (src_mcv) {3988 const src_reg = switch (src_mcv) {
3986 .register => |reg| reg,3989 .register => |reg| reg,
...@@ -3989,7 +3992,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3989,7 +3992,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
3989 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);3992 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
3990 defer self.register_manager.unlockReg(src_lock);3993 defer self.register_manager.unlockReg(src_lock);
39913994
3992 const dst_ty = self.air.typeOfIndex(inst);3995 const dst_ty = self.typeOfIndex(inst);
3993 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))3996 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
3994 src_reg3997 src_reg
3995 else3998 else
...@@ -4014,7 +4017,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4014,7 +4017,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
4014fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {4017fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
4015 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4018 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
40164019
4017 const dst_ty = self.air.typeOfIndex(inst);4020 const dst_ty = self.typeOfIndex(inst);
4018 const opt_mcv = try self.resolveInst(ty_op.operand);4021 const opt_mcv = try self.resolveInst(ty_op.operand);
40194022
4020 const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv))4023 const dst_mcv = if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv))
...@@ -4046,7 +4049,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi...@@ -4046,7 +4049,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi
40464049
4047fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {4050fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
4048 const mod = self.bin_file.options.module.?;4051 const mod = self.bin_file.options.module.?;
4049 const slice_ty = self.air.typeOf(lhs);4052 const slice_ty = self.typeOf(lhs);
4050 const slice_mcv = try self.resolveInst(lhs);4053 const slice_mcv = try self.resolveInst(lhs);
4051 const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {4054 const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {
4052 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),4055 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
...@@ -4059,7 +4062,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {...@@ -4059,7 +4062,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
4059 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4062 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4060 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);4063 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
40614064
4062 const index_ty = self.air.typeOf(rhs);4065 const index_ty = self.typeOf(rhs);
4063 const index_mcv = try self.resolveInst(rhs);4066 const index_mcv = try self.resolveInst(rhs);
4064 const index_mcv_lock: ?RegisterLock = switch (index_mcv) {4067 const index_mcv_lock: ?RegisterLock = switch (index_mcv) {
4065 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),4068 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
...@@ -4083,7 +4086,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {...@@ -4083,7 +4086,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
40834086
4084fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {4087fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
4085 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4088 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4086 const slice_ty = self.air.typeOf(bin_op.lhs);4089 const slice_ty = self.typeOf(bin_op.lhs);
40874090
4088 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4091 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4089 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);4092 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
...@@ -4105,7 +4108,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4105,7 +4108,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
4105 const mod = self.bin_file.options.module.?;4108 const mod = self.bin_file.options.module.?;
4106 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4109 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
41074110
4108 const array_ty = self.air.typeOf(bin_op.lhs);4111 const array_ty = self.typeOf(bin_op.lhs);
4109 const array = try self.resolveInst(bin_op.lhs);4112 const array = try self.resolveInst(bin_op.lhs);
4110 const array_lock: ?RegisterLock = switch (array) {4113 const array_lock: ?RegisterLock = switch (array) {
4111 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),4114 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
...@@ -4116,7 +4119,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4116,7 +4119,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
4116 const elem_ty = array_ty.childType();4119 const elem_ty = array_ty.childType();
4117 const elem_abi_size = elem_ty.abiSize(mod);4120 const elem_abi_size = elem_ty.abiSize(mod);
41184121
4119 const index_ty = self.air.typeOf(bin_op.rhs);4122 const index_ty = self.typeOf(bin_op.rhs);
4120 const index = try self.resolveInst(bin_op.rhs);4123 const index = try self.resolveInst(bin_op.rhs);
4121 const index_lock: ?RegisterLock = switch (index) {4124 const index_lock: ?RegisterLock = switch (index) {
4122 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),4125 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
...@@ -4170,14 +4173,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4170,14 +4173,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
4170fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {4173fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
4171 const mod = self.bin_file.options.module.?;4174 const mod = self.bin_file.options.module.?;
4172 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4175 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4173 const ptr_ty = self.air.typeOf(bin_op.lhs);4176 const ptr_ty = self.typeOf(bin_op.lhs);
41744177
4175 // this is identical to the `airPtrElemPtr` codegen expect here an4178 // this is identical to the `airPtrElemPtr` codegen expect here an
4176 // additional `mov` is needed at the end to get the actual value4179 // additional `mov` is needed at the end to get the actual value
41774180
4178 const elem_ty = ptr_ty.elemType2(mod);4181 const elem_ty = ptr_ty.elemType2(mod);
4179 const elem_abi_size = @intCast(u32, elem_ty.abiSize(mod));4182 const elem_abi_size = @intCast(u32, elem_ty.abiSize(mod));
4180 const index_ty = self.air.typeOf(bin_op.rhs);4183 const index_ty = self.typeOf(bin_op.rhs);
4181 const index_mcv = try self.resolveInst(bin_op.rhs);4184 const index_mcv = try self.resolveInst(bin_op.rhs);
4182 const index_lock = switch (index_mcv) {4185 const index_lock = switch (index_mcv) {
4183 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),4186 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
...@@ -4218,7 +4221,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4218,7 +4221,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
4218 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;4221 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4219 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;4222 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
42204223
4221 const ptr_ty = self.air.typeOf(extra.lhs);4224 const ptr_ty = self.typeOf(extra.lhs);
4222 const ptr = try self.resolveInst(extra.lhs);4225 const ptr = try self.resolveInst(extra.lhs);
4223 const ptr_lock: ?RegisterLock = switch (ptr) {4226 const ptr_lock: ?RegisterLock = switch (ptr) {
4224 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),4227 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
...@@ -4228,7 +4231,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4228,7 +4231,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
42284231
4229 const elem_ty = ptr_ty.elemType2(mod);4232 const elem_ty = ptr_ty.elemType2(mod);
4230 const elem_abi_size = elem_ty.abiSize(mod);4233 const elem_abi_size = elem_ty.abiSize(mod);
4231 const index_ty = self.air.typeOf(extra.rhs);4234 const index_ty = self.typeOf(extra.rhs);
4232 const index = try self.resolveInst(extra.rhs);4235 const index = try self.resolveInst(extra.rhs);
4233 const index_lock: ?RegisterLock = switch (index) {4236 const index_lock: ?RegisterLock = switch (index) {
4234 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),4237 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
...@@ -4249,9 +4252,9 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4249,9 +4252,9 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
4249fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {4252fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4250 const mod = self.bin_file.options.module.?;4253 const mod = self.bin_file.options.module.?;
4251 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4254 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4252 const ptr_union_ty = self.air.typeOf(bin_op.lhs);4255 const ptr_union_ty = self.typeOf(bin_op.lhs);
4253 const union_ty = ptr_union_ty.childType();4256 const union_ty = ptr_union_ty.childType();
4254 const tag_ty = self.air.typeOf(bin_op.rhs);4257 const tag_ty = self.typeOf(bin_op.rhs);
4255 const layout = union_ty.unionGetLayout(mod);4258 const layout = union_ty.unionGetLayout(mod);
42564259
4257 if (layout.tag_size == 0) {4260 if (layout.tag_size == 0) {
...@@ -4296,8 +4299,8 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -4296,8 +4299,8 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4296 const mod = self.bin_file.options.module.?;4299 const mod = self.bin_file.options.module.?;
4297 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4300 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
42984301
4299 const tag_ty = self.air.typeOfIndex(inst);4302 const tag_ty = self.typeOfIndex(inst);
4300 const union_ty = self.air.typeOf(ty_op.operand);4303 const union_ty = self.typeOf(ty_op.operand);
4301 const layout = union_ty.unionGetLayout(mod);4304 const layout = union_ty.unionGetLayout(mod);
43024305
4303 if (layout.tag_size == 0) {4306 if (layout.tag_size == 0) {
...@@ -4350,8 +4353,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4350,8 +4353,8 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
4350 const mod = self.bin_file.options.module.?;4353 const mod = self.bin_file.options.module.?;
4351 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4354 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4352 const result = result: {4355 const result = result: {
4353 const dst_ty = self.air.typeOfIndex(inst);4356 const dst_ty = self.typeOfIndex(inst);
4354 const src_ty = self.air.typeOf(ty_op.operand);4357 const src_ty = self.typeOf(ty_op.operand);
43554358
4356 const src_mcv = try self.resolveInst(ty_op.operand);4359 const src_mcv = try self.resolveInst(ty_op.operand);
4357 const mat_src_mcv = switch (src_mcv) {4360 const mat_src_mcv = switch (src_mcv) {
...@@ -4479,8 +4482,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -4479,8 +4482,8 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
4479 const mod = self.bin_file.options.module.?;4482 const mod = self.bin_file.options.module.?;
4480 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4483 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4481 const result = result: {4484 const result = result: {
4482 const dst_ty = self.air.typeOfIndex(inst);4485 const dst_ty = self.typeOfIndex(inst);
4483 const src_ty = self.air.typeOf(ty_op.operand);4486 const src_ty = self.typeOf(ty_op.operand);
4484 const src_bits = src_ty.bitSize(mod);4487 const src_bits = src_ty.bitSize(mod);
44854488
4486 const src_mcv = try self.resolveInst(ty_op.operand);4489 const src_mcv = try self.resolveInst(ty_op.operand);
...@@ -4575,7 +4578,7 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {...@@ -4575,7 +4578,7 @@ fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
4575 const mod = self.bin_file.options.module.?;4578 const mod = self.bin_file.options.module.?;
4576 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4579 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4577 const result: MCValue = result: {4580 const result: MCValue = result: {
4578 const src_ty = self.air.typeOf(ty_op.operand);4581 const src_ty = self.typeOf(ty_op.operand);
4579 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));4582 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
4580 const src_mcv = try self.resolveInst(ty_op.operand);4583 const src_mcv = try self.resolveInst(ty_op.operand);
45814584
...@@ -4745,7 +4748,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {...@@ -4745,7 +4748,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
4745 const mod = self.bin_file.options.module.?;4748 const mod = self.bin_file.options.module.?;
4746 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4749 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
47474750
4748 const src_ty = self.air.typeOf(ty_op.operand);4751 const src_ty = self.typeOf(ty_op.operand);
4749 const src_mcv = try self.resolveInst(ty_op.operand);4752 const src_mcv = try self.resolveInst(ty_op.operand);
47504753
4751 const dst_mcv = try self.byteSwap(inst, src_ty, src_mcv, true);4754 const dst_mcv = try self.byteSwap(inst, src_ty, src_mcv, true);
...@@ -4766,7 +4769,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {...@@ -4766,7 +4769,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
4766 const mod = self.bin_file.options.module.?;4769 const mod = self.bin_file.options.module.?;
4767 const ty_op = self.air.instructions.items(.data)[inst].ty_op;4770 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
47684771
4769 const src_ty = self.air.typeOf(ty_op.operand);4772 const src_ty = self.typeOf(ty_op.operand);
4770 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));4773 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
4771 const src_mcv = try self.resolveInst(ty_op.operand);4774 const src_mcv = try self.resolveInst(ty_op.operand);
47724775
...@@ -4876,12 +4879,12 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {...@@ -4876,12 +4879,12 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
4876 const mod = self.bin_file.options.module.?;4879 const mod = self.bin_file.options.module.?;
4877 const tag = self.air.instructions.items(.tag)[inst];4880 const tag = self.air.instructions.items(.tag)[inst];
4878 const un_op = self.air.instructions.items(.data)[inst].un_op;4881 const un_op = self.air.instructions.items(.data)[inst].un_op;
4879 const ty = self.air.typeOf(un_op);4882 const ty = self.typeOf(un_op);
4880 const abi_size: u32 = switch (ty.abiSize(mod)) {4883 const abi_size: u32 = switch (ty.abiSize(mod)) {
4881 1...16 => 16,4884 1...16 => 16,
4882 17...32 => 32,4885 17...32 => 32,
4883 else => return self.fail("TODO implement airFloatSign for {}", .{4886 else => return self.fail("TODO implement airFloatSign for {}", .{
4884 ty.fmt(self.bin_file.options.module.?),4887 ty.fmt(mod),
4885 }),4888 }),
4886 };4889 };
4887 const scalar_bits = ty.scalarType(mod).floatBits(self.target.*);4890 const scalar_bits = ty.scalarType(mod).floatBits(self.target.*);
...@@ -5005,7 +5008,7 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {...@@ -5005,7 +5008,7 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
50055008
5006fn airRound(self: *Self, inst: Air.Inst.Index, mode: u4) !void {5009fn airRound(self: *Self, inst: Air.Inst.Index, mode: u4) !void {
5007 const un_op = self.air.instructions.items(.data)[inst].un_op;5010 const un_op = self.air.instructions.items(.data)[inst].un_op;
5008 const ty = self.air.typeOf(un_op);5011 const ty = self.typeOf(un_op);
50095012
5010 const src_mcv = try self.resolveInst(un_op);5013 const src_mcv = try self.resolveInst(un_op);
5011 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv))5014 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv))
...@@ -5093,7 +5096,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4...@@ -5093,7 +5096,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4
5093fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {5096fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5094 const mod = self.bin_file.options.module.?;5097 const mod = self.bin_file.options.module.?;
5095 const un_op = self.air.instructions.items(.data)[inst].un_op;5098 const un_op = self.air.instructions.items(.data)[inst].un_op;
5096 const ty = self.air.typeOf(un_op);5099 const ty = self.typeOf(un_op);
5097 const abi_size = @intCast(u32, ty.abiSize(mod));5100 const abi_size = @intCast(u32, ty.abiSize(mod));
50985101
5099 const src_mcv = try self.resolveInst(un_op);5102 const src_mcv = try self.resolveInst(un_op);
...@@ -5399,7 +5402,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro...@@ -5399,7 +5402,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
5399fn airLoad(self: *Self, inst: Air.Inst.Index) !void {5402fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
5400 const mod = self.bin_file.options.module.?;5403 const mod = self.bin_file.options.module.?;
5401 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5404 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5402 const elem_ty = self.air.typeOfIndex(inst);5405 const elem_ty = self.typeOfIndex(inst);
5403 const result: MCValue = result: {5406 const result: MCValue = result: {
5404 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;5407 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
54055408
...@@ -5407,7 +5410,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -5407,7 +5410,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
5407 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });5410 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });
5408 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);5411 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
54095412
5410 const ptr_ty = self.air.typeOf(ty_op.operand);5413 const ptr_ty = self.typeOf(ty_op.operand);
5411 const elem_size = elem_ty.abiSize(mod);5414 const elem_size = elem_ty.abiSize(mod);
54125415
5413 const elem_rc = regClassForType(elem_ty, mod);5416 const elem_rc = regClassForType(elem_ty, mod);
...@@ -5548,7 +5551,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -5548,7 +5551,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
5548 }5551 }
5549 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5552 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5550 const ptr_mcv = try self.resolveInst(bin_op.lhs);5553 const ptr_mcv = try self.resolveInst(bin_op.lhs);
5551 const ptr_ty = self.air.typeOf(bin_op.lhs);5554 const ptr_ty = self.typeOf(bin_op.lhs);
5552 const src_mcv = try self.resolveInst(bin_op.rhs);5555 const src_mcv = try self.resolveInst(bin_op.rhs);
5553 if (ptr_ty.ptrInfo().data.host_size > 0) {5556 if (ptr_ty.ptrInfo().data.host_size > 0) {
5554 try self.packedStore(ptr_ty, ptr_mcv, src_mcv);5557 try self.packedStore(ptr_ty, ptr_mcv, src_mcv);
...@@ -5573,8 +5576,8 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {...@@ -5573,8 +5576,8 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
55735576
5574fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {5577fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
5575 const mod = self.bin_file.options.module.?;5578 const mod = self.bin_file.options.module.?;
5576 const ptr_field_ty = self.air.typeOfIndex(inst);5579 const ptr_field_ty = self.typeOfIndex(inst);
5577 const ptr_container_ty = self.air.typeOf(operand);5580 const ptr_container_ty = self.typeOf(operand);
5578 const container_ty = ptr_container_ty.childType();5581 const container_ty = ptr_container_ty.childType();
5579 const field_offset = @intCast(i32, switch (container_ty.containerLayout()) {5582 const field_offset = @intCast(i32, switch (container_ty.containerLayout()) {
5580 .Auto, .Extern => container_ty.structFieldOffset(index, mod),5583 .Auto, .Extern => container_ty.structFieldOffset(index, mod),
...@@ -5602,7 +5605,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -5602,7 +5605,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
5602 const operand = extra.struct_operand;5605 const operand = extra.struct_operand;
5603 const index = extra.field_index;5606 const index = extra.field_index;
56045607
5605 const container_ty = self.air.typeOf(operand);5608 const container_ty = self.typeOf(operand);
5606 const container_rc = regClassForType(container_ty, mod);5609 const container_rc = regClassForType(container_ty, mod);
5607 const field_ty = container_ty.structFieldType(index);5610 const field_ty = container_ty.structFieldType(index);
5608 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;5611 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
...@@ -5756,7 +5759,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5756,7 +5759,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
5756 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5759 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5757 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5760 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
57585761
5759 const inst_ty = self.air.typeOfIndex(inst);5762 const inst_ty = self.typeOfIndex(inst);
5760 const parent_ty = inst_ty.childType();5763 const parent_ty = inst_ty.childType();
5761 const field_offset = @intCast(i32, parent_ty.structFieldOffset(extra.field_index, mod));5764 const field_offset = @intCast(i32, parent_ty.structFieldOffset(extra.field_index, mod));
57625765
...@@ -5772,7 +5775,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -5772,7 +5775,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
57725775
5773fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue {5776fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue {
5774 const mod = self.bin_file.options.module.?;5777 const mod = self.bin_file.options.module.?;
5775 const src_ty = self.air.typeOf(src_air);5778 const src_ty = self.typeOf(src_air);
5776 const src_mcv = try self.resolveInst(src_air);5779 const src_mcv = try self.resolveInst(src_air);
5777 if (src_ty.zigTypeTag(mod) == .Vector) {5780 if (src_ty.zigTypeTag(mod) == .Vector) {
5778 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)});5781 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)});
...@@ -6358,8 +6361,8 @@ fn genBinOp(...@@ -6358,8 +6361,8 @@ fn genBinOp(
6358 rhs_air: Air.Inst.Ref,6361 rhs_air: Air.Inst.Ref,
6359) !MCValue {6362) !MCValue {
6360 const mod = self.bin_file.options.module.?;6363 const mod = self.bin_file.options.module.?;
6361 const lhs_ty = self.air.typeOf(lhs_air);6364 const lhs_ty = self.typeOf(lhs_air);
6362 const rhs_ty = self.air.typeOf(rhs_air);6365 const rhs_ty = self.typeOf(rhs_air);
6363 const abi_size = @intCast(u32, lhs_ty.abiSize(mod));6366 const abi_size = @intCast(u32, lhs_ty.abiSize(mod));
63646367
6365 const maybe_mask_reg = switch (air_tag) {6368 const maybe_mask_reg = switch (air_tag) {
...@@ -7918,6 +7921,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -7918,6 +7921,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
7918}7921}
79197922
7920fn airArg(self: *Self, inst: Air.Inst.Index) !void {7923fn airArg(self: *Self, inst: Air.Inst.Index) !void {
7924 const mod = self.bin_file.options.module.?;
7921 // skip zero-bit arguments as they don't have a corresponding arg instruction7925 // skip zero-bit arguments as they don't have a corresponding arg instruction
7922 var arg_index = self.arg_index;7926 var arg_index = self.arg_index;
7923 while (self.args[arg_index] == .none) arg_index += 1;7927 while (self.args[arg_index] == .none) arg_index += 1;
...@@ -7931,9 +7935,9 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -7931,9 +7935,9 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
7931 else => return self.fail("TODO implement arg for {}", .{dst_mcv}),7935 else => return self.fail("TODO implement arg for {}", .{dst_mcv}),
7932 }7936 }
79337937
7934 const ty = self.air.typeOfIndex(inst);7938 const ty = self.typeOfIndex(inst);
7935 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;7939 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
7936 const name = self.owner.mod_fn.getParamName(self.bin_file.options.module.?, src_index);7940 const name = self.owner.mod_fn.getParamName(mod, src_index);
7937 try self.genArgDbgInfo(ty, name, dst_mcv);7941 try self.genArgDbgInfo(ty, name, dst_mcv);
79387942
7939 break :result dst_mcv;7943 break :result dst_mcv;
...@@ -8050,7 +8054,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8050,7 +8054,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8050 const callee = pl_op.operand;8054 const callee = pl_op.operand;
8051 const extra = self.air.extraData(Air.Call, pl_op.payload);8055 const extra = self.air.extraData(Air.Call, pl_op.payload);
8052 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);8056 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
8053 const ty = self.air.typeOf(callee);8057 const ty = self.typeOf(callee);
80548058
8055 const fn_ty = switch (ty.zigTypeTag(mod)) {8059 const fn_ty = switch (ty.zigTypeTag(mod)) {
8056 .Fn => ty,8060 .Fn => ty,
...@@ -8085,7 +8089,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8085,7 +8089,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8085 else => unreachable,8089 else => unreachable,
8086 }8090 }
8087 for (args, info.args) |arg, mc_arg| {8091 for (args, info.args) |arg, mc_arg| {
8088 const arg_ty = self.air.typeOf(arg);8092 const arg_ty = self.typeOf(arg);
8089 const arg_mcv = try self.resolveInst(arg);8093 const arg_mcv = try self.resolveInst(arg);
8090 switch (mc_arg) {8094 switch (mc_arg) {
8091 .none => {},8095 .none => {},
...@@ -8112,7 +8116,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8112,7 +8116,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8112 defer if (ret_lock) |lock| self.register_manager.unlockReg(lock);8116 defer if (ret_lock) |lock| self.register_manager.unlockReg(lock);
81138117
8114 for (args, info.args) |arg, mc_arg| {8118 for (args, info.args) |arg, mc_arg| {
8115 const arg_ty = self.air.typeOf(arg);8119 const arg_ty = self.typeOf(arg);
8116 const arg_mcv = try self.resolveInst(arg);8120 const arg_mcv = try self.resolveInst(arg);
8117 switch (mc_arg) {8121 switch (mc_arg) {
8118 .none, .load_frame => {},8122 .none, .load_frame => {},
...@@ -8241,7 +8245,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -8241,7 +8245,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
8241fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {8245fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
8242 const un_op = self.air.instructions.items(.data)[inst].un_op;8246 const un_op = self.air.instructions.items(.data)[inst].un_op;
8243 const ptr = try self.resolveInst(un_op);8247 const ptr = try self.resolveInst(un_op);
8244 const ptr_ty = self.air.typeOf(un_op);8248 const ptr_ty = self.typeOf(un_op);
8245 switch (self.ret_mcv.short) {8249 switch (self.ret_mcv.short) {
8246 .none => {},8250 .none => {},
8247 .register => try self.load(self.ret_mcv.short, ptr_ty, ptr),8251 .register => try self.load(self.ret_mcv.short, ptr_ty, ptr),
...@@ -8258,7 +8262,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -8258,7 +8262,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
8258fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {8262fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
8259 const mod = self.bin_file.options.module.?;8263 const mod = self.bin_file.options.module.?;
8260 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8264 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8261 const ty = self.air.typeOf(bin_op.lhs);8265 const ty = self.typeOf(bin_op.lhs);
82628266
8263 try self.spillEflagsIfOccupied();8267 try self.spillEflagsIfOccupied();
8264 self.eflags_inst = inst;8268 self.eflags_inst = inst;
...@@ -8476,7 +8480,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -8476,7 +8480,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
8476 try self.spillEflagsIfOccupied();8480 try self.spillEflagsIfOccupied();
8477 self.eflags_inst = inst;8481 self.eflags_inst = inst;
84788482
8479 const op_ty = self.air.typeOf(un_op);8483 const op_ty = self.typeOf(un_op);
8480 const op_abi_size = @intCast(u32, op_ty.abiSize(mod));8484 const op_abi_size = @intCast(u32, op_ty.abiSize(mod));
8481 const op_mcv = try self.resolveInst(un_op);8485 const op_mcv = try self.resolveInst(un_op);
8482 const dst_reg = switch (op_mcv) {8486 const dst_reg = switch (op_mcv) {
...@@ -8496,7 +8500,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {...@@ -8496,7 +8500,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
8496 const pl_op = self.air.instructions.items(.data)[inst].pl_op;8500 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
8497 const extra = self.air.extraData(Air.Try, pl_op.payload);8501 const extra = self.air.extraData(Air.Try, pl_op.payload);
8498 const body = self.air.extra[extra.end..][0..extra.data.body_len];8502 const body = self.air.extra[extra.end..][0..extra.data.body_len];
8499 const err_union_ty = self.air.typeOf(pl_op.operand);8503 const err_union_ty = self.typeOf(pl_op.operand);
8500 const result = try self.genTry(inst, pl_op.operand, body, err_union_ty, false);8504 const result = try self.genTry(inst, pl_op.operand, body, err_union_ty, false);
8501 return self.finishAir(inst, result, .{ .none, .none, .none });8505 return self.finishAir(inst, result, .{ .none, .none, .none });
8502}8506}
...@@ -8505,7 +8509,7 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -8505,7 +8509,7 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
8505 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;8509 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
8506 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);8510 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
8507 const body = self.air.extra[extra.end..][0..extra.data.body_len];8511 const body = self.air.extra[extra.end..][0..extra.data.body_len];
8508 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();8512 const err_union_ty = self.typeOf(extra.data.ptr).childType();
8509 const result = try self.genTry(inst, extra.data.ptr, body, err_union_ty, true);8513 const result = try self.genTry(inst, extra.data.ptr, body, err_union_ty, true);
8510 return self.finishAir(inst, result, .{ .none, .none, .none });8514 return self.finishAir(inst, result, .{ .none, .none, .none });
8511}8515}
...@@ -8584,7 +8588,7 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -8584,7 +8588,7 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
8584fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {8588fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
8585 const pl_op = self.air.instructions.items(.data)[inst].pl_op;8589 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
8586 const operand = pl_op.operand;8590 const operand = pl_op.operand;
8587 const ty = self.air.typeOf(operand);8591 const ty = self.typeOf(operand);
8588 const mcv = try self.resolveInst(operand);8592 const mcv = try self.resolveInst(operand);
85898593
8590 const name = self.air.nullTerminatedString(pl_op.payload);8594 const name = self.air.nullTerminatedString(pl_op.payload);
...@@ -8626,7 +8630,7 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 {...@@ -8626,7 +8630,7 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 {
8626fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {8630fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
8627 const pl_op = self.air.instructions.items(.data)[inst].pl_op;8631 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
8628 const cond = try self.resolveInst(pl_op.operand);8632 const cond = try self.resolveInst(pl_op.operand);
8629 const cond_ty = self.air.typeOf(pl_op.operand);8633 const cond_ty = self.typeOf(pl_op.operand);
8630 const extra = self.air.extraData(Air.CondBr, pl_op.payload);8634 const extra = self.air.extraData(Air.CondBr, pl_op.payload);
8631 const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];8635 const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];
8632 const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];8636 const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
...@@ -8871,7 +8875,7 @@ fn isNonErr(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCVa...@@ -8871,7 +8875,7 @@ fn isNonErr(self: *Self, inst: Air.Inst.Index, ty: Type, operand: MCValue) !MCVa
8871fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {8875fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
8872 const un_op = self.air.instructions.items(.data)[inst].un_op;8876 const un_op = self.air.instructions.items(.data)[inst].un_op;
8873 const operand = try self.resolveInst(un_op);8877 const operand = try self.resolveInst(un_op);
8874 const ty = self.air.typeOf(un_op);8878 const ty = self.typeOf(un_op);
8875 const result = try self.isNull(inst, ty, operand);8879 const result = try self.isNull(inst, ty, operand);
8876 return self.finishAir(inst, result, .{ un_op, .none, .none });8880 return self.finishAir(inst, result, .{ un_op, .none, .none });
8877}8881}
...@@ -8879,7 +8883,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -8879,7 +8883,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
8879fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {8883fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
8880 const un_op = self.air.instructions.items(.data)[inst].un_op;8884 const un_op = self.air.instructions.items(.data)[inst].un_op;
8881 const operand = try self.resolveInst(un_op);8885 const operand = try self.resolveInst(un_op);
8882 const ty = self.air.typeOf(un_op);8886 const ty = self.typeOf(un_op);
8883 const result = try self.isNullPtr(inst, ty, operand);8887 const result = try self.isNullPtr(inst, ty, operand);
8884 return self.finishAir(inst, result, .{ un_op, .none, .none });8888 return self.finishAir(inst, result, .{ un_op, .none, .none });
8885}8889}
...@@ -8887,7 +8891,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -8887,7 +8891,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
8887fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {8891fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
8888 const un_op = self.air.instructions.items(.data)[inst].un_op;8892 const un_op = self.air.instructions.items(.data)[inst].un_op;
8889 const operand = try self.resolveInst(un_op);8893 const operand = try self.resolveInst(un_op);
8890 const ty = self.air.typeOf(un_op);8894 const ty = self.typeOf(un_op);
8891 const result = switch (try self.isNull(inst, ty, operand)) {8895 const result = switch (try self.isNull(inst, ty, operand)) {
8892 .eflags => |cc| .{ .eflags = cc.negate() },8896 .eflags => |cc| .{ .eflags = cc.negate() },
8893 else => unreachable,8897 else => unreachable,
...@@ -8898,7 +8902,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {...@@ -8898,7 +8902,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
8898fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {8902fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
8899 const un_op = self.air.instructions.items(.data)[inst].un_op;8903 const un_op = self.air.instructions.items(.data)[inst].un_op;
8900 const operand = try self.resolveInst(un_op);8904 const operand = try self.resolveInst(un_op);
8901 const ty = self.air.typeOf(un_op);8905 const ty = self.typeOf(un_op);
8902 const result = switch (try self.isNullPtr(inst, ty, operand)) {8906 const result = switch (try self.isNullPtr(inst, ty, operand)) {
8903 .eflags => |cc| .{ .eflags = cc.negate() },8907 .eflags => |cc| .{ .eflags = cc.negate() },
8904 else => unreachable,8908 else => unreachable,
...@@ -8909,7 +8913,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -8909,7 +8913,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
8909fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {8913fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
8910 const un_op = self.air.instructions.items(.data)[inst].un_op;8914 const un_op = self.air.instructions.items(.data)[inst].un_op;
8911 const operand = try self.resolveInst(un_op);8915 const operand = try self.resolveInst(un_op);
8912 const ty = self.air.typeOf(un_op);8916 const ty = self.typeOf(un_op);
8913 const result = try self.isErr(inst, ty, operand);8917 const result = try self.isErr(inst, ty, operand);
8914 return self.finishAir(inst, result, .{ un_op, .none, .none });8918 return self.finishAir(inst, result, .{ un_op, .none, .none });
8915}8919}
...@@ -8932,7 +8936,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -8932,7 +8936,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
8932 break :blk try self.allocRegOrMem(inst, true);8936 break :blk try self.allocRegOrMem(inst, true);
8933 }8937 }
8934 };8938 };
8935 const ptr_ty = self.air.typeOf(un_op);8939 const ptr_ty = self.typeOf(un_op);
8936 try self.load(operand, ptr_ty, operand_ptr);8940 try self.load(operand, ptr_ty, operand_ptr);
89378941
8938 const result = try self.isErr(inst, ptr_ty.childType(), operand);8942 const result = try self.isErr(inst, ptr_ty.childType(), operand);
...@@ -8943,7 +8947,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -8943,7 +8947,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
8943fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {8947fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
8944 const un_op = self.air.instructions.items(.data)[inst].un_op;8948 const un_op = self.air.instructions.items(.data)[inst].un_op;
8945 const operand = try self.resolveInst(un_op);8949 const operand = try self.resolveInst(un_op);
8946 const ty = self.air.typeOf(un_op);8950 const ty = self.typeOf(un_op);
8947 const result = try self.isNonErr(inst, ty, operand);8951 const result = try self.isNonErr(inst, ty, operand);
8948 return self.finishAir(inst, result, .{ un_op, .none, .none });8952 return self.finishAir(inst, result, .{ un_op, .none, .none });
8949}8953}
...@@ -8966,7 +8970,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -8966,7 +8970,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
8966 break :blk try self.allocRegOrMem(inst, true);8970 break :blk try self.allocRegOrMem(inst, true);
8967 }8971 }
8968 };8972 };
8969 const ptr_ty = self.air.typeOf(un_op);8973 const ptr_ty = self.typeOf(un_op);
8970 try self.load(operand, ptr_ty, operand_ptr);8974 try self.load(operand, ptr_ty, operand_ptr);
89718975
8972 const result = try self.isNonErr(inst, ptr_ty.childType(), operand);8976 const result = try self.isNonErr(inst, ptr_ty.childType(), operand);
...@@ -9032,7 +9036,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -9032,7 +9036,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
9032fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {9036fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
9033 const pl_op = self.air.instructions.items(.data)[inst].pl_op;9037 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
9034 const condition = try self.resolveInst(pl_op.operand);9038 const condition = try self.resolveInst(pl_op.operand);
9035 const condition_ty = self.air.typeOf(pl_op.operand);9039 const condition_ty = self.typeOf(pl_op.operand);
9036 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);9040 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
9037 var extra_index: usize = switch_br.end;9041 var extra_index: usize = switch_br.end;
9038 var case_i: u32 = 0;9042 var case_i: u32 = 0;
...@@ -9119,7 +9123,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -9119,7 +9123,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
9119 const br = self.air.instructions.items(.data)[inst].br;9123 const br = self.air.instructions.items(.data)[inst].br;
9120 const src_mcv = try self.resolveInst(br.operand);9124 const src_mcv = try self.resolveInst(br.operand);
91219125
9122 const block_ty = self.air.typeOfIndex(br.block_inst);9126 const block_ty = self.typeOfIndex(br.block_inst);
9123 const block_unused =9127 const block_unused =
9124 !block_ty.hasRuntimeBitsIgnoreComptime(mod) or self.liveness.isUnused(br.block_inst);9128 !block_ty.hasRuntimeBitsIgnoreComptime(mod) or self.liveness.isUnused(br.block_inst);
9125 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;9129 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;
...@@ -9244,7 +9248,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -9244,7 +9248,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
92449248
9245 const arg_mcv = try self.resolveInst(input);9249 const arg_mcv = try self.resolveInst(input);
9246 try self.register_manager.getReg(reg, null);9250 try self.register_manager.getReg(reg, null);
9247 try self.genSetReg(reg, self.air.typeOf(input), arg_mcv);9251 try self.genSetReg(reg, self.typeOf(input), arg_mcv);
9248 }9252 }
92499253
9250 {9254 {
...@@ -10169,7 +10173,7 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -10169,7 +10173,7 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void {
10169 if (self.reuseOperand(inst, un_op, 0, src_mcv)) break :result src_mcv;10173 if (self.reuseOperand(inst, un_op, 0, src_mcv)) break :result src_mcv;
1017010174
10171 const dst_mcv = try self.allocRegOrMem(inst, true);10175 const dst_mcv = try self.allocRegOrMem(inst, true);
10172 const dst_ty = self.air.typeOfIndex(inst);10176 const dst_ty = self.typeOfIndex(inst);
10173 try self.genCopy(dst_ty, dst_mcv, src_mcv);10177 try self.genCopy(dst_ty, dst_mcv, src_mcv);
10174 break :result dst_mcv;10178 break :result dst_mcv;
10175 };10179 };
...@@ -10179,8 +10183,8 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -10179,8 +10183,8 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void {
10179fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {10183fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
10180 const mod = self.bin_file.options.module.?;10184 const mod = self.bin_file.options.module.?;
10181 const ty_op = self.air.instructions.items(.data)[inst].ty_op;10185 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
10182 const dst_ty = self.air.typeOfIndex(inst);10186 const dst_ty = self.typeOfIndex(inst);
10183 const src_ty = self.air.typeOf(ty_op.operand);10187 const src_ty = self.typeOf(ty_op.operand);
1018410188
10185 const result = result: {10189 const result = result: {
10186 const dst_rc = regClassForType(dst_ty, mod);10190 const dst_rc = regClassForType(dst_ty, mod);
...@@ -10241,8 +10245,8 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -10241,8 +10245,8 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
10241 const mod = self.bin_file.options.module.?;10245 const mod = self.bin_file.options.module.?;
10242 const ty_op = self.air.instructions.items(.data)[inst].ty_op;10246 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1024310247
10244 const slice_ty = self.air.typeOfIndex(inst);10248 const slice_ty = self.typeOfIndex(inst);
10245 const ptr_ty = self.air.typeOf(ty_op.operand);10249 const ptr_ty = self.typeOf(ty_op.operand);
10246 const ptr = try self.resolveInst(ty_op.operand);10250 const ptr = try self.resolveInst(ty_op.operand);
10247 const array_ty = ptr_ty.childType();10251 const array_ty = ptr_ty.childType();
10248 const array_len = array_ty.arrayLen();10252 const array_len = array_ty.arrayLen();
...@@ -10264,11 +10268,11 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {...@@ -10264,11 +10268,11 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
10264 const mod = self.bin_file.options.module.?;10268 const mod = self.bin_file.options.module.?;
10265 const ty_op = self.air.instructions.items(.data)[inst].ty_op;10269 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1026610270
10267 const src_ty = self.air.typeOf(ty_op.operand);10271 const src_ty = self.typeOf(ty_op.operand);
10268 const src_bits = @intCast(u32, src_ty.bitSize(mod));10272 const src_bits = @intCast(u32, src_ty.bitSize(mod));
10269 const src_signedness =10273 const src_signedness =
10270 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;10274 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;
10271 const dst_ty = self.air.typeOfIndex(inst);10275 const dst_ty = self.typeOfIndex(inst);
1027210276
10273 const src_size = math.divCeil(u32, @max(switch (src_signedness) {10277 const src_size = math.divCeil(u32, @max(switch (src_signedness) {
10274 .signed => src_bits,10278 .signed => src_bits,
...@@ -10318,8 +10322,8 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {...@@ -10318,8 +10322,8 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
10318 const mod = self.bin_file.options.module.?;10322 const mod = self.bin_file.options.module.?;
10319 const ty_op = self.air.instructions.items(.data)[inst].ty_op;10323 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1032010324
10321 const src_ty = self.air.typeOf(ty_op.operand);10325 const src_ty = self.typeOf(ty_op.operand);
10322 const dst_ty = self.air.typeOfIndex(inst);10326 const dst_ty = self.typeOfIndex(inst);
10323 const dst_bits = @intCast(u32, dst_ty.bitSize(mod));10327 const dst_bits = @intCast(u32, dst_ty.bitSize(mod));
10324 const dst_signedness =10328 const dst_signedness =
10325 if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned;10329 if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned;
...@@ -10371,8 +10375,8 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {...@@ -10371,8 +10375,8 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
10371 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;10375 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
10372 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;10376 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
1037310377
10374 const ptr_ty = self.air.typeOf(extra.ptr);10378 const ptr_ty = self.typeOf(extra.ptr);
10375 const val_ty = self.air.typeOf(extra.expected_value);10379 const val_ty = self.typeOf(extra.expected_value);
10376 const val_abi_size = @intCast(u32, val_ty.abiSize(mod));10380 const val_abi_size = @intCast(u32, val_ty.abiSize(mod));
1037710381
10378 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });10382 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });
...@@ -10712,10 +10716,10 @@ fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void {...@@ -10712,10 +10716,10 @@ fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void {
1071210716
10713 const unused = self.liveness.isUnused(inst);10717 const unused = self.liveness.isUnused(inst);
1071410718
10715 const ptr_ty = self.air.typeOf(pl_op.operand);10719 const ptr_ty = self.typeOf(pl_op.operand);
10716 const ptr_mcv = try self.resolveInst(pl_op.operand);10720 const ptr_mcv = try self.resolveInst(pl_op.operand);
1071710721
10718 const val_ty = self.air.typeOf(extra.operand);10722 const val_ty = self.typeOf(extra.operand);
10719 const val_mcv = try self.resolveInst(extra.operand);10723 const val_mcv = try self.resolveInst(extra.operand);
1072010724
10721 const result =10725 const result =
...@@ -10726,7 +10730,7 @@ fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void {...@@ -10726,7 +10730,7 @@ fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void {
10726fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void {10730fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void {
10727 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;10731 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;
1072810732
10729 const ptr_ty = self.air.typeOf(atomic_load.ptr);10733 const ptr_ty = self.typeOf(atomic_load.ptr);
10730 const ptr_mcv = try self.resolveInst(atomic_load.ptr);10734 const ptr_mcv = try self.resolveInst(atomic_load.ptr);
10731 const ptr_lock = switch (ptr_mcv) {10735 const ptr_lock = switch (ptr_mcv) {
10732 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),10736 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
...@@ -10747,10 +10751,10 @@ fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -10747,10 +10751,10 @@ fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void {
10747fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOrder) !void {10751fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOrder) !void {
10748 const bin_op = self.air.instructions.items(.data)[inst].bin_op;10752 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1074910753
10750 const ptr_ty = self.air.typeOf(bin_op.lhs);10754 const ptr_ty = self.typeOf(bin_op.lhs);
10751 const ptr_mcv = try self.resolveInst(bin_op.lhs);10755 const ptr_mcv = try self.resolveInst(bin_op.lhs);
1075210756
10753 const val_ty = self.air.typeOf(bin_op.rhs);10757 const val_ty = self.typeOf(bin_op.rhs);
10754 const val_mcv = try self.resolveInst(bin_op.rhs);10758 const val_mcv = try self.resolveInst(bin_op.rhs);
1075510759
10756 const result = try self.atomicOp(ptr_mcv, val_mcv, ptr_ty, val_ty, true, null, order);10760 const result = try self.atomicOp(ptr_mcv, val_mcv, ptr_ty, val_ty, true, null, order);
...@@ -10768,7 +10772,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -10768,7 +10772,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
10768 const bin_op = self.air.instructions.items(.data)[inst].bin_op;10772 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1076910773
10770 const dst_ptr = try self.resolveInst(bin_op.lhs);10774 const dst_ptr = try self.resolveInst(bin_op.lhs);
10771 const dst_ptr_ty = self.air.typeOf(bin_op.lhs);10775 const dst_ptr_ty = self.typeOf(bin_op.lhs);
10772 const dst_ptr_lock: ?RegisterLock = switch (dst_ptr) {10776 const dst_ptr_lock: ?RegisterLock = switch (dst_ptr) {
10773 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),10777 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
10774 else => null,10778 else => null,
...@@ -10776,7 +10780,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -10776,7 +10780,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
10776 defer if (dst_ptr_lock) |lock| self.register_manager.unlockReg(lock);10780 defer if (dst_ptr_lock) |lock| self.register_manager.unlockReg(lock);
1077710781
10778 const src_val = try self.resolveInst(bin_op.rhs);10782 const src_val = try self.resolveInst(bin_op.rhs);
10779 const elem_ty = self.air.typeOf(bin_op.rhs);10783 const elem_ty = self.typeOf(bin_op.rhs);
10780 const src_val_lock: ?RegisterLock = switch (src_val) {10784 const src_val_lock: ?RegisterLock = switch (src_val) {
10781 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),10785 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
10782 else => null,10786 else => null,
...@@ -10888,7 +10892,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {...@@ -10888,7 +10892,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
10888 const bin_op = self.air.instructions.items(.data)[inst].bin_op;10892 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1088910893
10890 const dst_ptr = try self.resolveInst(bin_op.lhs);10894 const dst_ptr = try self.resolveInst(bin_op.lhs);
10891 const dst_ptr_ty = self.air.typeOf(bin_op.lhs);10895 const dst_ptr_ty = self.typeOf(bin_op.lhs);
10892 const dst_ptr_lock: ?RegisterLock = switch (dst_ptr) {10896 const dst_ptr_lock: ?RegisterLock = switch (dst_ptr) {
10893 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),10897 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
10894 else => null,10898 else => null,
...@@ -10922,8 +10926,8 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {...@@ -10922,8 +10926,8 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
10922fn airTagName(self: *Self, inst: Air.Inst.Index) !void {10926fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
10923 const mod = self.bin_file.options.module.?;10927 const mod = self.bin_file.options.module.?;
10924 const un_op = self.air.instructions.items(.data)[inst].un_op;10928 const un_op = self.air.instructions.items(.data)[inst].un_op;
10925 const inst_ty = self.air.typeOfIndex(inst);10929 const inst_ty = self.typeOfIndex(inst);
10926 const enum_ty = self.air.typeOf(un_op);10930 const enum_ty = self.typeOf(un_op);
1092710931
10928 // We need a properly aligned and sized call frame to be able to call this function.10932 // We need a properly aligned and sized call frame to be able to call this function.
10929 {10933 {
...@@ -10964,7 +10968,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -10964,7 +10968,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
10964 const mod = self.bin_file.options.module.?;10968 const mod = self.bin_file.options.module.?;
10965 const un_op = self.air.instructions.items(.data)[inst].un_op;10969 const un_op = self.air.instructions.items(.data)[inst].un_op;
1096610970
10967 const err_ty = self.air.typeOf(un_op);10971 const err_ty = self.typeOf(un_op);
10968 const err_mcv = try self.resolveInst(un_op);10972 const err_mcv = try self.resolveInst(un_op);
10969 const err_reg = try self.copyToTmpRegister(err_ty, err_mcv);10973 const err_reg = try self.copyToTmpRegister(err_ty, err_mcv);
10970 const err_lock = self.register_manager.lockRegAssumeUnused(err_reg);10974 const err_lock = self.register_manager.lockRegAssumeUnused(err_reg);
...@@ -11046,7 +11050,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -11046,7 +11050,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
11046fn airSplat(self: *Self, inst: Air.Inst.Index) !void {11050fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
11047 const mod = self.bin_file.options.module.?;11051 const mod = self.bin_file.options.module.?;
11048 const ty_op = self.air.instructions.items(.data)[inst].ty_op;11052 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
11049 const vector_ty = self.air.typeOfIndex(inst);11053 const vector_ty = self.typeOfIndex(inst);
11050 const dst_rc = regClassForType(vector_ty, mod);11054 const dst_rc = regClassForType(vector_ty, mod);
11051 const scalar_ty = vector_ty.scalarType(mod);11055 const scalar_ty = vector_ty.scalarType(mod);
1105211056
...@@ -11266,7 +11270,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {...@@ -11266,7 +11270,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
1126611270
11267fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {11271fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11268 const mod = self.bin_file.options.module.?;11272 const mod = self.bin_file.options.module.?;
11269 const result_ty = self.air.typeOfIndex(inst);11273 const result_ty = self.typeOfIndex(inst);
11270 const len = @intCast(usize, result_ty.arrayLen());11274 const len = @intCast(usize, result_ty.arrayLen());
11271 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;11275 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
11272 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);11276 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
...@@ -11411,10 +11415,10 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -11411,10 +11415,10 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
11411 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;11415 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
11412 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;11416 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
11413 const result: MCValue = result: {11417 const result: MCValue = result: {
11414 const union_ty = self.air.typeOfIndex(inst);11418 const union_ty = self.typeOfIndex(inst);
11415 const layout = union_ty.unionGetLayout(mod);11419 const layout = union_ty.unionGetLayout(mod);
1141611420
11417 const src_ty = self.air.typeOf(extra.init);11421 const src_ty = self.typeOf(extra.init);
11418 const src_mcv = try self.resolveInst(extra.init);11422 const src_mcv = try self.resolveInst(extra.init);
11419 if (layout.tag_size == 0) {11423 if (layout.tag_size == 0) {
11420 if (self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv;11424 if (self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv;
...@@ -11461,7 +11465,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -11461,7 +11465,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
11461 const mod = self.bin_file.options.module.?;11465 const mod = self.bin_file.options.module.?;
11462 const pl_op = self.air.instructions.items(.data)[inst].pl_op;11466 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
11463 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;11467 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
11464 const ty = self.air.typeOfIndex(inst);11468 const ty = self.typeOfIndex(inst);
1146511469
11466 if (!self.hasFeature(.fma)) return self.fail("TODO implement airMulAdd for {}", .{11470 if (!self.hasFeature(.fma)) return self.fail("TODO implement airMulAdd for {}", .{
11467 ty.fmt(self.bin_file.options.module.?),11471 ty.fmt(self.bin_file.options.module.?),
...@@ -11609,7 +11613,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -11609,7 +11613,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
1160911613
11610fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {11614fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
11611 const mod = self.bin_file.options.module.?;11615 const mod = self.bin_file.options.module.?;
11612 const ty = self.air.typeOf(ref);11616 const ty = self.typeOf(ref);
1161311617
11614 // If the type has no codegen bits, no need to store it.11618 // If the type has no codegen bits, no need to store it.
11615 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;11619 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;
...@@ -11713,7 +11717,7 @@ fn resolveCallingConventionValues(...@@ -11713,7 +11717,7 @@ fn resolveCallingConventionValues(
11713 defer self.gpa.free(param_types);11717 defer self.gpa.free(param_types);
11714 fn_ty.fnParamTypes(param_types);11718 fn_ty.fnParamTypes(param_types);
11715 // TODO: promote var arg types11719 // TODO: promote var arg types
11716 for (param_types[param_len..], var_args) |*param_ty, arg| param_ty.* = self.air.typeOf(arg);11720 for (param_types[param_len..], var_args) |*param_ty, arg| param_ty.* = self.typeOf(arg);
11717 var result: CallMCValues = .{11721 var result: CallMCValues = .{
11718 .args = try self.gpa.alloc(MCValue, param_types.len),11722 .args = try self.gpa.alloc(MCValue, param_types.len),
11719 // These undefined values must be populated before returning from this function.11723 // These undefined values must be populated before returning from this function.
...@@ -12023,3 +12027,13 @@ fn hasAnyFeatures(self: *Self, features: anytype) bool {...@@ -12023,3 +12027,13 @@ fn hasAnyFeatures(self: *Self, features: anytype) bool {
12023fn hasAllFeatures(self: *Self, features: anytype) bool {12027fn hasAllFeatures(self: *Self, features: anytype) bool {
12024 return Target.x86.featureSetHasAll(self.target.cpu.features, features);12028 return Target.x86.featureSetHasAll(self.target.cpu.features, features);
12025}12029}
12030
12031fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
12032 const mod = self.bin_file.options.module.?;
12033 return self.air.typeOf(inst, mod.intern_pool);
12034}
12035
12036fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
12037 const mod = self.bin_file.options.module.?;
12038 return self.air.typeOfIndex(inst, mod.intern_pool);
12039}
src/codegen/c.zig+140-128
...@@ -288,7 +288,7 @@ pub const Function = struct {...@@ -288,7 +288,7 @@ pub const Function = struct {
288288
289 const mod = f.object.dg.module;289 const mod = f.object.dg.module;
290 const val = f.air.value(ref, mod).?;290 const val = f.air.value(ref, mod).?;
291 const ty = f.air.typeOf(ref);291 const ty = f.typeOf(ref);
292292
293 const result: CValue = if (lowersToArray(ty, mod)) result: {293 const result: CValue = if (lowersToArray(ty, mod)) result: {
294 const writer = f.object.code_header.writer();294 const writer = f.object.code_header.writer();
...@@ -355,7 +355,7 @@ pub const Function = struct {...@@ -355,7 +355,7 @@ pub const Function = struct {
355 switch (c_value) {355 switch (c_value) {
356 .constant => |inst| {356 .constant => |inst| {
357 const mod = f.object.dg.module;357 const mod = f.object.dg.module;
358 const ty = f.air.typeOf(inst);358 const ty = f.typeOf(inst);
359 const val = f.air.value(inst, mod).?;359 const val = f.air.value(inst, mod).?;
360 return f.object.dg.renderValue(w, ty, val, location);360 return f.object.dg.renderValue(w, ty, val, location);
361 },361 },
...@@ -368,7 +368,7 @@ pub const Function = struct {...@@ -368,7 +368,7 @@ pub const Function = struct {
368 switch (c_value) {368 switch (c_value) {
369 .constant => |inst| {369 .constant => |inst| {
370 const mod = f.object.dg.module;370 const mod = f.object.dg.module;
371 const ty = f.air.typeOf(inst);371 const ty = f.typeOf(inst);
372 const val = f.air.value(inst, mod).?;372 const val = f.air.value(inst, mod).?;
373 try w.writeAll("(*");373 try w.writeAll("(*");
374 try f.object.dg.renderValue(w, ty, val, .Other);374 try f.object.dg.renderValue(w, ty, val, .Other);
...@@ -382,7 +382,7 @@ pub const Function = struct {...@@ -382,7 +382,7 @@ pub const Function = struct {
382 switch (c_value) {382 switch (c_value) {
383 .constant => |inst| {383 .constant => |inst| {
384 const mod = f.object.dg.module;384 const mod = f.object.dg.module;
385 const ty = f.air.typeOf(inst);385 const ty = f.typeOf(inst);
386 const val = f.air.value(inst, mod).?;386 const val = f.air.value(inst, mod).?;
387 try f.object.dg.renderValue(w, ty, val, .Other);387 try f.object.dg.renderValue(w, ty, val, .Other);
388 try w.writeByte('.');388 try w.writeByte('.');
...@@ -396,7 +396,7 @@ pub const Function = struct {...@@ -396,7 +396,7 @@ pub const Function = struct {
396 switch (c_value) {396 switch (c_value) {
397 .constant => |inst| {397 .constant => |inst| {
398 const mod = f.object.dg.module;398 const mod = f.object.dg.module;
399 const ty = f.air.typeOf(inst);399 const ty = f.typeOf(inst);
400 const val = f.air.value(inst, mod).?;400 const val = f.air.value(inst, mod).?;
401 try w.writeByte('(');401 try w.writeByte('(');
402 try f.object.dg.renderValue(w, ty, val, .Other);402 try f.object.dg.renderValue(w, ty, val, .Other);
...@@ -486,6 +486,16 @@ pub const Function = struct {...@@ -486,6 +486,16 @@ pub const Function = struct {
486 f.object.dg.ctypes.deinit(gpa);486 f.object.dg.ctypes.deinit(gpa);
487 f.object.dg.fwd_decl.deinit();487 f.object.dg.fwd_decl.deinit();
488 }488 }
489
490 fn typeOf(f: *Function, inst: Air.Inst.Ref) Type {
491 const mod = f.object.dg.module;
492 return f.air.typeOf(inst, mod.intern_pool);
493 }
494
495 fn typeOfIndex(f: *Function, inst: Air.Inst.Index) Type {
496 const mod = f.object.dg.module;
497 return f.air.typeOfIndex(inst, mod.intern_pool);
498 }
489};499};
490500
491/// This data is available when outputting .c code for a `Module`.501/// This data is available when outputting .c code for a `Module`.
...@@ -2802,17 +2812,19 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con...@@ -2802,17 +2812,19 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
28022812
2803fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {2813fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {
2804 const mod = f.object.dg.module;2814 const mod = f.object.dg.module;
2815 const ip = &mod.intern_pool;
2805 const air_tags = f.air.instructions.items(.tag);2816 const air_tags = f.air.instructions.items(.tag);
28062817
2807 for (body) |inst| {2818 for (body) |inst| {
2808 if (f.liveness.isUnused(inst) and !f.air.mustLower(inst)) {2819 if (f.liveness.isUnused(inst) and !f.air.mustLower(inst, ip.*))
2809 continue;2820 continue;
2810 }
28112821
2812 const result_value = switch (air_tags[inst]) {2822 const result_value = switch (air_tags[inst]) {
2813 // zig fmt: off2823 // zig fmt: off
2814 .constant => unreachable, // excluded from function bodies2824 .constant => unreachable, // excluded from function bodies
2815 .const_ty => unreachable, // excluded from function bodies2825 .const_ty => unreachable, // excluded from function bodies
2826 .interned => unreachable, // excluded from function bodies
2827
2816 .arg => try airArg(f, inst),2828 .arg => try airArg(f, inst),
28172829
2818 .trap => try airTrap(f.object.writer()),2830 .trap => try airTrap(f.object.writer()),
...@@ -2837,7 +2849,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -2837,7 +2849,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
2837 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),2849 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),
2838 .rem => blk: {2850 .rem => blk: {
2839 const bin_op = f.air.instructions.items(.data)[inst].bin_op;2851 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2840 const lhs_scalar_ty = f.air.typeOf(bin_op.lhs).scalarType(mod);2852 const lhs_scalar_ty = f.typeOf(bin_op.lhs).scalarType(mod);
2841 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),2853 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
2842 // so we only check one.2854 // so we only check one.
2843 break :blk if (lhs_scalar_ty.isInt(mod))2855 break :blk if (lhs_scalar_ty.isInt(mod))
...@@ -3088,7 +3100,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -3088,7 +3100,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
3088fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: []const u8) !CValue {3100fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: []const u8) !CValue {
3089 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3101 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
30903102
3091 const inst_ty = f.air.typeOfIndex(inst);3103 const inst_ty = f.typeOfIndex(inst);
3092 const operand = try f.resolveInst(ty_op.operand);3104 const operand = try f.resolveInst(ty_op.operand);
3093 try reap(f, inst, &.{ty_op.operand});3105 try reap(f, inst, &.{ty_op.operand});
30943106
...@@ -3107,7 +3119,7 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [...@@ -3107,7 +3119,7 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
31073119
3108fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3120fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3109 const mod = f.object.dg.module;3121 const mod = f.object.dg.module;
3110 const inst_ty = f.air.typeOfIndex(inst);3122 const inst_ty = f.typeOfIndex(inst);
3111 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3123 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3112 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {3124 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3113 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3125 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
...@@ -3136,8 +3148,8 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3136,8 +3148,8 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3136 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3148 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3137 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3149 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
31383150
3139 const inst_ty = f.air.typeOfIndex(inst);3151 const inst_ty = f.typeOfIndex(inst);
3140 const ptr_ty = f.air.typeOf(bin_op.lhs);3152 const ptr_ty = f.typeOf(bin_op.lhs);
3141 const elem_ty = ptr_ty.childType();3153 const elem_ty = ptr_ty.childType();
3142 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);3154 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);
31433155
...@@ -3169,7 +3181,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3169,7 +3181,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
31693181
3170fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3182fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3171 const mod = f.object.dg.module;3183 const mod = f.object.dg.module;
3172 const inst_ty = f.air.typeOfIndex(inst);3184 const inst_ty = f.typeOfIndex(inst);
3173 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3185 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3174 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {3186 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3175 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3187 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
...@@ -3198,8 +3210,8 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3198,8 +3210,8 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3198 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;3210 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
3199 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;3211 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
32003212
3201 const inst_ty = f.air.typeOfIndex(inst);3213 const inst_ty = f.typeOfIndex(inst);
3202 const slice_ty = f.air.typeOf(bin_op.lhs);3214 const slice_ty = f.typeOf(bin_op.lhs);
3203 const elem_ty = slice_ty.elemType2(mod);3215 const elem_ty = slice_ty.elemType2(mod);
3204 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);3216 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);
32053217
...@@ -3226,7 +3238,7 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3226,7 +3238,7 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3226fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {3238fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3227 const mod = f.object.dg.module;3239 const mod = f.object.dg.module;
3228 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3240 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3229 const inst_ty = f.air.typeOfIndex(inst);3241 const inst_ty = f.typeOfIndex(inst);
3230 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {3242 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3231 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3243 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3232 return .none;3244 return .none;
...@@ -3251,7 +3263,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3251,7 +3263,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
32513263
3252fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {3264fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3253 const mod = f.object.dg.module;3265 const mod = f.object.dg.module;
3254 const inst_ty = f.air.typeOfIndex(inst);3266 const inst_ty = f.typeOfIndex(inst);
3255 const elem_type = inst_ty.elemType();3267 const elem_type = inst_ty.elemType();
3256 if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty };3268 if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty };
32573269
...@@ -3267,7 +3279,7 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3267,7 +3279,7 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
32673279
3268fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {3280fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3269 const mod = f.object.dg.module;3281 const mod = f.object.dg.module;
3270 const inst_ty = f.air.typeOfIndex(inst);3282 const inst_ty = f.typeOfIndex(inst);
3271 const elem_ty = inst_ty.elemType();3283 const elem_ty = inst_ty.elemType();
3272 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty };3284 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty };
32733285
...@@ -3282,7 +3294,7 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3282,7 +3294,7 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3282}3294}
32833295
3284fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {3296fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
3285 const inst_ty = f.air.typeOfIndex(inst);3297 const inst_ty = f.typeOfIndex(inst);
3286 const inst_cty = try f.typeToIndex(inst_ty, .parameter);3298 const inst_cty = try f.typeToIndex(inst_ty, .parameter);
32873299
3288 const i = f.next_arg_index;3300 const i = f.next_arg_index;
...@@ -3309,7 +3321,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3309,7 +3321,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3309 const mod = f.object.dg.module;3321 const mod = f.object.dg.module;
3310 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3322 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
33113323
3312 const ptr_ty = f.air.typeOf(ty_op.operand);3324 const ptr_ty = f.typeOf(ty_op.operand);
3313 const ptr_scalar_ty = ptr_ty.scalarType(mod);3325 const ptr_scalar_ty = ptr_ty.scalarType(mod);
3314 const ptr_info = ptr_scalar_ty.ptrInfo().data;3326 const ptr_info = ptr_scalar_ty.ptrInfo().data;
3315 const src_ty = ptr_info.pointee_type;3327 const src_ty = ptr_info.pointee_type;
...@@ -3399,7 +3411,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {...@@ -3399,7 +3411,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3399 const un_op = f.air.instructions.items(.data)[inst].un_op;3411 const un_op = f.air.instructions.items(.data)[inst].un_op;
3400 const writer = f.object.writer();3412 const writer = f.object.writer();
3401 const op_inst = Air.refToIndex(un_op);3413 const op_inst = Air.refToIndex(un_op);
3402 const op_ty = f.air.typeOf(un_op);3414 const op_ty = f.typeOf(un_op);
3403 const ret_ty = if (is_ptr) op_ty.childType() else op_ty;3415 const ret_ty = if (is_ptr) op_ty.childType() else op_ty;
3404 var lowered_ret_buf: LowerFnRetTyBuffer = undefined;3416 var lowered_ret_buf: LowerFnRetTyBuffer = undefined;
3405 const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, mod);3417 const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, mod);
...@@ -3453,9 +3465,9 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3453,9 +3465,9 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
3453 const operand = try f.resolveInst(ty_op.operand);3465 const operand = try f.resolveInst(ty_op.operand);
3454 try reap(f, inst, &.{ty_op.operand});3466 try reap(f, inst, &.{ty_op.operand});
34553467
3456 const inst_ty = f.air.typeOfIndex(inst);3468 const inst_ty = f.typeOfIndex(inst);
3457 const inst_scalar_ty = inst_ty.scalarType(mod);3469 const inst_scalar_ty = inst_ty.scalarType(mod);
3458 const operand_ty = f.air.typeOf(ty_op.operand);3470 const operand_ty = f.typeOf(ty_op.operand);
3459 const scalar_ty = operand_ty.scalarType(mod);3471 const scalar_ty = operand_ty.scalarType(mod);
34603472
3461 const writer = f.object.writer();3473 const writer = f.object.writer();
...@@ -3478,13 +3490,13 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3478,13 +3490,13 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
34783490
3479 const operand = try f.resolveInst(ty_op.operand);3491 const operand = try f.resolveInst(ty_op.operand);
3480 try reap(f, inst, &.{ty_op.operand});3492 try reap(f, inst, &.{ty_op.operand});
3481 const inst_ty = f.air.typeOfIndex(inst);3493 const inst_ty = f.typeOfIndex(inst);
3482 const inst_scalar_ty = inst_ty.scalarType(mod);3494 const inst_scalar_ty = inst_ty.scalarType(mod);
3483 const dest_int_info = inst_scalar_ty.intInfo(mod);3495 const dest_int_info = inst_scalar_ty.intInfo(mod);
3484 const dest_bits = dest_int_info.bits;3496 const dest_bits = dest_int_info.bits;
3485 const dest_c_bits = toCIntBits(dest_int_info.bits) orelse3497 const dest_c_bits = toCIntBits(dest_int_info.bits) orelse
3486 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});3498 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
3487 const operand_ty = f.air.typeOf(ty_op.operand);3499 const operand_ty = f.typeOf(ty_op.operand);
3488 const scalar_ty = operand_ty.scalarType(mod);3500 const scalar_ty = operand_ty.scalarType(mod);
3489 const scalar_int_info = scalar_ty.intInfo(mod);3501 const scalar_int_info = scalar_ty.intInfo(mod);
34903502
...@@ -3572,7 +3584,7 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3572,7 +3584,7 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
3572 const operand = try f.resolveInst(un_op);3584 const operand = try f.resolveInst(un_op);
3573 try reap(f, inst, &.{un_op});3585 try reap(f, inst, &.{un_op});
3574 const writer = f.object.writer();3586 const writer = f.object.writer();
3575 const inst_ty = f.air.typeOfIndex(inst);3587 const inst_ty = f.typeOfIndex(inst);
3576 const local = try f.allocLocal(inst, inst_ty);3588 const local = try f.allocLocal(inst, inst_ty);
3577 const a = try Assignment.start(f, writer, inst_ty);3589 const a = try Assignment.start(f, writer, inst_ty);
3578 try f.writeCValue(writer, local, .Other);3590 try f.writeCValue(writer, local, .Other);
...@@ -3587,12 +3599,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -3587,12 +3599,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3587 // *a = b;3599 // *a = b;
3588 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3600 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
35893601
3590 const ptr_ty = f.air.typeOf(bin_op.lhs);3602 const ptr_ty = f.typeOf(bin_op.lhs);
3591 const ptr_scalar_ty = ptr_ty.scalarType(mod);3603 const ptr_scalar_ty = ptr_ty.scalarType(mod);
3592 const ptr_info = ptr_scalar_ty.ptrInfo().data;3604 const ptr_info = ptr_scalar_ty.ptrInfo().data;
35933605
3594 const ptr_val = try f.resolveInst(bin_op.lhs);3606 const ptr_val = try f.resolveInst(bin_op.lhs);
3595 const src_ty = f.air.typeOf(bin_op.rhs);3607 const src_ty = f.typeOf(bin_op.rhs);
35963608
3597 const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep() else false;3609 const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep() else false;
35983610
...@@ -3737,8 +3749,8 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -3737,8 +3749,8 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
3737 const rhs = try f.resolveInst(bin_op.rhs);3749 const rhs = try f.resolveInst(bin_op.rhs);
3738 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3750 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37393751
3740 const inst_ty = f.air.typeOfIndex(inst);3752 const inst_ty = f.typeOfIndex(inst);
3741 const operand_ty = f.air.typeOf(bin_op.lhs);3753 const operand_ty = f.typeOf(bin_op.lhs);
3742 const scalar_ty = operand_ty.scalarType(mod);3754 const scalar_ty = operand_ty.scalarType(mod);
37433755
3744 const w = f.object.writer();3756 const w = f.object.writer();
...@@ -3769,14 +3781,14 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -3769,14 +3781,14 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
3769fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {3781fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
3770 const mod = f.object.dg.module;3782 const mod = f.object.dg.module;
3771 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3783 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
3772 const operand_ty = f.air.typeOf(ty_op.operand);3784 const operand_ty = f.typeOf(ty_op.operand);
3773 const scalar_ty = operand_ty.scalarType(mod);3785 const scalar_ty = operand_ty.scalarType(mod);
3774 if (scalar_ty.tag() != .bool) return try airUnBuiltinCall(f, inst, "not", .bits);3786 if (scalar_ty.tag() != .bool) return try airUnBuiltinCall(f, inst, "not", .bits);
37753787
3776 const op = try f.resolveInst(ty_op.operand);3788 const op = try f.resolveInst(ty_op.operand);
3777 try reap(f, inst, &.{ty_op.operand});3789 try reap(f, inst, &.{ty_op.operand});
37783790
3779 const inst_ty = f.air.typeOfIndex(inst);3791 const inst_ty = f.typeOfIndex(inst);
37803792
3781 const writer = f.object.writer();3793 const writer = f.object.writer();
3782 const local = try f.allocLocal(inst, inst_ty);3794 const local = try f.allocLocal(inst, inst_ty);
...@@ -3802,7 +3814,7 @@ fn airBinOp(...@@ -3802,7 +3814,7 @@ fn airBinOp(
3802) !CValue {3814) !CValue {
3803 const mod = f.object.dg.module;3815 const mod = f.object.dg.module;
3804 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3816 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3805 const operand_ty = f.air.typeOf(bin_op.lhs);3817 const operand_ty = f.typeOf(bin_op.lhs);
3806 const scalar_ty = operand_ty.scalarType(mod);3818 const scalar_ty = operand_ty.scalarType(mod);
3807 if ((scalar_ty.isInt(mod) and scalar_ty.bitSize(mod) > 64) or scalar_ty.isRuntimeFloat())3819 if ((scalar_ty.isInt(mod) and scalar_ty.bitSize(mod) > 64) or scalar_ty.isRuntimeFloat())
3808 return try airBinBuiltinCall(f, inst, operation, info);3820 return try airBinBuiltinCall(f, inst, operation, info);
...@@ -3811,7 +3823,7 @@ fn airBinOp(...@@ -3811,7 +3823,7 @@ fn airBinOp(
3811 const rhs = try f.resolveInst(bin_op.rhs);3823 const rhs = try f.resolveInst(bin_op.rhs);
3812 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3824 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
38133825
3814 const inst_ty = f.air.typeOfIndex(inst);3826 const inst_ty = f.typeOfIndex(inst);
38153827
3816 const writer = f.object.writer();3828 const writer = f.object.writer();
3817 const local = try f.allocLocal(inst, inst_ty);3829 const local = try f.allocLocal(inst, inst_ty);
...@@ -3839,7 +3851,7 @@ fn airCmpOp(...@@ -3839,7 +3851,7 @@ fn airCmpOp(
3839 operator: std.math.CompareOperator,3851 operator: std.math.CompareOperator,
3840) !CValue {3852) !CValue {
3841 const mod = f.object.dg.module;3853 const mod = f.object.dg.module;
3842 const lhs_ty = f.air.typeOf(data.lhs);3854 const lhs_ty = f.typeOf(data.lhs);
3843 const scalar_ty = lhs_ty.scalarType(mod);3855 const scalar_ty = lhs_ty.scalarType(mod);
38443856
3845 const scalar_bits = scalar_ty.bitSize(mod);3857 const scalar_bits = scalar_ty.bitSize(mod);
...@@ -3855,12 +3867,12 @@ fn airCmpOp(...@@ -3855,12 +3867,12 @@ fn airCmpOp(
3855 if (scalar_ty.isRuntimeFloat())3867 if (scalar_ty.isRuntimeFloat())
3856 return airCmpBuiltinCall(f, inst, data, operator, .operator, .none);3868 return airCmpBuiltinCall(f, inst, data, operator, .operator, .none);
38573869
3858 const inst_ty = f.air.typeOfIndex(inst);3870 const inst_ty = f.typeOfIndex(inst);
3859 const lhs = try f.resolveInst(data.lhs);3871 const lhs = try f.resolveInst(data.lhs);
3860 const rhs = try f.resolveInst(data.rhs);3872 const rhs = try f.resolveInst(data.rhs);
3861 try reap(f, inst, &.{ data.lhs, data.rhs });3873 try reap(f, inst, &.{ data.lhs, data.rhs });
38623874
3863 const rhs_ty = f.air.typeOf(data.rhs);3875 const rhs_ty = f.typeOf(data.rhs);
3864 const need_cast = lhs_ty.isSinglePointer() or rhs_ty.isSinglePointer();3876 const need_cast = lhs_ty.isSinglePointer() or rhs_ty.isSinglePointer();
3865 const writer = f.object.writer();3877 const writer = f.object.writer();
3866 const local = try f.allocLocal(inst, inst_ty);3878 const local = try f.allocLocal(inst, inst_ty);
...@@ -3891,7 +3903,7 @@ fn airEquality(...@@ -3891,7 +3903,7 @@ fn airEquality(
3891 const mod = f.object.dg.module;3903 const mod = f.object.dg.module;
3892 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3904 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
38933905
3894 const operand_ty = f.air.typeOf(bin_op.lhs);3906 const operand_ty = f.typeOf(bin_op.lhs);
3895 const operand_bits = operand_ty.bitSize(mod);3907 const operand_bits = operand_ty.bitSize(mod);
3896 if (operand_ty.isInt(mod) and operand_bits > 64)3908 if (operand_ty.isInt(mod) and operand_bits > 64)
3897 return airCmpBuiltinCall(3909 return airCmpBuiltinCall(
...@@ -3910,7 +3922,7 @@ fn airEquality(...@@ -3910,7 +3922,7 @@ fn airEquality(
3910 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3922 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
39113923
3912 const writer = f.object.writer();3924 const writer = f.object.writer();
3913 const inst_ty = f.air.typeOfIndex(inst);3925 const inst_ty = f.typeOfIndex(inst);
3914 const local = try f.allocLocal(inst, inst_ty);3926 const local = try f.allocLocal(inst, inst_ty);
3915 try f.writeCValue(writer, local, .Other);3927 try f.writeCValue(writer, local, .Other);
3916 try writer.writeAll(" = ");3928 try writer.writeAll(" = ");
...@@ -3954,7 +3966,7 @@ fn airEquality(...@@ -3954,7 +3966,7 @@ fn airEquality(
3954fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {3966fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
3955 const un_op = f.air.instructions.items(.data)[inst].un_op;3967 const un_op = f.air.instructions.items(.data)[inst].un_op;
39563968
3957 const inst_ty = f.air.typeOfIndex(inst);3969 const inst_ty = f.typeOfIndex(inst);
3958 const operand = try f.resolveInst(un_op);3970 const operand = try f.resolveInst(un_op);
3959 try reap(f, inst, &.{un_op});3971 try reap(f, inst, &.{un_op});
39603972
...@@ -3976,7 +3988,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {...@@ -3976,7 +3988,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
3976 const rhs = try f.resolveInst(bin_op.rhs);3988 const rhs = try f.resolveInst(bin_op.rhs);
3977 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3989 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
39783990
3979 const inst_ty = f.air.typeOfIndex(inst);3991 const inst_ty = f.typeOfIndex(inst);
3980 const inst_scalar_ty = inst_ty.scalarType(mod);3992 const inst_scalar_ty = inst_ty.scalarType(mod);
3981 const elem_ty = inst_scalar_ty.elemType2(mod);3993 const elem_ty = inst_scalar_ty.elemType2(mod);
39823994
...@@ -4019,7 +4031,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons...@@ -4019,7 +4031,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
4019 const mod = f.object.dg.module;4031 const mod = f.object.dg.module;
4020 const bin_op = f.air.instructions.items(.data)[inst].bin_op;4032 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
40214033
4022 const inst_ty = f.air.typeOfIndex(inst);4034 const inst_ty = f.typeOfIndex(inst);
4023 const inst_scalar_ty = inst_ty.scalarType(mod);4035 const inst_scalar_ty = inst_ty.scalarType(mod);
40244036
4025 if (inst_scalar_ty.isInt(mod) and inst_scalar_ty.bitSize(mod) > 64)4037 if (inst_scalar_ty.isInt(mod) and inst_scalar_ty.bitSize(mod) > 64)
...@@ -4065,7 +4077,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4065,7 +4077,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4065 const len = try f.resolveInst(bin_op.rhs);4077 const len = try f.resolveInst(bin_op.rhs);
4066 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4078 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
40674079
4068 const inst_ty = f.air.typeOfIndex(inst);4080 const inst_ty = f.typeOfIndex(inst);
4069 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4081 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4070 const ptr_ty = inst_ty.slicePtrFieldType(&buf);4082 const ptr_ty = inst_ty.slicePtrFieldType(&buf);
40714083
...@@ -4110,7 +4122,7 @@ fn airCall(...@@ -4110,7 +4122,7 @@ fn airCall(
4110 const resolved_args = try gpa.alloc(CValue, args.len);4122 const resolved_args = try gpa.alloc(CValue, args.len);
4111 defer gpa.free(resolved_args);4123 defer gpa.free(resolved_args);
4112 for (resolved_args, args) |*resolved_arg, arg| {4124 for (resolved_args, args) |*resolved_arg, arg| {
4113 const arg_ty = f.air.typeOf(arg);4125 const arg_ty = f.typeOf(arg);
4114 const arg_cty = try f.typeToIndex(arg_ty, .parameter);4126 const arg_cty = try f.typeToIndex(arg_ty, .parameter);
4115 if (f.indexToCType(arg_cty).tag() == .void) {4127 if (f.indexToCType(arg_cty).tag() == .void) {
4116 resolved_arg.* = .none;4128 resolved_arg.* = .none;
...@@ -4141,7 +4153,7 @@ fn airCall(...@@ -4141,7 +4153,7 @@ fn airCall(
4141 for (args) |arg| try bt.feed(arg);4153 for (args) |arg| try bt.feed(arg);
4142 }4154 }
41434155
4144 const callee_ty = f.air.typeOf(pl_op.operand);4156 const callee_ty = f.typeOf(pl_op.operand);
4145 const fn_ty = switch (callee_ty.zigTypeTag(mod)) {4157 const fn_ty = switch (callee_ty.zigTypeTag(mod)) {
4146 .Fn => callee_ty,4158 .Fn => callee_ty,
4147 .Pointer => callee_ty.childType(),4159 .Pointer => callee_ty.childType(),
...@@ -4279,7 +4291,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4279,7 +4291,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4279 f.next_block_index += 1;4291 f.next_block_index += 1;
4280 const writer = f.object.writer();4292 const writer = f.object.writer();
42814293
4282 const inst_ty = f.air.typeOfIndex(inst);4294 const inst_ty = f.typeOfIndex(inst);
4283 const result = if (inst_ty.tag() != .void and !f.liveness.isUnused(inst))4295 const result = if (inst_ty.tag() != .void and !f.liveness.isUnused(inst))
4284 try f.allocLocal(inst, inst_ty)4296 try f.allocLocal(inst, inst_ty)
4285 else4297 else
...@@ -4302,7 +4314,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4302,7 +4314,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4302 try f.object.indent_writer.insertNewline();4314 try f.object.indent_writer.insertNewline();
43034315
4304 // noreturn blocks have no `br` instructions reaching them, so we don't want a label4316 // noreturn blocks have no `br` instructions reaching them, so we don't want a label
4305 if (!f.air.typeOfIndex(inst).isNoReturn()) {4317 if (!f.typeOfIndex(inst).isNoReturn()) {
4306 // label must be followed by an expression, include an empty one.4318 // label must be followed by an expression, include an empty one.
4307 try writer.print("zig_block_{d}:;\n", .{block_id});4319 try writer.print("zig_block_{d}:;\n", .{block_id});
4308 }4320 }
...@@ -4314,7 +4326,7 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4314,7 +4326,7 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {
4314 const pl_op = f.air.instructions.items(.data)[inst].pl_op;4326 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
4315 const extra = f.air.extraData(Air.Try, pl_op.payload);4327 const extra = f.air.extraData(Air.Try, pl_op.payload);
4316 const body = f.air.extra[extra.end..][0..extra.data.body_len];4328 const body = f.air.extra[extra.end..][0..extra.data.body_len];
4317 const err_union_ty = f.air.typeOf(pl_op.operand);4329 const err_union_ty = f.typeOf(pl_op.operand);
4318 return lowerTry(f, inst, pl_op.operand, body, err_union_ty, false);4330 return lowerTry(f, inst, pl_op.operand, body, err_union_ty, false);
4319}4331}
43204332
...@@ -4322,7 +4334,7 @@ fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4322,7 +4334,7 @@ fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue {
4322 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;4334 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
4323 const extra = f.air.extraData(Air.TryPtr, ty_pl.payload);4335 const extra = f.air.extraData(Air.TryPtr, ty_pl.payload);
4324 const body = f.air.extra[extra.end..][0..extra.data.body_len];4336 const body = f.air.extra[extra.end..][0..extra.data.body_len];
4325 const err_union_ty = f.air.typeOf(extra.data.ptr).childType();4337 const err_union_ty = f.typeOf(extra.data.ptr).childType();
4326 return lowerTry(f, inst, extra.data.ptr, body, err_union_ty, true);4338 return lowerTry(f, inst, extra.data.ptr, body, err_union_ty, true);
4327}4339}
43284340
...@@ -4336,7 +4348,7 @@ fn lowerTry(...@@ -4336,7 +4348,7 @@ fn lowerTry(
4336) !CValue {4348) !CValue {
4337 const mod = f.object.dg.module;4349 const mod = f.object.dg.module;
4338 const err_union = try f.resolveInst(operand);4350 const err_union = try f.resolveInst(operand);
4339 const inst_ty = f.air.typeOfIndex(inst);4351 const inst_ty = f.typeOfIndex(inst);
4340 const liveness_condbr = f.liveness.getCondBr(inst);4352 const liveness_condbr = f.liveness.getCondBr(inst);
4341 const writer = f.object.writer();4353 const writer = f.object.writer();
4342 const payload_ty = err_union_ty.errorUnionPayload();4354 const payload_ty = err_union_ty.errorUnionPayload();
...@@ -4404,7 +4416,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4404,7 +4416,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
44044416
4405 // If result is .none then the value of the block is unused.4417 // If result is .none then the value of the block is unused.
4406 if (result != .none) {4418 if (result != .none) {
4407 const operand_ty = f.air.typeOf(branch.operand);4419 const operand_ty = f.typeOf(branch.operand);
4408 const operand = try f.resolveInst(branch.operand);4420 const operand = try f.resolveInst(branch.operand);
4409 try reap(f, inst, &.{branch.operand});4421 try reap(f, inst, &.{branch.operand});
44104422
...@@ -4421,10 +4433,10 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4421,10 +4433,10 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
44214433
4422fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {4434fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
4423 const ty_op = f.air.instructions.items(.data)[inst].ty_op;4435 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
4424 const dest_ty = f.air.typeOfIndex(inst);4436 const dest_ty = f.typeOfIndex(inst);
44254437
4426 const operand = try f.resolveInst(ty_op.operand);4438 const operand = try f.resolveInst(ty_op.operand);
4427 const operand_ty = f.air.typeOf(ty_op.operand);4439 const operand_ty = f.typeOf(ty_op.operand);
44284440
4429 const bitcasted = try bitcast(f, dest_ty, operand, operand_ty);4441 const bitcasted = try bitcast(f, dest_ty, operand, operand_ty);
4430 try reap(f, inst, &.{ty_op.operand});4442 try reap(f, inst, &.{ty_op.operand});
...@@ -4684,7 +4696,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4684,7 +4696,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4684 const pl_op = f.air.instructions.items(.data)[inst].pl_op;4696 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
4685 const condition = try f.resolveInst(pl_op.operand);4697 const condition = try f.resolveInst(pl_op.operand);
4686 try reap(f, inst, &.{pl_op.operand});4698 try reap(f, inst, &.{pl_op.operand});
4687 const condition_ty = f.air.typeOf(pl_op.operand);4699 const condition_ty = f.typeOf(pl_op.operand);
4688 const switch_br = f.air.extraData(Air.SwitchBr, pl_op.payload);4700 const switch_br = f.air.extraData(Air.SwitchBr, pl_op.payload);
4689 const writer = f.object.writer();4701 const writer = f.object.writer();
46904702
...@@ -4784,7 +4796,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4784,7 +4796,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
47844796
4785 const result = result: {4797 const result = result: {
4786 const writer = f.object.writer();4798 const writer = f.object.writer();
4787 const inst_ty = f.air.typeOfIndex(inst);4799 const inst_ty = f.typeOfIndex(inst);
4788 const local = if (inst_ty.hasRuntimeBitsIgnoreComptime(mod)) local: {4800 const local = if (inst_ty.hasRuntimeBitsIgnoreComptime(mod)) local: {
4789 const local = try f.allocLocal(inst, inst_ty);4801 const local = try f.allocLocal(inst, inst_ty);
4790 if (f.wantSafety()) {4802 if (f.wantSafety()) {
...@@ -4814,7 +4826,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4814,7 +4826,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
48144826
4815 const is_reg = constraint[1] == '{';4827 const is_reg = constraint[1] == '{';
4816 if (is_reg) {4828 if (is_reg) {
4817 const output_ty = if (output == .none) inst_ty else f.air.typeOf(output).childType();4829 const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType();
4818 try writer.writeAll("register ");4830 try writer.writeAll("register ");
4819 const alignment = 0;4831 const alignment = 0;
4820 const local_value = try f.allocLocalValue(output_ty, alignment);4832 const local_value = try f.allocLocalValue(output_ty, alignment);
...@@ -4847,7 +4859,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4847,7 +4859,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4847 const is_reg = constraint[0] == '{';4859 const is_reg = constraint[0] == '{';
4848 const input_val = try f.resolveInst(input);4860 const input_val = try f.resolveInst(input);
4849 if (asmInputNeedsLocal(constraint, input_val)) {4861 if (asmInputNeedsLocal(constraint, input_val)) {
4850 const input_ty = f.air.typeOf(input);4862 const input_ty = f.typeOf(input);
4851 if (is_reg) try writer.writeAll("register ");4863 if (is_reg) try writer.writeAll("register ");
4852 const alignment = 0;4864 const alignment = 0;
4853 const local_value = try f.allocLocalValue(input_ty, alignment);4865 const local_value = try f.allocLocalValue(input_ty, alignment);
...@@ -5048,7 +5060,7 @@ fn airIsNull(...@@ -5048,7 +5060,7 @@ fn airIsNull(
5048 try f.writeCValue(writer, operand, .Other);5060 try f.writeCValue(writer, operand, .Other);
5049 }5061 }
50505062
5051 const operand_ty = f.air.typeOf(un_op);5063 const operand_ty = f.typeOf(un_op);
5052 const optional_ty = if (is_ptr) operand_ty.childType() else operand_ty;5064 const optional_ty = if (is_ptr) operand_ty.childType() else operand_ty;
5053 var payload_buf: Type.Payload.ElemType = undefined;5065 var payload_buf: Type.Payload.ElemType = undefined;
5054 const payload_ty = optional_ty.optionalChild(&payload_buf);5066 const payload_ty = optional_ty.optionalChild(&payload_buf);
...@@ -5083,7 +5095,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5083,7 +5095,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
50835095
5084 const operand = try f.resolveInst(ty_op.operand);5096 const operand = try f.resolveInst(ty_op.operand);
5085 try reap(f, inst, &.{ty_op.operand});5097 try reap(f, inst, &.{ty_op.operand});
5086 const opt_ty = f.air.typeOf(ty_op.operand);5098 const opt_ty = f.typeOf(ty_op.operand);
50875099
5088 var buf: Type.Payload.ElemType = undefined;5100 var buf: Type.Payload.ElemType = undefined;
5089 const payload_ty = opt_ty.optionalChild(&buf);5101 const payload_ty = opt_ty.optionalChild(&buf);
...@@ -5092,7 +5104,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5092,7 +5104,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
5092 return .none;5104 return .none;
5093 }5105 }
50945106
5095 const inst_ty = f.air.typeOfIndex(inst);5107 const inst_ty = f.typeOfIndex(inst);
5096 const writer = f.object.writer();5108 const writer = f.object.writer();
5097 const local = try f.allocLocal(inst, inst_ty);5109 const local = try f.allocLocal(inst, inst_ty);
50985110
...@@ -5119,9 +5131,9 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5119,9 +5131,9 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5119 const writer = f.object.writer();5131 const writer = f.object.writer();
5120 const operand = try f.resolveInst(ty_op.operand);5132 const operand = try f.resolveInst(ty_op.operand);
5121 try reap(f, inst, &.{ty_op.operand});5133 try reap(f, inst, &.{ty_op.operand});
5122 const ptr_ty = f.air.typeOf(ty_op.operand);5134 const ptr_ty = f.typeOf(ty_op.operand);
5123 const opt_ty = ptr_ty.childType();5135 const opt_ty = ptr_ty.childType();
5124 const inst_ty = f.air.typeOfIndex(inst);5136 const inst_ty = f.typeOfIndex(inst);
51255137
5126 if (!inst_ty.childType().hasRuntimeBitsIgnoreComptime(mod)) {5138 if (!inst_ty.childType().hasRuntimeBitsIgnoreComptime(mod)) {
5127 return .{ .undef = inst_ty };5139 return .{ .undef = inst_ty };
...@@ -5149,11 +5161,11 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5149,11 +5161,11 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5149 const writer = f.object.writer();5161 const writer = f.object.writer();
5150 const operand = try f.resolveInst(ty_op.operand);5162 const operand = try f.resolveInst(ty_op.operand);
5151 try reap(f, inst, &.{ty_op.operand});5163 try reap(f, inst, &.{ty_op.operand});
5152 const operand_ty = f.air.typeOf(ty_op.operand);5164 const operand_ty = f.typeOf(ty_op.operand);
51535165
5154 const opt_ty = operand_ty.elemType();5166 const opt_ty = operand_ty.elemType();
51555167
5156 const inst_ty = f.air.typeOfIndex(inst);5168 const inst_ty = f.typeOfIndex(inst);
51575169
5158 if (opt_ty.optionalReprIsPayload(mod)) {5170 if (opt_ty.optionalReprIsPayload(mod)) {
5159 if (f.liveness.isUnused(inst)) {5171 if (f.liveness.isUnused(inst)) {
...@@ -5249,7 +5261,7 @@ fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5249,7 +5261,7 @@ fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue {
52495261
5250 const container_ptr_val = try f.resolveInst(extra.struct_operand);5262 const container_ptr_val = try f.resolveInst(extra.struct_operand);
5251 try reap(f, inst, &.{extra.struct_operand});5263 try reap(f, inst, &.{extra.struct_operand});
5252 const container_ptr_ty = f.air.typeOf(extra.struct_operand);5264 const container_ptr_ty = f.typeOf(extra.struct_operand);
5253 return fieldPtr(f, inst, container_ptr_ty, container_ptr_val, extra.field_index);5265 return fieldPtr(f, inst, container_ptr_ty, container_ptr_val, extra.field_index);
5254}5266}
52555267
...@@ -5258,7 +5270,7 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue...@@ -5258,7 +5270,7 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
52585270
5259 const container_ptr_val = try f.resolveInst(ty_op.operand);5271 const container_ptr_val = try f.resolveInst(ty_op.operand);
5260 try reap(f, inst, &.{ty_op.operand});5272 try reap(f, inst, &.{ty_op.operand});
5261 const container_ptr_ty = f.air.typeOf(ty_op.operand);5273 const container_ptr_ty = f.typeOf(ty_op.operand);
5262 return fieldPtr(f, inst, container_ptr_ty, container_ptr_val, index);5274 return fieldPtr(f, inst, container_ptr_ty, container_ptr_val, index);
5263}5275}
52645276
...@@ -5267,10 +5279,10 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5267,10 +5279,10 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5267 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;5279 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
5268 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;5280 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
52695281
5270 const container_ptr_ty = f.air.typeOfIndex(inst);5282 const container_ptr_ty = f.typeOfIndex(inst);
5271 const container_ty = container_ptr_ty.childType();5283 const container_ty = container_ptr_ty.childType();
52725284
5273 const field_ptr_ty = f.air.typeOf(extra.field_ptr);5285 const field_ptr_ty = f.typeOf(extra.field_ptr);
5274 const field_ptr_val = try f.resolveInst(extra.field_ptr);5286 const field_ptr_val = try f.resolveInst(extra.field_ptr);
5275 try reap(f, inst, &.{extra.field_ptr});5287 try reap(f, inst, &.{extra.field_ptr});
52765288
...@@ -5334,7 +5346,7 @@ fn fieldPtr(...@@ -5334,7 +5346,7 @@ fn fieldPtr(
5334) !CValue {5346) !CValue {
5335 const mod = f.object.dg.module;5347 const mod = f.object.dg.module;
5336 const container_ty = container_ptr_ty.elemType();5348 const container_ty = container_ptr_ty.elemType();
5337 const field_ptr_ty = f.air.typeOfIndex(inst);5349 const field_ptr_ty = f.typeOfIndex(inst);
53385350
5339 // Ensure complete type definition is visible before accessing fields.5351 // Ensure complete type definition is visible before accessing fields.
5340 _ = try f.typeToIndex(container_ty, .complete);5352 _ = try f.typeToIndex(container_ty, .complete);
...@@ -5385,7 +5397,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5385,7 +5397,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5385 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;5397 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
5386 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;5398 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
53875399
5388 const inst_ty = f.air.typeOfIndex(inst);5400 const inst_ty = f.typeOfIndex(inst);
5389 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {5401 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5390 try reap(f, inst, &.{extra.struct_operand});5402 try reap(f, inst, &.{extra.struct_operand});
5391 return .none;5403 return .none;
...@@ -5393,7 +5405,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5393,7 +5405,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
53935405
5394 const struct_byval = try f.resolveInst(extra.struct_operand);5406 const struct_byval = try f.resolveInst(extra.struct_operand);
5395 try reap(f, inst, &.{extra.struct_operand});5407 try reap(f, inst, &.{extra.struct_operand});
5396 const struct_ty = f.air.typeOf(extra.struct_operand);5408 const struct_ty = f.typeOf(extra.struct_operand);
5397 const writer = f.object.writer();5409 const writer = f.object.writer();
53985410
5399 // Ensure complete type definition is visible before accessing fields.5411 // Ensure complete type definition is visible before accessing fields.
...@@ -5514,9 +5526,9 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5514,9 +5526,9 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5514 const mod = f.object.dg.module;5526 const mod = f.object.dg.module;
5515 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5527 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55165528
5517 const inst_ty = f.air.typeOfIndex(inst);5529 const inst_ty = f.typeOfIndex(inst);
5518 const operand = try f.resolveInst(ty_op.operand);5530 const operand = try f.resolveInst(ty_op.operand);
5519 const operand_ty = f.air.typeOf(ty_op.operand);5531 const operand_ty = f.typeOf(ty_op.operand);
5520 try reap(f, inst, &.{ty_op.operand});5532 try reap(f, inst, &.{ty_op.operand});
55215533
5522 const operand_is_ptr = operand_ty.zigTypeTag(mod) == .Pointer;5534 const operand_is_ptr = operand_ty.zigTypeTag(mod) == .Pointer;
...@@ -5553,10 +5565,10 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu...@@ -5553,10 +5565,10 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
5553 const mod = f.object.dg.module;5565 const mod = f.object.dg.module;
5554 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5566 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55555567
5556 const inst_ty = f.air.typeOfIndex(inst);5568 const inst_ty = f.typeOfIndex(inst);
5557 const operand = try f.resolveInst(ty_op.operand);5569 const operand = try f.resolveInst(ty_op.operand);
5558 try reap(f, inst, &.{ty_op.operand});5570 try reap(f, inst, &.{ty_op.operand});
5559 const operand_ty = f.air.typeOf(ty_op.operand);5571 const operand_ty = f.typeOf(ty_op.operand);
5560 const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;5572 const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;
55615573
5562 const writer = f.object.writer();5574 const writer = f.object.writer();
...@@ -5589,9 +5601,9 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5589,9 +5601,9 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
5589 const mod = f.object.dg.module;5601 const mod = f.object.dg.module;
5590 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5602 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55915603
5592 const inst_ty = f.air.typeOfIndex(inst);5604 const inst_ty = f.typeOfIndex(inst);
5593 const repr_is_payload = inst_ty.optionalReprIsPayload(mod);5605 const repr_is_payload = inst_ty.optionalReprIsPayload(mod);
5594 const payload_ty = f.air.typeOf(ty_op.operand);5606 const payload_ty = f.typeOf(ty_op.operand);
5595 const payload = try f.resolveInst(ty_op.operand);5607 const payload = try f.resolveInst(ty_op.operand);
5596 try reap(f, inst, &.{ty_op.operand});5608 try reap(f, inst, &.{ty_op.operand});
55975609
...@@ -5621,7 +5633,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5621,7 +5633,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5621 const mod = f.object.dg.module;5633 const mod = f.object.dg.module;
5622 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5634 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56235635
5624 const inst_ty = f.air.typeOfIndex(inst);5636 const inst_ty = f.typeOfIndex(inst);
5625 const payload_ty = inst_ty.errorUnionPayload();5637 const payload_ty = inst_ty.errorUnionPayload();
5626 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);5638 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5627 const err_ty = inst_ty.errorUnionSet();5639 const err_ty = inst_ty.errorUnionSet();
...@@ -5661,7 +5673,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5661,7 +5673,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5661 const writer = f.object.writer();5673 const writer = f.object.writer();
5662 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5674 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
5663 const operand = try f.resolveInst(ty_op.operand);5675 const operand = try f.resolveInst(ty_op.operand);
5664 const error_union_ty = f.air.typeOf(ty_op.operand).childType();5676 const error_union_ty = f.typeOf(ty_op.operand).childType();
56655677
5666 const error_ty = error_union_ty.errorUnionSet();5678 const error_ty = error_union_ty.errorUnionSet();
5667 const payload_ty = error_union_ty.errorUnionPayload();5679 const payload_ty = error_union_ty.errorUnionPayload();
...@@ -5684,7 +5696,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5684,7 +5696,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5684 // Then return the payload pointer (only if it is used)5696 // Then return the payload pointer (only if it is used)
5685 if (f.liveness.isUnused(inst)) return .none;5697 if (f.liveness.isUnused(inst)) return .none;
56865698
5687 const local = try f.allocLocal(inst, f.air.typeOfIndex(inst));5699 const local = try f.allocLocal(inst, f.typeOfIndex(inst));
5688 try f.writeCValue(writer, local, .Other);5700 try f.writeCValue(writer, local, .Other);
5689 try writer.writeAll(" = &(");5701 try writer.writeAll(" = &(");
5690 try f.writeCValueDeref(writer, operand);5702 try f.writeCValueDeref(writer, operand);
...@@ -5711,7 +5723,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5711,7 +5723,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
5711 const mod = f.object.dg.module;5723 const mod = f.object.dg.module;
5712 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5724 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
57135725
5714 const inst_ty = f.air.typeOfIndex(inst);5726 const inst_ty = f.typeOfIndex(inst);
5715 const payload_ty = inst_ty.errorUnionPayload();5727 const payload_ty = inst_ty.errorUnionPayload();
5716 const payload = try f.resolveInst(ty_op.operand);5728 const payload = try f.resolveInst(ty_op.operand);
5717 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);5729 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
...@@ -5747,7 +5759,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -5747,7 +5759,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
5747 const writer = f.object.writer();5759 const writer = f.object.writer();
5748 const operand = try f.resolveInst(un_op);5760 const operand = try f.resolveInst(un_op);
5749 try reap(f, inst, &.{un_op});5761 try reap(f, inst, &.{un_op});
5750 const operand_ty = f.air.typeOf(un_op);5762 const operand_ty = f.typeOf(un_op);
5751 const local = try f.allocLocal(inst, Type.bool);5763 const local = try f.allocLocal(inst, Type.bool);
5752 const err_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;5764 const err_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;
5753 const payload_ty = err_union_ty.errorUnionPayload();5765 const payload_ty = err_union_ty.errorUnionPayload();
...@@ -5780,10 +5792,10 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5780,10 +5792,10 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
57805792
5781 const operand = try f.resolveInst(ty_op.operand);5793 const operand = try f.resolveInst(ty_op.operand);
5782 try reap(f, inst, &.{ty_op.operand});5794 try reap(f, inst, &.{ty_op.operand});
5783 const inst_ty = f.air.typeOfIndex(inst);5795 const inst_ty = f.typeOfIndex(inst);
5784 const writer = f.object.writer();5796 const writer = f.object.writer();
5785 const local = try f.allocLocal(inst, inst_ty);5797 const local = try f.allocLocal(inst, inst_ty);
5786 const array_ty = f.air.typeOf(ty_op.operand).childType();5798 const array_ty = f.typeOf(ty_op.operand).childType();
57875799
5788 try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });5800 try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
5789 try writer.writeAll(" = ");5801 try writer.writeAll(" = ");
...@@ -5812,10 +5824,10 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5812,10 +5824,10 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
5812 const mod = f.object.dg.module;5824 const mod = f.object.dg.module;
5813 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5825 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
58145826
5815 const inst_ty = f.air.typeOfIndex(inst);5827 const inst_ty = f.typeOfIndex(inst);
5816 const operand = try f.resolveInst(ty_op.operand);5828 const operand = try f.resolveInst(ty_op.operand);
5817 try reap(f, inst, &.{ty_op.operand});5829 try reap(f, inst, &.{ty_op.operand});
5818 const operand_ty = f.air.typeOf(ty_op.operand);5830 const operand_ty = f.typeOf(ty_op.operand);
5819 const target = f.object.dg.module.getTarget();5831 const target = f.object.dg.module.getTarget();
5820 const operation = if (inst_ty.isRuntimeFloat() and operand_ty.isRuntimeFloat())5832 const operation = if (inst_ty.isRuntimeFloat() and operand_ty.isRuntimeFloat())
5821 if (inst_ty.floatBits(target) < operand_ty.floatBits(target)) "trunc" else "extend"5833 if (inst_ty.floatBits(target) < operand_ty.floatBits(target)) "trunc" else "extend"
...@@ -5855,9 +5867,9 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5855,9 +5867,9 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {
5855 const un_op = f.air.instructions.items(.data)[inst].un_op;5867 const un_op = f.air.instructions.items(.data)[inst].un_op;
58565868
5857 const operand = try f.resolveInst(un_op);5869 const operand = try f.resolveInst(un_op);
5858 const operand_ty = f.air.typeOf(un_op);5870 const operand_ty = f.typeOf(un_op);
5859 try reap(f, inst, &.{un_op});5871 try reap(f, inst, &.{un_op});
5860 const inst_ty = f.air.typeOfIndex(inst);5872 const inst_ty = f.typeOfIndex(inst);
5861 const writer = f.object.writer();5873 const writer = f.object.writer();
5862 const local = try f.allocLocal(inst, inst_ty);5874 const local = try f.allocLocal(inst, inst_ty);
5863 try f.writeCValue(writer, local, .Other);5875 try f.writeCValue(writer, local, .Other);
...@@ -5885,9 +5897,9 @@ fn airUnBuiltinCall(...@@ -5885,9 +5897,9 @@ fn airUnBuiltinCall(
58855897
5886 const operand = try f.resolveInst(ty_op.operand);5898 const operand = try f.resolveInst(ty_op.operand);
5887 try reap(f, inst, &.{ty_op.operand});5899 try reap(f, inst, &.{ty_op.operand});
5888 const inst_ty = f.air.typeOfIndex(inst);5900 const inst_ty = f.typeOfIndex(inst);
5889 const inst_scalar_ty = inst_ty.scalarType(mod);5901 const inst_scalar_ty = inst_ty.scalarType(mod);
5890 const operand_ty = f.air.typeOf(ty_op.operand);5902 const operand_ty = f.typeOf(ty_op.operand);
5891 const scalar_ty = operand_ty.scalarType(mod);5903 const scalar_ty = operand_ty.scalarType(mod);
58925904
5893 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);5905 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
...@@ -5927,7 +5939,7 @@ fn airBinBuiltinCall(...@@ -5927,7 +5939,7 @@ fn airBinBuiltinCall(
5927 const mod = f.object.dg.module;5939 const mod = f.object.dg.module;
5928 const bin_op = f.air.instructions.items(.data)[inst].bin_op;5940 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
59295941
5930 const operand_ty = f.air.typeOf(bin_op.lhs);5942 const operand_ty = f.typeOf(bin_op.lhs);
5931 const operand_cty = try f.typeToCType(operand_ty, .complete);5943 const operand_cty = try f.typeToCType(operand_ty, .complete);
5932 const is_big = operand_cty.tag() == .array;5944 const is_big = operand_cty.tag() == .array;
59335945
...@@ -5935,7 +5947,7 @@ fn airBinBuiltinCall(...@@ -5935,7 +5947,7 @@ fn airBinBuiltinCall(
5935 const rhs = try f.resolveInst(bin_op.rhs);5947 const rhs = try f.resolveInst(bin_op.rhs);
5936 if (!is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });5948 if (!is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
59375949
5938 const inst_ty = f.air.typeOfIndex(inst);5950 const inst_ty = f.typeOfIndex(inst);
5939 const inst_scalar_ty = inst_ty.scalarType(mod);5951 const inst_scalar_ty = inst_ty.scalarType(mod);
5940 const scalar_ty = operand_ty.scalarType(mod);5952 const scalar_ty = operand_ty.scalarType(mod);
59415953
...@@ -5984,9 +5996,9 @@ fn airCmpBuiltinCall(...@@ -5984,9 +5996,9 @@ fn airCmpBuiltinCall(
5984 const rhs = try f.resolveInst(data.rhs);5996 const rhs = try f.resolveInst(data.rhs);
5985 try reap(f, inst, &.{ data.lhs, data.rhs });5997 try reap(f, inst, &.{ data.lhs, data.rhs });
59865998
5987 const inst_ty = f.air.typeOfIndex(inst);5999 const inst_ty = f.typeOfIndex(inst);
5988 const inst_scalar_ty = inst_ty.scalarType(mod);6000 const inst_scalar_ty = inst_ty.scalarType(mod);
5989 const operand_ty = f.air.typeOf(data.lhs);6001 const operand_ty = f.typeOf(data.lhs);
5990 const scalar_ty = operand_ty.scalarType(mod);6002 const scalar_ty = operand_ty.scalarType(mod);
59916003
5992 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);6004 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
...@@ -6032,11 +6044,11 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6032,11 +6044,11 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6032 const mod = f.object.dg.module;6044 const mod = f.object.dg.module;
6033 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;6045 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
6034 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;6046 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
6035 const inst_ty = f.air.typeOfIndex(inst);6047 const inst_ty = f.typeOfIndex(inst);
6036 const ptr = try f.resolveInst(extra.ptr);6048 const ptr = try f.resolveInst(extra.ptr);
6037 const expected_value = try f.resolveInst(extra.expected_value);6049 const expected_value = try f.resolveInst(extra.expected_value);
6038 const new_value = try f.resolveInst(extra.new_value);6050 const new_value = try f.resolveInst(extra.new_value);
6039 const ptr_ty = f.air.typeOf(extra.ptr);6051 const ptr_ty = f.typeOf(extra.ptr);
6040 const ty = ptr_ty.childType();6052 const ty = ptr_ty.childType();
60416053
6042 const writer = f.object.writer();6054 const writer = f.object.writer();
...@@ -6137,8 +6149,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6137,8 +6149,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6137 const mod = f.object.dg.module;6149 const mod = f.object.dg.module;
6138 const pl_op = f.air.instructions.items(.data)[inst].pl_op;6150 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
6139 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;6151 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
6140 const inst_ty = f.air.typeOfIndex(inst);6152 const inst_ty = f.typeOfIndex(inst);
6141 const ptr_ty = f.air.typeOf(pl_op.operand);6153 const ptr_ty = f.typeOf(pl_op.operand);
6142 const ty = ptr_ty.childType();6154 const ty = ptr_ty.childType();
6143 const ptr = try f.resolveInst(pl_op.operand);6155 const ptr = try f.resolveInst(pl_op.operand);
6144 const operand = try f.resolveInst(extra.operand);6156 const operand = try f.resolveInst(extra.operand);
...@@ -6193,7 +6205,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6193,7 +6205,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6193 const atomic_load = f.air.instructions.items(.data)[inst].atomic_load;6205 const atomic_load = f.air.instructions.items(.data)[inst].atomic_load;
6194 const ptr = try f.resolveInst(atomic_load.ptr);6206 const ptr = try f.resolveInst(atomic_load.ptr);
6195 try reap(f, inst, &.{atomic_load.ptr});6207 try reap(f, inst, &.{atomic_load.ptr});
6196 const ptr_ty = f.air.typeOf(atomic_load.ptr);6208 const ptr_ty = f.typeOf(atomic_load.ptr);
6197 const ty = ptr_ty.childType();6209 const ty = ptr_ty.childType();
61986210
6199 const repr_ty = if (ty.isRuntimeFloat())6211 const repr_ty = if (ty.isRuntimeFloat())
...@@ -6201,7 +6213,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6201,7 +6213,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6201 else6213 else
6202 ty;6214 ty;
62036215
6204 const inst_ty = f.air.typeOfIndex(inst);6216 const inst_ty = f.typeOfIndex(inst);
6205 const writer = f.object.writer();6217 const writer = f.object.writer();
6206 const local = try f.allocLocal(inst, inst_ty);6218 const local = try f.allocLocal(inst, inst_ty);
62076219
...@@ -6227,7 +6239,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6227,7 +6239,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6227fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {6239fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {
6228 const mod = f.object.dg.module;6240 const mod = f.object.dg.module;
6229 const bin_op = f.air.instructions.items(.data)[inst].bin_op;6241 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
6230 const ptr_ty = f.air.typeOf(bin_op.lhs);6242 const ptr_ty = f.typeOf(bin_op.lhs);
6231 const ty = ptr_ty.childType();6243 const ty = ptr_ty.childType();
6232 const ptr = try f.resolveInst(bin_op.lhs);6244 const ptr = try f.resolveInst(bin_op.lhs);
6233 const element = try f.resolveInst(bin_op.rhs);6245 const element = try f.resolveInst(bin_op.rhs);
...@@ -6270,10 +6282,10 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo...@@ -6270,10 +6282,10 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo
6270fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {6282fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6271 const mod = f.object.dg.module;6283 const mod = f.object.dg.module;
6272 const bin_op = f.air.instructions.items(.data)[inst].bin_op;6284 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
6273 const dest_ty = f.air.typeOf(bin_op.lhs);6285 const dest_ty = f.typeOf(bin_op.lhs);
6274 const dest_slice = try f.resolveInst(bin_op.lhs);6286 const dest_slice = try f.resolveInst(bin_op.lhs);
6275 const value = try f.resolveInst(bin_op.rhs);6287 const value = try f.resolveInst(bin_op.rhs);
6276 const elem_ty = f.air.typeOf(bin_op.rhs);6288 const elem_ty = f.typeOf(bin_op.rhs);
6277 const elem_abi_size = elem_ty.abiSize(mod);6289 const elem_abi_size = elem_ty.abiSize(mod);
6278 const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;6290 const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;
6279 const writer = f.object.writer();6291 const writer = f.object.writer();
...@@ -6393,8 +6405,8 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6393,8 +6405,8 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
6393 const bin_op = f.air.instructions.items(.data)[inst].bin_op;6405 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
6394 const dest_ptr = try f.resolveInst(bin_op.lhs);6406 const dest_ptr = try f.resolveInst(bin_op.lhs);
6395 const src_ptr = try f.resolveInst(bin_op.rhs);6407 const src_ptr = try f.resolveInst(bin_op.rhs);
6396 const dest_ty = f.air.typeOf(bin_op.lhs);6408 const dest_ty = f.typeOf(bin_op.lhs);
6397 const src_ty = f.air.typeOf(bin_op.rhs);6409 const src_ty = f.typeOf(bin_op.rhs);
6398 const writer = f.object.writer();6410 const writer = f.object.writer();
63996411
6400 try writer.writeAll("memcpy(");6412 try writer.writeAll("memcpy(");
...@@ -6434,7 +6446,7 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6434,7 +6446,7 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6434 const new_tag = try f.resolveInst(bin_op.rhs);6446 const new_tag = try f.resolveInst(bin_op.rhs);
6435 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6447 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
64366448
6437 const union_ty = f.air.typeOf(bin_op.lhs).childType();6449 const union_ty = f.typeOf(bin_op.lhs).childType();
6438 const layout = union_ty.unionGetLayout(mod);6450 const layout = union_ty.unionGetLayout(mod);
6439 if (layout.tag_size == 0) return .none;6451 if (layout.tag_size == 0) return .none;
6440 const tag_ty = union_ty.unionTagTypeSafety().?;6452 const tag_ty = union_ty.unionTagTypeSafety().?;
...@@ -6455,11 +6467,11 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6455,11 +6467,11 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6455 const operand = try f.resolveInst(ty_op.operand);6467 const operand = try f.resolveInst(ty_op.operand);
6456 try reap(f, inst, &.{ty_op.operand});6468 try reap(f, inst, &.{ty_op.operand});
64576469
6458 const union_ty = f.air.typeOf(ty_op.operand);6470 const union_ty = f.typeOf(ty_op.operand);
6459 const layout = union_ty.unionGetLayout(mod);6471 const layout = union_ty.unionGetLayout(mod);
6460 if (layout.tag_size == 0) return .none;6472 if (layout.tag_size == 0) return .none;
64616473
6462 const inst_ty = f.air.typeOfIndex(inst);6474 const inst_ty = f.typeOfIndex(inst);
6463 const writer = f.object.writer();6475 const writer = f.object.writer();
6464 const local = try f.allocLocal(inst, inst_ty);6476 const local = try f.allocLocal(inst, inst_ty);
6465 const a = try Assignment.start(f, writer, inst_ty);6477 const a = try Assignment.start(f, writer, inst_ty);
...@@ -6473,8 +6485,8 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6473,8 +6485,8 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6473fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {6485fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
6474 const un_op = f.air.instructions.items(.data)[inst].un_op;6486 const un_op = f.air.instructions.items(.data)[inst].un_op;
64756487
6476 const inst_ty = f.air.typeOfIndex(inst);6488 const inst_ty = f.typeOfIndex(inst);
6477 const enum_ty = f.air.typeOf(un_op);6489 const enum_ty = f.typeOf(un_op);
6478 const operand = try f.resolveInst(un_op);6490 const operand = try f.resolveInst(un_op);
6479 try reap(f, inst, &.{un_op});6491 try reap(f, inst, &.{un_op});
64806492
...@@ -6494,7 +6506,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6494,7 +6506,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
6494 const un_op = f.air.instructions.items(.data)[inst].un_op;6506 const un_op = f.air.instructions.items(.data)[inst].un_op;
64956507
6496 const writer = f.object.writer();6508 const writer = f.object.writer();
6497 const inst_ty = f.air.typeOfIndex(inst);6509 const inst_ty = f.typeOfIndex(inst);
6498 const operand = try f.resolveInst(un_op);6510 const operand = try f.resolveInst(un_op);
6499 try reap(f, inst, &.{un_op});6511 try reap(f, inst, &.{un_op});
6500 const local = try f.allocLocal(inst, inst_ty);6512 const local = try f.allocLocal(inst, inst_ty);
...@@ -6513,7 +6525,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6513,7 +6525,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
6513 const operand = try f.resolveInst(ty_op.operand);6525 const operand = try f.resolveInst(ty_op.operand);
6514 try reap(f, inst, &.{ty_op.operand});6526 try reap(f, inst, &.{ty_op.operand});
65156527
6516 const inst_ty = f.air.typeOfIndex(inst);6528 const inst_ty = f.typeOfIndex(inst);
6517 const inst_scalar_ty = inst_ty.scalarType(mod);6529 const inst_scalar_ty = inst_ty.scalarType(mod);
65186530
6519 const writer = f.object.writer();6531 const writer = f.object.writer();
...@@ -6539,7 +6551,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6539,7 +6551,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
6539 const rhs = try f.resolveInst(extra.rhs);6551 const rhs = try f.resolveInst(extra.rhs);
6540 try reap(f, inst, &.{ pl_op.operand, extra.lhs, extra.rhs });6552 try reap(f, inst, &.{ pl_op.operand, extra.lhs, extra.rhs });
65416553
6542 const inst_ty = f.air.typeOfIndex(inst);6554 const inst_ty = f.typeOfIndex(inst);
65436555
6544 const writer = f.object.writer();6556 const writer = f.object.writer();
6545 const local = try f.allocLocal(inst, inst_ty);6557 const local = try f.allocLocal(inst, inst_ty);
...@@ -6570,7 +6582,7 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6570,7 +6582,7 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6570 const lhs = try f.resolveInst(extra.a);6582 const lhs = try f.resolveInst(extra.a);
6571 const rhs = try f.resolveInst(extra.b);6583 const rhs = try f.resolveInst(extra.b);
65726584
6573 const inst_ty = f.air.typeOfIndex(inst);6585 const inst_ty = f.typeOfIndex(inst);
65746586
6575 const writer = f.object.writer();6587 const writer = f.object.writer();
6576 const local = try f.allocLocal(inst, inst_ty);6588 const local = try f.allocLocal(inst, inst_ty);
...@@ -6607,10 +6619,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6607,10 +6619,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6607 const reduce = f.air.instructions.items(.data)[inst].reduce;6619 const reduce = f.air.instructions.items(.data)[inst].reduce;
66086620
6609 const target = mod.getTarget();6621 const target = mod.getTarget();
6610 const scalar_ty = f.air.typeOfIndex(inst);6622 const scalar_ty = f.typeOfIndex(inst);
6611 const operand = try f.resolveInst(reduce.operand);6623 const operand = try f.resolveInst(reduce.operand);
6612 try reap(f, inst, &.{reduce.operand});6624 try reap(f, inst, &.{reduce.operand});
6613 const operand_ty = f.air.typeOf(reduce.operand);6625 const operand_ty = f.typeOf(reduce.operand);
6614 const writer = f.object.writer();6626 const writer = f.object.writer();
66156627
6616 const use_operator = scalar_ty.bitSize(mod) <= 64;6628 const use_operator = scalar_ty.bitSize(mod) <= 64;
...@@ -6762,7 +6774,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6762,7 +6774,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6762fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {6774fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6763 const mod = f.object.dg.module;6775 const mod = f.object.dg.module;
6764 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;6776 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
6765 const inst_ty = f.air.typeOfIndex(inst);6777 const inst_ty = f.typeOfIndex(inst);
6766 const len = @intCast(usize, inst_ty.arrayLen());6778 const len = @intCast(usize, inst_ty.arrayLen());
6767 const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);6779 const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);
6768 const gpa = f.object.dg.gpa;6780 const gpa = f.object.dg.gpa;
...@@ -6892,10 +6904,10 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6892,10 +6904,10 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
6892 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;6904 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
6893 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;6905 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
68946906
6895 const union_ty = f.air.typeOfIndex(inst);6907 const union_ty = f.typeOfIndex(inst);
6896 const union_obj = union_ty.cast(Type.Payload.Union).?.data;6908 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
6897 const field_name = union_obj.fields.keys()[extra.field_index];6909 const field_name = union_obj.fields.keys()[extra.field_index];
6898 const payload_ty = f.air.typeOf(extra.init);6910 const payload_ty = f.typeOf(extra.init);
6899 const payload = try f.resolveInst(extra.init);6911 const payload = try f.resolveInst(extra.init);
6900 try reap(f, inst, &.{extra.init});6912 try reap(f, inst, &.{extra.init});
69016913
...@@ -6965,7 +6977,7 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6965,7 +6977,7 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
6965 const pl_op = f.air.instructions.items(.data)[inst].pl_op;6977 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
69666978
6967 const writer = f.object.writer();6979 const writer = f.object.writer();
6968 const inst_ty = f.air.typeOfIndex(inst);6980 const inst_ty = f.typeOfIndex(inst);
6969 const local = try f.allocLocal(inst, inst_ty);6981 const local = try f.allocLocal(inst, inst_ty);
6970 try f.writeCValue(writer, local, .Other);6982 try f.writeCValue(writer, local, .Other);
69716983
...@@ -6979,7 +6991,7 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6979,7 +6991,7 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
6979 const pl_op = f.air.instructions.items(.data)[inst].pl_op;6991 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
69806992
6981 const writer = f.object.writer();6993 const writer = f.object.writer();
6982 const inst_ty = f.air.typeOfIndex(inst);6994 const inst_ty = f.typeOfIndex(inst);
6983 const operand = try f.resolveInst(pl_op.operand);6995 const operand = try f.resolveInst(pl_op.operand);
6984 try reap(f, inst, &.{pl_op.operand});6996 try reap(f, inst, &.{pl_op.operand});
6985 const local = try f.allocLocal(inst, inst_ty);6997 const local = try f.allocLocal(inst, inst_ty);
...@@ -6999,7 +7011,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6999,7 +7011,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
6999 const operand = try f.resolveInst(un_op);7011 const operand = try f.resolveInst(un_op);
7000 try reap(f, inst, &.{un_op});7012 try reap(f, inst, &.{un_op});
70017013
7002 const operand_ty = f.air.typeOf(un_op);7014 const operand_ty = f.typeOf(un_op);
7003 const scalar_ty = operand_ty.scalarType(mod);7015 const scalar_ty = operand_ty.scalarType(mod);
70047016
7005 const writer = f.object.writer();7017 const writer = f.object.writer();
...@@ -7025,7 +7037,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal...@@ -7025,7 +7037,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
7025 const operand = try f.resolveInst(un_op);7037 const operand = try f.resolveInst(un_op);
7026 try reap(f, inst, &.{un_op});7038 try reap(f, inst, &.{un_op});
70277039
7028 const inst_ty = f.air.typeOfIndex(inst);7040 const inst_ty = f.typeOfIndex(inst);
7029 const inst_scalar_ty = inst_ty.scalarType(mod);7041 const inst_scalar_ty = inst_ty.scalarType(mod);
70307042
7031 const writer = f.object.writer();7043 const writer = f.object.writer();
...@@ -7054,7 +7066,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa...@@ -7054,7 +7066,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
7054 const rhs = try f.resolveInst(bin_op.rhs);7066 const rhs = try f.resolveInst(bin_op.rhs);
7055 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });7067 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
70567068
7057 const inst_ty = f.air.typeOfIndex(inst);7069 const inst_ty = f.typeOfIndex(inst);
7058 const inst_scalar_ty = inst_ty.scalarType(mod);7070 const inst_scalar_ty = inst_ty.scalarType(mod);
70597071
7060 const writer = f.object.writer();7072 const writer = f.object.writer();
...@@ -7088,7 +7100,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7088,7 +7100,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7088 const addend = try f.resolveInst(pl_op.operand);7100 const addend = try f.resolveInst(pl_op.operand);
7089 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });7101 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });
70907102
7091 const inst_ty = f.air.typeOfIndex(inst);7103 const inst_ty = f.typeOfIndex(inst);
7092 const inst_scalar_ty = inst_ty.scalarType(mod);7104 const inst_scalar_ty = inst_ty.scalarType(mod);
70937105
7094 const writer = f.object.writer();7106 const writer = f.object.writer();
...@@ -7114,7 +7126,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7114,7 +7126,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7114}7126}
71157127
7116fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {7128fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
7117 const inst_ty = f.air.typeOfIndex(inst);7129 const inst_ty = f.typeOfIndex(inst);
7118 const fn_cty = try f.typeToCType(f.object.dg.decl.?.ty, .complete);7130 const fn_cty = try f.typeToCType(f.object.dg.decl.?.ty, .complete);
7119 const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;7131 const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;
71207132
...@@ -7133,7 +7145,7 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7133,7 +7145,7 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
7133fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {7145fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {
7134 const ty_op = f.air.instructions.items(.data)[inst].ty_op;7146 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
71357147
7136 const inst_ty = f.air.typeOfIndex(inst);7148 const inst_ty = f.typeOfIndex(inst);
7137 const va_list = try f.resolveInst(ty_op.operand);7149 const va_list = try f.resolveInst(ty_op.operand);
7138 try reap(f, inst, &.{ty_op.operand});7150 try reap(f, inst, &.{ty_op.operand});
71397151
...@@ -7164,7 +7176,7 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7164,7 +7176,7 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {
7164fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {7176fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
7165 const ty_op = f.air.instructions.items(.data)[inst].ty_op;7177 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
71667178
7167 const inst_ty = f.air.typeOfIndex(inst);7179 const inst_ty = f.typeOfIndex(inst);
7168 const va_list = try f.resolveInst(ty_op.operand);7180 const va_list = try f.resolveInst(ty_op.operand);
7169 try reap(f, inst, &.{ty_op.operand});7181 try reap(f, inst, &.{ty_op.operand});
71707182
src/codegen/llvm.zig+156-143
...@@ -4497,7 +4497,7 @@ pub const FuncGen = struct {...@@ -4497,7 +4497,7 @@ pub const FuncGen = struct {
44974497
4498 const mod = self.dg.module;4498 const mod = self.dg.module;
4499 const llvm_val = try self.resolveValue(.{4499 const llvm_val = try self.resolveValue(.{
4500 .ty = self.air.typeOf(inst),4500 .ty = self.typeOf(inst),
4501 .val = self.air.value(inst, mod).?,4501 .val = self.air.value(inst, mod).?,
4502 });4502 });
4503 gop.value_ptr.* = llvm_val;4503 gop.value_ptr.* = llvm_val;
...@@ -4528,11 +4528,12 @@ pub const FuncGen = struct {...@@ -4528,11 +4528,12 @@ pub const FuncGen = struct {
4528 }4528 }
45294529
4530 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {4530 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
4531 const mod = self.dg.module;
4532 const ip = &mod.intern_pool;
4531 const air_tags = self.air.instructions.items(.tag);4533 const air_tags = self.air.instructions.items(.tag);
4532 for (body, 0..) |inst, i| {4534 for (body, 0..) |inst, i| {
4533 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {4535 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
4534 continue;4536 continue;
4535 }
45364537
4537 const opt_value: ?*llvm.Value = switch (air_tags[inst]) {4538 const opt_value: ?*llvm.Value = switch (air_tags[inst]) {
4538 // zig fmt: off4539 // zig fmt: off
...@@ -4751,6 +4752,8 @@ pub const FuncGen = struct {...@@ -4751,6 +4752,8 @@ pub const FuncGen = struct {
47514752
4752 .constant => unreachable,4753 .constant => unreachable,
4753 .const_ty => unreachable,4754 .const_ty => unreachable,
4755 .interned => unreachable,
4756
4754 .unreach => self.airUnreach(inst),4757 .unreach => self.airUnreach(inst),
4755 .dbg_stmt => self.airDbgStmt(inst),4758 .dbg_stmt => self.airDbgStmt(inst),
4756 .dbg_inline_begin => try self.airDbgInlineBegin(inst),4759 .dbg_inline_begin => try self.airDbgInlineBegin(inst),
...@@ -4781,7 +4784,7 @@ pub const FuncGen = struct {...@@ -4781,7 +4784,7 @@ pub const FuncGen = struct {
4781 const pl_op = self.air.instructions.items(.data)[inst].pl_op;4784 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
4782 const extra = self.air.extraData(Air.Call, pl_op.payload);4785 const extra = self.air.extraData(Air.Call, pl_op.payload);
4783 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);4786 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
4784 const callee_ty = self.air.typeOf(pl_op.operand);4787 const callee_ty = self.typeOf(pl_op.operand);
4785 const mod = self.dg.module;4788 const mod = self.dg.module;
4786 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {4789 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
4787 .Fn => callee_ty,4790 .Fn => callee_ty,
...@@ -4815,7 +4818,7 @@ pub const FuncGen = struct {...@@ -4815,7 +4818,7 @@ pub const FuncGen = struct {
4815 .no_bits => continue,4818 .no_bits => continue,
4816 .byval => {4819 .byval => {
4817 const arg = args[it.zig_index - 1];4820 const arg = args[it.zig_index - 1];
4818 const param_ty = self.air.typeOf(arg);4821 const param_ty = self.typeOf(arg);
4819 const llvm_arg = try self.resolveInst(arg);4822 const llvm_arg = try self.resolveInst(arg);
4820 const llvm_param_ty = try self.dg.lowerType(param_ty);4823 const llvm_param_ty = try self.dg.lowerType(param_ty);
4821 if (isByRef(param_ty, mod)) {4824 if (isByRef(param_ty, mod)) {
...@@ -4829,7 +4832,7 @@ pub const FuncGen = struct {...@@ -4829,7 +4832,7 @@ pub const FuncGen = struct {
4829 },4832 },
4830 .byref => {4833 .byref => {
4831 const arg = args[it.zig_index - 1];4834 const arg = args[it.zig_index - 1];
4832 const param_ty = self.air.typeOf(arg);4835 const param_ty = self.typeOf(arg);
4833 const llvm_arg = try self.resolveInst(arg);4836 const llvm_arg = try self.resolveInst(arg);
4834 if (isByRef(param_ty, mod)) {4837 if (isByRef(param_ty, mod)) {
4835 try llvm_args.append(llvm_arg);4838 try llvm_args.append(llvm_arg);
...@@ -4844,7 +4847,7 @@ pub const FuncGen = struct {...@@ -4844,7 +4847,7 @@ pub const FuncGen = struct {
4844 },4847 },
4845 .byref_mut => {4848 .byref_mut => {
4846 const arg = args[it.zig_index - 1];4849 const arg = args[it.zig_index - 1];
4847 const param_ty = self.air.typeOf(arg);4850 const param_ty = self.typeOf(arg);
4848 const llvm_arg = try self.resolveInst(arg);4851 const llvm_arg = try self.resolveInst(arg);
48494852
4850 const alignment = param_ty.abiAlignment(mod);4853 const alignment = param_ty.abiAlignment(mod);
...@@ -4865,7 +4868,7 @@ pub const FuncGen = struct {...@@ -4865,7 +4868,7 @@ pub const FuncGen = struct {
4865 },4868 },
4866 .abi_sized_int => {4869 .abi_sized_int => {
4867 const arg = args[it.zig_index - 1];4870 const arg = args[it.zig_index - 1];
4868 const param_ty = self.air.typeOf(arg);4871 const param_ty = self.typeOf(arg);
4869 const llvm_arg = try self.resolveInst(arg);4872 const llvm_arg = try self.resolveInst(arg);
4870 const abi_size = @intCast(c_uint, param_ty.abiSize(mod));4873 const abi_size = @intCast(c_uint, param_ty.abiSize(mod));
4871 const int_llvm_ty = self.context.intType(abi_size * 8);4874 const int_llvm_ty = self.context.intType(abi_size * 8);
...@@ -4901,7 +4904,7 @@ pub const FuncGen = struct {...@@ -4901,7 +4904,7 @@ pub const FuncGen = struct {
4901 },4904 },
4902 .multiple_llvm_types => {4905 .multiple_llvm_types => {
4903 const arg = args[it.zig_index - 1];4906 const arg = args[it.zig_index - 1];
4904 const param_ty = self.air.typeOf(arg);4907 const param_ty = self.typeOf(arg);
4905 const llvm_types = it.llvm_types_buffer[0..it.llvm_types_len];4908 const llvm_types = it.llvm_types_buffer[0..it.llvm_types_len];
4906 const llvm_arg = try self.resolveInst(arg);4909 const llvm_arg = try self.resolveInst(arg);
4907 const is_by_ref = isByRef(param_ty, mod);4910 const is_by_ref = isByRef(param_ty, mod);
...@@ -4930,7 +4933,7 @@ pub const FuncGen = struct {...@@ -4930,7 +4933,7 @@ pub const FuncGen = struct {
4930 },4933 },
4931 .float_array => |count| {4934 .float_array => |count| {
4932 const arg = args[it.zig_index - 1];4935 const arg = args[it.zig_index - 1];
4933 const arg_ty = self.air.typeOf(arg);4936 const arg_ty = self.typeOf(arg);
4934 var llvm_arg = try self.resolveInst(arg);4937 var llvm_arg = try self.resolveInst(arg);
4935 if (!isByRef(arg_ty, mod)) {4938 if (!isByRef(arg_ty, mod)) {
4936 const p = self.buildAlloca(llvm_arg.typeOf(), null);4939 const p = self.buildAlloca(llvm_arg.typeOf(), null);
...@@ -4950,7 +4953,7 @@ pub const FuncGen = struct {...@@ -4950,7 +4953,7 @@ pub const FuncGen = struct {
4950 .i32_array, .i64_array => |arr_len| {4953 .i32_array, .i64_array => |arr_len| {
4951 const elem_size: u8 = if (lowering == .i32_array) 32 else 64;4954 const elem_size: u8 = if (lowering == .i32_array) 32 else 64;
4952 const arg = args[it.zig_index - 1];4955 const arg = args[it.zig_index - 1];
4953 const arg_ty = self.air.typeOf(arg);4956 const arg_ty = self.typeOf(arg);
4954 var llvm_arg = try self.resolveInst(arg);4957 var llvm_arg = try self.resolveInst(arg);
4955 if (!isByRef(arg_ty, mod)) {4958 if (!isByRef(arg_ty, mod)) {
4956 const p = self.buildAlloca(llvm_arg.typeOf(), null);4959 const p = self.buildAlloca(llvm_arg.typeOf(), null);
...@@ -5094,7 +5097,7 @@ pub const FuncGen = struct {...@@ -5094,7 +5097,7 @@ pub const FuncGen = struct {
5094 fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5097 fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5095 const mod = self.dg.module;5098 const mod = self.dg.module;
5096 const un_op = self.air.instructions.items(.data)[inst].un_op;5099 const un_op = self.air.instructions.items(.data)[inst].un_op;
5097 const ret_ty = self.air.typeOf(un_op);5100 const ret_ty = self.typeOf(un_op);
5098 if (self.ret_ptr) |ret_ptr| {5101 if (self.ret_ptr) |ret_ptr| {
5099 const operand = try self.resolveInst(un_op);5102 const operand = try self.resolveInst(un_op);
5100 var ptr_ty_payload: Type.Payload.ElemType = .{5103 var ptr_ty_payload: Type.Payload.ElemType = .{
...@@ -5150,7 +5153,7 @@ pub const FuncGen = struct {...@@ -5150,7 +5153,7 @@ pub const FuncGen = struct {
51505153
5151 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5154 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5152 const un_op = self.air.instructions.items(.data)[inst].un_op;5155 const un_op = self.air.instructions.items(.data)[inst].un_op;
5153 const ptr_ty = self.air.typeOf(un_op);5156 const ptr_ty = self.typeOf(un_op);
5154 const ret_ty = ptr_ty.childType();5157 const ret_ty = ptr_ty.childType();
5155 const fn_info = self.dg.decl.ty.fnInfo();5158 const fn_info = self.dg.decl.ty.fnInfo();
5156 const mod = self.dg.module;5159 const mod = self.dg.module;
...@@ -5236,7 +5239,7 @@ pub const FuncGen = struct {...@@ -5236,7 +5239,7 @@ pub const FuncGen = struct {
52365239
5237 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5240 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5238 const mod = self.dg.module;5241 const mod = self.dg.module;
5239 const va_list_ty = self.air.typeOfIndex(inst);5242 const va_list_ty = self.typeOfIndex(inst);
5240 const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);5243 const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);
52415244
5242 const result_alignment = va_list_ty.abiAlignment(mod);5245 const result_alignment = va_list_ty.abiAlignment(mod);
...@@ -5266,7 +5269,7 @@ pub const FuncGen = struct {...@@ -5266,7 +5269,7 @@ pub const FuncGen = struct {
5266 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5269 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5267 const lhs = try self.resolveInst(bin_op.lhs);5270 const lhs = try self.resolveInst(bin_op.lhs);
5268 const rhs = try self.resolveInst(bin_op.rhs);5271 const rhs = try self.resolveInst(bin_op.rhs);
5269 const operand_ty = self.air.typeOf(bin_op.lhs);5272 const operand_ty = self.typeOf(bin_op.lhs);
52705273
5271 return self.cmp(lhs, rhs, operand_ty, op);5274 return self.cmp(lhs, rhs, operand_ty, op);
5272 }5275 }
...@@ -5279,7 +5282,7 @@ pub const FuncGen = struct {...@@ -5279,7 +5282,7 @@ pub const FuncGen = struct {
52795282
5280 const lhs = try self.resolveInst(extra.lhs);5283 const lhs = try self.resolveInst(extra.lhs);
5281 const rhs = try self.resolveInst(extra.rhs);5284 const rhs = try self.resolveInst(extra.rhs);
5282 const vec_ty = self.air.typeOf(extra.lhs);5285 const vec_ty = self.typeOf(extra.lhs);
5283 const cmp_op = extra.compareOperator();5286 const cmp_op = extra.compareOperator();
52845287
5285 return self.cmp(lhs, rhs, vec_ty, cmp_op);5288 return self.cmp(lhs, rhs, vec_ty, cmp_op);
...@@ -5396,12 +5399,12 @@ pub const FuncGen = struct {...@@ -5396,12 +5399,12 @@ pub const FuncGen = struct {
5396 }5399 }
53975400
5398 fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5401 fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5402 const mod = self.dg.module;
5399 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5403 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5400 const extra = self.air.extraData(Air.Block, ty_pl.payload);5404 const extra = self.air.extraData(Air.Block, ty_pl.payload);
5401 const body = self.air.extra[extra.end..][0..extra.data.body_len];5405 const body = self.air.extra[extra.end..][0..extra.data.body_len];
5402 const inst_ty = self.air.typeOfIndex(inst);5406 const inst_ty = self.typeOfIndex(inst);
5403 const parent_bb = self.context.createBasicBlock("Block");5407 const parent_bb = self.context.createBasicBlock("Block");
5404 const mod = self.dg.module;
54055408
5406 if (inst_ty.isNoReturn()) {5409 if (inst_ty.isNoReturn()) {
5407 try self.genBody(body);5410 try self.genBody(body);
...@@ -5453,7 +5456,7 @@ pub const FuncGen = struct {...@@ -5453,7 +5456,7 @@ pub const FuncGen = struct {
5453 const block = self.blocks.get(branch.block_inst).?;5456 const block = self.blocks.get(branch.block_inst).?;
54545457
5455 // Add the values to the lists only if the break provides a value.5458 // Add the values to the lists only if the break provides a value.
5456 const operand_ty = self.air.typeOf(branch.operand);5459 const operand_ty = self.typeOf(branch.operand);
5457 const mod = self.dg.module;5460 const mod = self.dg.module;
5458 if (operand_ty.hasRuntimeBitsIgnoreComptime(mod) or operand_ty.zigTypeTag(mod) == .Fn) {5461 if (operand_ty.hasRuntimeBitsIgnoreComptime(mod) or operand_ty.zigTypeTag(mod) == .Fn) {
5459 const val = try self.resolveInst(branch.operand);5462 const val = try self.resolveInst(branch.operand);
...@@ -5497,8 +5500,8 @@ pub const FuncGen = struct {...@@ -5497,8 +5500,8 @@ pub const FuncGen = struct {
5497 const err_union = try self.resolveInst(pl_op.operand);5500 const err_union = try self.resolveInst(pl_op.operand);
5498 const extra = self.air.extraData(Air.Try, pl_op.payload);5501 const extra = self.air.extraData(Air.Try, pl_op.payload);
5499 const body = self.air.extra[extra.end..][0..extra.data.body_len];5502 const body = self.air.extra[extra.end..][0..extra.data.body_len];
5500 const err_union_ty = self.air.typeOf(pl_op.operand);5503 const err_union_ty = self.typeOf(pl_op.operand);
5501 const payload_ty = self.air.typeOfIndex(inst);5504 const payload_ty = self.typeOfIndex(inst);
5502 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;5505 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;
5503 const is_unused = self.liveness.isUnused(inst);5506 const is_unused = self.liveness.isUnused(inst);
5504 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);5507 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);
...@@ -5509,7 +5512,7 @@ pub const FuncGen = struct {...@@ -5509,7 +5512,7 @@ pub const FuncGen = struct {
5509 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);5512 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
5510 const err_union_ptr = try self.resolveInst(extra.data.ptr);5513 const err_union_ptr = try self.resolveInst(extra.data.ptr);
5511 const body = self.air.extra[extra.end..][0..extra.data.body_len];5514 const body = self.air.extra[extra.end..][0..extra.data.body_len];
5512 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();5515 const err_union_ty = self.typeOf(extra.data.ptr).childType();
5513 const is_unused = self.liveness.isUnused(inst);5516 const is_unused = self.liveness.isUnused(inst);
5514 return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused);5517 return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused);
5515 }5518 }
...@@ -5650,7 +5653,7 @@ pub const FuncGen = struct {...@@ -5650,7 +5653,7 @@ pub const FuncGen = struct {
5650 // would have been emitted already. Also the main loop in genBody can5653 // would have been emitted already. Also the main loop in genBody can
5651 // be while(true) instead of for(body), which will eliminate 1 branch on5654 // be while(true) instead of for(body), which will eliminate 1 branch on
5652 // a hot path.5655 // a hot path.
5653 if (body.len == 0 or !self.air.typeOfIndex(body[body.len - 1]).isNoReturn()) {5656 if (body.len == 0 or !self.typeOfIndex(body[body.len - 1]).isNoReturn()) {
5654 _ = self.builder.buildBr(loop_block);5657 _ = self.builder.buildBr(loop_block);
5655 }5658 }
5656 return null;5659 return null;
...@@ -5659,11 +5662,11 @@ pub const FuncGen = struct {...@@ -5659,11 +5662,11 @@ pub const FuncGen = struct {
5659 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5662 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5660 const mod = self.dg.module;5663 const mod = self.dg.module;
5661 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5664 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5662 const operand_ty = self.air.typeOf(ty_op.operand);5665 const operand_ty = self.typeOf(ty_op.operand);
5663 const array_ty = operand_ty.childType();5666 const array_ty = operand_ty.childType();
5664 const llvm_usize = try self.dg.lowerType(Type.usize);5667 const llvm_usize = try self.dg.lowerType(Type.usize);
5665 const len = llvm_usize.constInt(array_ty.arrayLen(), .False);5668 const len = llvm_usize.constInt(array_ty.arrayLen(), .False);
5666 const slice_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));5669 const slice_llvm_ty = try self.dg.lowerType(self.typeOfIndex(inst));
5667 const operand = try self.resolveInst(ty_op.operand);5670 const operand = try self.resolveInst(ty_op.operand);
5668 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {5671 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5669 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");5672 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");
...@@ -5683,10 +5686,10 @@ pub const FuncGen = struct {...@@ -5683,10 +5686,10 @@ pub const FuncGen = struct {
5683 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5686 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
56845687
5685 const operand = try self.resolveInst(ty_op.operand);5688 const operand = try self.resolveInst(ty_op.operand);
5686 const operand_ty = self.air.typeOf(ty_op.operand);5689 const operand_ty = self.typeOf(ty_op.operand);
5687 const operand_scalar_ty = operand_ty.scalarType(mod);5690 const operand_scalar_ty = operand_ty.scalarType(mod);
56885691
5689 const dest_ty = self.air.typeOfIndex(inst);5692 const dest_ty = self.typeOfIndex(inst);
5690 const dest_scalar_ty = dest_ty.scalarType(mod);5693 const dest_scalar_ty = dest_ty.scalarType(mod);
5691 const dest_llvm_ty = try self.dg.lowerType(dest_ty);5694 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
5692 const target = mod.getTarget();5695 const target = mod.getTarget();
...@@ -5743,10 +5746,10 @@ pub const FuncGen = struct {...@@ -5743,10 +5746,10 @@ pub const FuncGen = struct {
5743 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5746 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
57445747
5745 const operand = try self.resolveInst(ty_op.operand);5748 const operand = try self.resolveInst(ty_op.operand);
5746 const operand_ty = self.air.typeOf(ty_op.operand);5749 const operand_ty = self.typeOf(ty_op.operand);
5747 const operand_scalar_ty = operand_ty.scalarType(mod);5750 const operand_scalar_ty = operand_ty.scalarType(mod);
57485751
5749 const dest_ty = self.air.typeOfIndex(inst);5752 const dest_ty = self.typeOfIndex(inst);
5750 const dest_scalar_ty = dest_ty.scalarType(mod);5753 const dest_scalar_ty = dest_ty.scalarType(mod);
5751 const dest_llvm_ty = try self.dg.lowerType(dest_ty);5754 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
57525755
...@@ -5832,7 +5835,7 @@ pub const FuncGen = struct {...@@ -5832,7 +5835,7 @@ pub const FuncGen = struct {
5832 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*llvm.Value {5835 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*llvm.Value {
5833 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5836 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5834 const slice_ptr = try self.resolveInst(ty_op.operand);5837 const slice_ptr = try self.resolveInst(ty_op.operand);
5835 const slice_ptr_ty = self.air.typeOf(ty_op.operand);5838 const slice_ptr_ty = self.typeOf(ty_op.operand);
5836 const slice_llvm_ty = try self.dg.lowerPtrElemTy(slice_ptr_ty.childType());5839 const slice_llvm_ty = try self.dg.lowerPtrElemTy(slice_ptr_ty.childType());
58375840
5838 return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, "");5841 return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, "");
...@@ -5842,7 +5845,7 @@ pub const FuncGen = struct {...@@ -5842,7 +5845,7 @@ pub const FuncGen = struct {
5842 const mod = self.dg.module;5845 const mod = self.dg.module;
5843 const inst = body_tail[0];5846 const inst = body_tail[0];
5844 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5847 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5845 const slice_ty = self.air.typeOf(bin_op.lhs);5848 const slice_ty = self.typeOf(bin_op.lhs);
5846 const slice = try self.resolveInst(bin_op.lhs);5849 const slice = try self.resolveInst(bin_op.lhs);
5847 const index = try self.resolveInst(bin_op.rhs);5850 const index = try self.resolveInst(bin_op.rhs);
5848 const elem_ty = slice_ty.childType();5851 const elem_ty = slice_ty.childType();
...@@ -5863,7 +5866,7 @@ pub const FuncGen = struct {...@@ -5863,7 +5866,7 @@ pub const FuncGen = struct {
5863 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5866 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5864 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5867 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5865 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;5868 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
5866 const slice_ty = self.air.typeOf(bin_op.lhs);5869 const slice_ty = self.typeOf(bin_op.lhs);
58675870
5868 const slice = try self.resolveInst(bin_op.lhs);5871 const slice = try self.resolveInst(bin_op.lhs);
5869 const index = try self.resolveInst(bin_op.rhs);5872 const index = try self.resolveInst(bin_op.rhs);
...@@ -5878,7 +5881,7 @@ pub const FuncGen = struct {...@@ -5878,7 +5881,7 @@ pub const FuncGen = struct {
5878 const inst = body_tail[0];5881 const inst = body_tail[0];
58795882
5880 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5883 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5881 const array_ty = self.air.typeOf(bin_op.lhs);5884 const array_ty = self.typeOf(bin_op.lhs);
5882 const array_llvm_val = try self.resolveInst(bin_op.lhs);5885 const array_llvm_val = try self.resolveInst(bin_op.lhs);
5883 const rhs = try self.resolveInst(bin_op.rhs);5886 const rhs = try self.resolveInst(bin_op.rhs);
5884 const array_llvm_ty = try self.dg.lowerType(array_ty);5887 const array_llvm_ty = try self.dg.lowerType(array_ty);
...@@ -5920,7 +5923,7 @@ pub const FuncGen = struct {...@@ -5920,7 +5923,7 @@ pub const FuncGen = struct {
5920 const mod = self.dg.module;5923 const mod = self.dg.module;
5921 const inst = body_tail[0];5924 const inst = body_tail[0];
5922 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5925 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5923 const ptr_ty = self.air.typeOf(bin_op.lhs);5926 const ptr_ty = self.typeOf(bin_op.lhs);
5924 const elem_ty = ptr_ty.childType();5927 const elem_ty = ptr_ty.childType();
5925 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);5928 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
5926 const base_ptr = try self.resolveInst(bin_op.lhs);5929 const base_ptr = try self.resolveInst(bin_op.lhs);
...@@ -5948,7 +5951,7 @@ pub const FuncGen = struct {...@@ -5948,7 +5951,7 @@ pub const FuncGen = struct {
5948 const mod = self.dg.module;5951 const mod = self.dg.module;
5949 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5952 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5950 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;5953 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
5951 const ptr_ty = self.air.typeOf(bin_op.lhs);5954 const ptr_ty = self.typeOf(bin_op.lhs);
5952 const elem_ty = ptr_ty.childType();5955 const elem_ty = ptr_ty.childType();
5953 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);5956 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
59545957
...@@ -5973,7 +5976,7 @@ pub const FuncGen = struct {...@@ -5973,7 +5976,7 @@ pub const FuncGen = struct {
5973 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5976 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5974 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;5977 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
5975 const struct_ptr = try self.resolveInst(struct_field.struct_operand);5978 const struct_ptr = try self.resolveInst(struct_field.struct_operand);
5976 const struct_ptr_ty = self.air.typeOf(struct_field.struct_operand);5979 const struct_ptr_ty = self.typeOf(struct_field.struct_operand);
5977 return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, struct_field.field_index);5980 return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, struct_field.field_index);
5978 }5981 }
59795982
...@@ -5984,7 +5987,7 @@ pub const FuncGen = struct {...@@ -5984,7 +5987,7 @@ pub const FuncGen = struct {
5984 ) !?*llvm.Value {5987 ) !?*llvm.Value {
5985 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5988 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5986 const struct_ptr = try self.resolveInst(ty_op.operand);5989 const struct_ptr = try self.resolveInst(ty_op.operand);
5987 const struct_ptr_ty = self.air.typeOf(ty_op.operand);5990 const struct_ptr_ty = self.typeOf(ty_op.operand);
5988 return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, field_index);5991 return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, field_index);
5989 }5992 }
59905993
...@@ -5993,7 +5996,7 @@ pub const FuncGen = struct {...@@ -5993,7 +5996,7 @@ pub const FuncGen = struct {
5993 const inst = body_tail[0];5996 const inst = body_tail[0];
5994 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5997 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5995 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;5998 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
5996 const struct_ty = self.air.typeOf(struct_field.struct_operand);5999 const struct_ty = self.typeOf(struct_field.struct_operand);
5997 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);6000 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
5998 const field_index = struct_field.field_index;6001 const field_index = struct_field.field_index;
5999 const field_ty = struct_ty.structFieldType(field_index);6002 const field_ty = struct_ty.structFieldType(field_index);
...@@ -6234,7 +6237,7 @@ pub const FuncGen = struct {...@@ -6234,7 +6237,7 @@ pub const FuncGen = struct {
6234 const pl_op = self.air.instructions.items(.data)[inst].pl_op;6237 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
6235 const operand = try self.resolveInst(pl_op.operand);6238 const operand = try self.resolveInst(pl_op.operand);
6236 const name = self.air.nullTerminatedString(pl_op.payload);6239 const name = self.air.nullTerminatedString(pl_op.payload);
6237 const ptr_ty = self.air.typeOf(pl_op.operand);6240 const ptr_ty = self.typeOf(pl_op.operand);
62386241
6239 const di_local_var = dib.createAutoVariable(6242 const di_local_var = dib.createAutoVariable(
6240 self.di_scope.?,6243 self.di_scope.?,
...@@ -6259,7 +6262,7 @@ pub const FuncGen = struct {...@@ -6259,7 +6262,7 @@ pub const FuncGen = struct {
6259 const dib = self.dg.object.di_builder orelse return null;6262 const dib = self.dg.object.di_builder orelse return null;
6260 const pl_op = self.air.instructions.items(.data)[inst].pl_op;6263 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
6261 const operand = try self.resolveInst(pl_op.operand);6264 const operand = try self.resolveInst(pl_op.operand);
6262 const operand_ty = self.air.typeOf(pl_op.operand);6265 const operand_ty = self.typeOf(pl_op.operand);
6263 const name = self.air.nullTerminatedString(pl_op.payload);6266 const name = self.air.nullTerminatedString(pl_op.payload);
62646267
6265 if (needDbgVarWorkaround(self.dg)) {6268 if (needDbgVarWorkaround(self.dg)) {
...@@ -6361,7 +6364,7 @@ pub const FuncGen = struct {...@@ -6361,7 +6364,7 @@ pub const FuncGen = struct {
6361 llvm_ret_indirect[i] = (output != .none) and constraintAllowsMemory(constraint);6364 llvm_ret_indirect[i] = (output != .none) and constraintAllowsMemory(constraint);
6362 if (output != .none) {6365 if (output != .none) {
6363 const output_inst = try self.resolveInst(output);6366 const output_inst = try self.resolveInst(output);
6364 const output_ty = self.air.typeOf(output);6367 const output_ty = self.typeOf(output);
6365 assert(output_ty.zigTypeTag(mod) == .Pointer);6368 assert(output_ty.zigTypeTag(mod) == .Pointer);
6366 const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType());6369 const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType());
63676370
...@@ -6379,7 +6382,7 @@ pub const FuncGen = struct {...@@ -6379,7 +6382,7 @@ pub const FuncGen = struct {
6379 llvm_ret_i += 1;6382 llvm_ret_i += 1;
6380 }6383 }
6381 } else {6384 } else {
6382 const ret_ty = self.air.typeOfIndex(inst);6385 const ret_ty = self.typeOfIndex(inst);
6383 llvm_ret_types[llvm_ret_i] = try self.dg.lowerType(ret_ty);6386 llvm_ret_types[llvm_ret_i] = try self.dg.lowerType(ret_ty);
6384 llvm_ret_i += 1;6387 llvm_ret_i += 1;
6385 }6388 }
...@@ -6414,7 +6417,7 @@ pub const FuncGen = struct {...@@ -6414,7 +6417,7 @@ pub const FuncGen = struct {
6414 extra_i += (constraint.len + name.len + (2 + 3)) / 4;6417 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
64156418
6416 const arg_llvm_value = try self.resolveInst(input);6419 const arg_llvm_value = try self.resolveInst(input);
6417 const arg_ty = self.air.typeOf(input);6420 const arg_ty = self.typeOf(input);
6418 var llvm_elem_ty: ?*llvm.Type = null;6421 var llvm_elem_ty: ?*llvm.Type = null;
6419 if (isByRef(arg_ty, mod)) {6422 if (isByRef(arg_ty, mod)) {
6420 llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty);6423 llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty);
...@@ -6636,7 +6639,7 @@ pub const FuncGen = struct {...@@ -6636,7 +6639,7 @@ pub const FuncGen = struct {
66366639
6637 if (output != .none) {6640 if (output != .none) {
6638 const output_ptr = try self.resolveInst(output);6641 const output_ptr = try self.resolveInst(output);
6639 const output_ptr_ty = self.air.typeOf(output);6642 const output_ptr_ty = self.typeOf(output);
66406643
6641 const store_inst = self.builder.buildStore(output_value, output_ptr);6644 const store_inst = self.builder.buildStore(output_value, output_ptr);
6642 store_inst.setAlignment(output_ptr_ty.ptrAlignment(mod));6645 store_inst.setAlignment(output_ptr_ty.ptrAlignment(mod));
...@@ -6657,7 +6660,7 @@ pub const FuncGen = struct {...@@ -6657,7 +6660,7 @@ pub const FuncGen = struct {
6657 ) !?*llvm.Value {6660 ) !?*llvm.Value {
6658 const un_op = self.air.instructions.items(.data)[inst].un_op;6661 const un_op = self.air.instructions.items(.data)[inst].un_op;
6659 const operand = try self.resolveInst(un_op);6662 const operand = try self.resolveInst(un_op);
6660 const operand_ty = self.air.typeOf(un_op);6663 const operand_ty = self.typeOf(un_op);
6661 const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;6664 const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
6662 const optional_llvm_ty = try self.dg.lowerType(optional_ty);6665 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
6663 var buf: Type.Payload.ElemType = undefined;6666 var buf: Type.Payload.ElemType = undefined;
...@@ -6706,7 +6709,7 @@ pub const FuncGen = struct {...@@ -6706,7 +6709,7 @@ pub const FuncGen = struct {
6706 const mod = self.dg.module;6709 const mod = self.dg.module;
6707 const un_op = self.air.instructions.items(.data)[inst].un_op;6710 const un_op = self.air.instructions.items(.data)[inst].un_op;
6708 const operand = try self.resolveInst(un_op);6711 const operand = try self.resolveInst(un_op);
6709 const operand_ty = self.air.typeOf(un_op);6712 const operand_ty = self.typeOf(un_op);
6710 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;6713 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
6711 const payload_ty = err_union_ty.errorUnionPayload();6714 const payload_ty = err_union_ty.errorUnionPayload();
6712 const err_set_ty = try self.dg.lowerType(Type.anyerror);6715 const err_set_ty = try self.dg.lowerType(Type.anyerror);
...@@ -6746,7 +6749,7 @@ pub const FuncGen = struct {...@@ -6746,7 +6749,7 @@ pub const FuncGen = struct {
6746 const mod = self.dg.module;6749 const mod = self.dg.module;
6747 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6750 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6748 const operand = try self.resolveInst(ty_op.operand);6751 const operand = try self.resolveInst(ty_op.operand);
6749 const optional_ty = self.air.typeOf(ty_op.operand).childType();6752 const optional_ty = self.typeOf(ty_op.operand).childType();
6750 var buf: Type.Payload.ElemType = undefined;6753 var buf: Type.Payload.ElemType = undefined;
6751 const payload_ty = optional_ty.optionalChild(&buf);6754 const payload_ty = optional_ty.optionalChild(&buf);
6752 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6755 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -6768,7 +6771,7 @@ pub const FuncGen = struct {...@@ -6768,7 +6771,7 @@ pub const FuncGen = struct {
6768 const mod = self.dg.module;6771 const mod = self.dg.module;
6769 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6772 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6770 const operand = try self.resolveInst(ty_op.operand);6773 const operand = try self.resolveInst(ty_op.operand);
6771 const optional_ty = self.air.typeOf(ty_op.operand).childType();6774 const optional_ty = self.typeOf(ty_op.operand).childType();
6772 var buf: Type.Payload.ElemType = undefined;6775 var buf: Type.Payload.ElemType = undefined;
6773 const payload_ty = optional_ty.optionalChild(&buf);6776 const payload_ty = optional_ty.optionalChild(&buf);
6774 const non_null_bit = self.context.intType(8).constInt(1, .False);6777 const non_null_bit = self.context.intType(8).constInt(1, .False);
...@@ -6801,8 +6804,8 @@ pub const FuncGen = struct {...@@ -6801,8 +6804,8 @@ pub const FuncGen = struct {
6801 const inst = body_tail[0];6804 const inst = body_tail[0];
6802 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6805 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6803 const operand = try self.resolveInst(ty_op.operand);6806 const operand = try self.resolveInst(ty_op.operand);
6804 const optional_ty = self.air.typeOf(ty_op.operand);6807 const optional_ty = self.typeOf(ty_op.operand);
6805 const payload_ty = self.air.typeOfIndex(inst);6808 const payload_ty = self.typeOfIndex(inst);
6806 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;6809 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
68076810
6808 if (optional_ty.optionalReprIsPayload(mod)) {6811 if (optional_ty.optionalReprIsPayload(mod)) {
...@@ -6824,9 +6827,9 @@ pub const FuncGen = struct {...@@ -6824,9 +6827,9 @@ pub const FuncGen = struct {
6824 const inst = body_tail[0];6827 const inst = body_tail[0];
6825 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6828 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6826 const operand = try self.resolveInst(ty_op.operand);6829 const operand = try self.resolveInst(ty_op.operand);
6827 const operand_ty = self.air.typeOf(ty_op.operand);6830 const operand_ty = self.typeOf(ty_op.operand);
6828 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;6831 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
6829 const result_ty = self.air.typeOfIndex(inst);6832 const result_ty = self.typeOfIndex(inst);
6830 const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;6833 const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;
68316834
6832 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6835 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -6859,7 +6862,7 @@ pub const FuncGen = struct {...@@ -6859,7 +6862,7 @@ pub const FuncGen = struct {
6859 const mod = self.dg.module;6862 const mod = self.dg.module;
6860 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6863 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6861 const operand = try self.resolveInst(ty_op.operand);6864 const operand = try self.resolveInst(ty_op.operand);
6862 const operand_ty = self.air.typeOf(ty_op.operand);6865 const operand_ty = self.typeOf(ty_op.operand);
6863 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;6866 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
6864 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {6867 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
6865 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);6868 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
...@@ -6893,7 +6896,7 @@ pub const FuncGen = struct {...@@ -6893,7 +6896,7 @@ pub const FuncGen = struct {
6893 const mod = self.dg.module;6896 const mod = self.dg.module;
6894 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6897 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6895 const operand = try self.resolveInst(ty_op.operand);6898 const operand = try self.resolveInst(ty_op.operand);
6896 const err_union_ty = self.air.typeOf(ty_op.operand).childType();6899 const err_union_ty = self.typeOf(ty_op.operand).childType();
68976900
6898 const payload_ty = err_union_ty.errorUnionPayload();6901 const payload_ty = err_union_ty.errorUnionPayload();
6899 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });6902 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });
...@@ -6946,12 +6949,12 @@ pub const FuncGen = struct {...@@ -6946,12 +6949,12 @@ pub const FuncGen = struct {
6946 fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6949 fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6947 const mod = self.dg.module;6950 const mod = self.dg.module;
6948 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6951 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6949 const payload_ty = self.air.typeOf(ty_op.operand);6952 const payload_ty = self.typeOf(ty_op.operand);
6950 const non_null_bit = self.context.intType(8).constInt(1, .False);6953 const non_null_bit = self.context.intType(8).constInt(1, .False);
6951 comptime assert(optional_layout_version == 3);6954 comptime assert(optional_layout_version == 3);
6952 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;6955 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;
6953 const operand = try self.resolveInst(ty_op.operand);6956 const operand = try self.resolveInst(ty_op.operand);
6954 const optional_ty = self.air.typeOfIndex(inst);6957 const optional_ty = self.typeOfIndex(inst);
6955 if (optional_ty.optionalReprIsPayload(mod)) {6958 if (optional_ty.optionalReprIsPayload(mod)) {
6956 return operand;6959 return operand;
6957 }6960 }
...@@ -6976,9 +6979,9 @@ pub const FuncGen = struct {...@@ -6976,9 +6979,9 @@ pub const FuncGen = struct {
6976 fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {6979 fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6977 const mod = self.dg.module;6980 const mod = self.dg.module;
6978 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6981 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6979 const err_un_ty = self.air.typeOfIndex(inst);6982 const err_un_ty = self.typeOfIndex(inst);
6980 const operand = try self.resolveInst(ty_op.operand);6983 const operand = try self.resolveInst(ty_op.operand);
6981 const payload_ty = self.air.typeOf(ty_op.operand);6984 const payload_ty = self.typeOf(ty_op.operand);
6982 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6985 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6983 return operand;6986 return operand;
6984 }6987 }
...@@ -7009,7 +7012,7 @@ pub const FuncGen = struct {...@@ -7009,7 +7012,7 @@ pub const FuncGen = struct {
7009 fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7012 fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7010 const mod = self.dg.module;7013 const mod = self.dg.module;
7011 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7014 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7012 const err_un_ty = self.air.typeOfIndex(inst);7015 const err_un_ty = self.typeOfIndex(inst);
7013 const payload_ty = err_un_ty.errorUnionPayload();7016 const payload_ty = err_un_ty.errorUnionPayload();
7014 const operand = try self.resolveInst(ty_op.operand);7017 const operand = try self.resolveInst(ty_op.operand);
7015 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7018 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -7069,7 +7072,7 @@ pub const FuncGen = struct {...@@ -7069,7 +7072,7 @@ pub const FuncGen = struct {
7069 const extra = self.air.extraData(Air.Bin, data.payload).data;7072 const extra = self.air.extraData(Air.Bin, data.payload).data;
70707073
7071 const vector_ptr = try self.resolveInst(data.vector_ptr);7074 const vector_ptr = try self.resolveInst(data.vector_ptr);
7072 const vector_ptr_ty = self.air.typeOf(data.vector_ptr);7075 const vector_ptr_ty = self.typeOf(data.vector_ptr);
7073 const index = try self.resolveInst(extra.lhs);7076 const index = try self.resolveInst(extra.lhs);
7074 const operand = try self.resolveInst(extra.rhs);7077 const operand = try self.resolveInst(extra.rhs);
70757078
...@@ -7090,7 +7093,7 @@ pub const FuncGen = struct {...@@ -7090,7 +7093,7 @@ pub const FuncGen = struct {
7090 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7093 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7091 const lhs = try self.resolveInst(bin_op.lhs);7094 const lhs = try self.resolveInst(bin_op.lhs);
7092 const rhs = try self.resolveInst(bin_op.rhs);7095 const rhs = try self.resolveInst(bin_op.rhs);
7093 const scalar_ty = self.air.typeOfIndex(inst).scalarType(mod);7096 const scalar_ty = self.typeOfIndex(inst).scalarType(mod);
70947097
7095 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, scalar_ty, 2, .{ lhs, rhs });7098 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, scalar_ty, 2, .{ lhs, rhs });
7096 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSMin(lhs, rhs, "");7099 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSMin(lhs, rhs, "");
...@@ -7102,7 +7105,7 @@ pub const FuncGen = struct {...@@ -7102,7 +7105,7 @@ pub const FuncGen = struct {
7102 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7105 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7103 const lhs = try self.resolveInst(bin_op.lhs);7106 const lhs = try self.resolveInst(bin_op.lhs);
7104 const rhs = try self.resolveInst(bin_op.rhs);7107 const rhs = try self.resolveInst(bin_op.rhs);
7105 const scalar_ty = self.air.typeOfIndex(inst).scalarType(mod);7108 const scalar_ty = self.typeOfIndex(inst).scalarType(mod);
71067109
7107 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, scalar_ty, 2, .{ lhs, rhs });7110 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, scalar_ty, 2, .{ lhs, rhs });
7108 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSMax(lhs, rhs, "");7111 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSMax(lhs, rhs, "");
...@@ -7114,7 +7117,7 @@ pub const FuncGen = struct {...@@ -7114,7 +7117,7 @@ pub const FuncGen = struct {
7114 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;7117 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
7115 const ptr = try self.resolveInst(bin_op.lhs);7118 const ptr = try self.resolveInst(bin_op.lhs);
7116 const len = try self.resolveInst(bin_op.rhs);7119 const len = try self.resolveInst(bin_op.rhs);
7117 const inst_ty = self.air.typeOfIndex(inst);7120 const inst_ty = self.typeOfIndex(inst);
7118 const llvm_slice_ty = try self.dg.lowerType(inst_ty);7121 const llvm_slice_ty = try self.dg.lowerType(inst_ty);
71197122
7120 // In case of slicing a global, the result type looks something like `{ i8*, i64 }`7123 // In case of slicing a global, the result type looks something like `{ i8*, i64 }`
...@@ -7130,7 +7133,7 @@ pub const FuncGen = struct {...@@ -7130,7 +7133,7 @@ pub const FuncGen = struct {
7130 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7133 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7131 const lhs = try self.resolveInst(bin_op.lhs);7134 const lhs = try self.resolveInst(bin_op.lhs);
7132 const rhs = try self.resolveInst(bin_op.rhs);7135 const rhs = try self.resolveInst(bin_op.rhs);
7133 const inst_ty = self.air.typeOfIndex(inst);7136 const inst_ty = self.typeOfIndex(inst);
7134 const scalar_ty = inst_ty.scalarType(mod);7137 const scalar_ty = inst_ty.scalarType(mod);
71357138
7136 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.add, inst_ty, 2, .{ lhs, rhs });7139 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.add, inst_ty, 2, .{ lhs, rhs });
...@@ -7153,7 +7156,7 @@ pub const FuncGen = struct {...@@ -7153,7 +7156,7 @@ pub const FuncGen = struct {
7153 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7156 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7154 const lhs = try self.resolveInst(bin_op.lhs);7157 const lhs = try self.resolveInst(bin_op.lhs);
7155 const rhs = try self.resolveInst(bin_op.rhs);7158 const rhs = try self.resolveInst(bin_op.rhs);
7156 const inst_ty = self.air.typeOfIndex(inst);7159 const inst_ty = self.typeOfIndex(inst);
7157 const scalar_ty = inst_ty.scalarType(mod);7160 const scalar_ty = inst_ty.scalarType(mod);
71587161
7159 if (scalar_ty.isAnyFloat()) return self.todo("saturating float add", .{});7162 if (scalar_ty.isAnyFloat()) return self.todo("saturating float add", .{});
...@@ -7169,7 +7172,7 @@ pub const FuncGen = struct {...@@ -7169,7 +7172,7 @@ pub const FuncGen = struct {
7169 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7172 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7170 const lhs = try self.resolveInst(bin_op.lhs);7173 const lhs = try self.resolveInst(bin_op.lhs);
7171 const rhs = try self.resolveInst(bin_op.rhs);7174 const rhs = try self.resolveInst(bin_op.rhs);
7172 const inst_ty = self.air.typeOfIndex(inst);7175 const inst_ty = self.typeOfIndex(inst);
7173 const scalar_ty = inst_ty.scalarType(mod);7176 const scalar_ty = inst_ty.scalarType(mod);
71747177
7175 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.sub, inst_ty, 2, .{ lhs, rhs });7178 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.sub, inst_ty, 2, .{ lhs, rhs });
...@@ -7192,7 +7195,7 @@ pub const FuncGen = struct {...@@ -7192,7 +7195,7 @@ pub const FuncGen = struct {
7192 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7195 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7193 const lhs = try self.resolveInst(bin_op.lhs);7196 const lhs = try self.resolveInst(bin_op.lhs);
7194 const rhs = try self.resolveInst(bin_op.rhs);7197 const rhs = try self.resolveInst(bin_op.rhs);
7195 const inst_ty = self.air.typeOfIndex(inst);7198 const inst_ty = self.typeOfIndex(inst);
7196 const scalar_ty = inst_ty.scalarType(mod);7199 const scalar_ty = inst_ty.scalarType(mod);
71977200
7198 if (scalar_ty.isAnyFloat()) return self.todo("saturating float sub", .{});7201 if (scalar_ty.isAnyFloat()) return self.todo("saturating float sub", .{});
...@@ -7207,7 +7210,7 @@ pub const FuncGen = struct {...@@ -7207,7 +7210,7 @@ pub const FuncGen = struct {
7207 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7210 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7208 const lhs = try self.resolveInst(bin_op.lhs);7211 const lhs = try self.resolveInst(bin_op.lhs);
7209 const rhs = try self.resolveInst(bin_op.rhs);7212 const rhs = try self.resolveInst(bin_op.rhs);
7210 const inst_ty = self.air.typeOfIndex(inst);7213 const inst_ty = self.typeOfIndex(inst);
7211 const scalar_ty = inst_ty.scalarType(mod);7214 const scalar_ty = inst_ty.scalarType(mod);
72127215
7213 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.mul, inst_ty, 2, .{ lhs, rhs });7216 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.mul, inst_ty, 2, .{ lhs, rhs });
...@@ -7230,7 +7233,7 @@ pub const FuncGen = struct {...@@ -7230,7 +7233,7 @@ pub const FuncGen = struct {
7230 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7233 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7231 const lhs = try self.resolveInst(bin_op.lhs);7234 const lhs = try self.resolveInst(bin_op.lhs);
7232 const rhs = try self.resolveInst(bin_op.rhs);7235 const rhs = try self.resolveInst(bin_op.rhs);
7233 const inst_ty = self.air.typeOfIndex(inst);7236 const inst_ty = self.typeOfIndex(inst);
7234 const scalar_ty = inst_ty.scalarType(mod);7237 const scalar_ty = inst_ty.scalarType(mod);
72357238
7236 if (scalar_ty.isAnyFloat()) return self.todo("saturating float mul", .{});7239 if (scalar_ty.isAnyFloat()) return self.todo("saturating float mul", .{});
...@@ -7244,7 +7247,7 @@ pub const FuncGen = struct {...@@ -7244,7 +7247,7 @@ pub const FuncGen = struct {
7244 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7247 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7245 const lhs = try self.resolveInst(bin_op.lhs);7248 const lhs = try self.resolveInst(bin_op.lhs);
7246 const rhs = try self.resolveInst(bin_op.rhs);7249 const rhs = try self.resolveInst(bin_op.rhs);
7247 const inst_ty = self.air.typeOfIndex(inst);7250 const inst_ty = self.typeOfIndex(inst);
72487251
7249 return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });7252 return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });
7250 }7253 }
...@@ -7256,7 +7259,7 @@ pub const FuncGen = struct {...@@ -7256,7 +7259,7 @@ pub const FuncGen = struct {
7256 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7259 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7257 const lhs = try self.resolveInst(bin_op.lhs);7260 const lhs = try self.resolveInst(bin_op.lhs);
7258 const rhs = try self.resolveInst(bin_op.rhs);7261 const rhs = try self.resolveInst(bin_op.rhs);
7259 const inst_ty = self.air.typeOfIndex(inst);7262 const inst_ty = self.typeOfIndex(inst);
7260 const scalar_ty = inst_ty.scalarType(mod);7263 const scalar_ty = inst_ty.scalarType(mod);
72617264
7262 if (scalar_ty.isRuntimeFloat()) {7265 if (scalar_ty.isRuntimeFloat()) {
...@@ -7274,7 +7277,7 @@ pub const FuncGen = struct {...@@ -7274,7 +7277,7 @@ pub const FuncGen = struct {
7274 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7277 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7275 const lhs = try self.resolveInst(bin_op.lhs);7278 const lhs = try self.resolveInst(bin_op.lhs);
7276 const rhs = try self.resolveInst(bin_op.rhs);7279 const rhs = try self.resolveInst(bin_op.rhs);
7277 const inst_ty = self.air.typeOfIndex(inst);7280 const inst_ty = self.typeOfIndex(inst);
7278 const scalar_ty = inst_ty.scalarType(mod);7281 const scalar_ty = inst_ty.scalarType(mod);
72797282
7280 if (scalar_ty.isRuntimeFloat()) {7283 if (scalar_ty.isRuntimeFloat()) {
...@@ -7314,7 +7317,7 @@ pub const FuncGen = struct {...@@ -7314,7 +7317,7 @@ pub const FuncGen = struct {
7314 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7317 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7315 const lhs = try self.resolveInst(bin_op.lhs);7318 const lhs = try self.resolveInst(bin_op.lhs);
7316 const rhs = try self.resolveInst(bin_op.rhs);7319 const rhs = try self.resolveInst(bin_op.rhs);
7317 const inst_ty = self.air.typeOfIndex(inst);7320 const inst_ty = self.typeOfIndex(inst);
7318 const scalar_ty = inst_ty.scalarType(mod);7321 const scalar_ty = inst_ty.scalarType(mod);
73197322
7320 if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });7323 if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });
...@@ -7329,7 +7332,7 @@ pub const FuncGen = struct {...@@ -7329,7 +7332,7 @@ pub const FuncGen = struct {
7329 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7332 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7330 const lhs = try self.resolveInst(bin_op.lhs);7333 const lhs = try self.resolveInst(bin_op.lhs);
7331 const rhs = try self.resolveInst(bin_op.rhs);7334 const rhs = try self.resolveInst(bin_op.rhs);
7332 const inst_ty = self.air.typeOfIndex(inst);7335 const inst_ty = self.typeOfIndex(inst);
7333 const scalar_ty = inst_ty.scalarType(mod);7336 const scalar_ty = inst_ty.scalarType(mod);
73347337
7335 if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.fmod, inst_ty, 2, .{ lhs, rhs });7338 if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.fmod, inst_ty, 2, .{ lhs, rhs });
...@@ -7344,7 +7347,7 @@ pub const FuncGen = struct {...@@ -7344,7 +7347,7 @@ pub const FuncGen = struct {
7344 const bin_op = self.air.instructions.items(.data)[inst].bin_op;7347 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
7345 const lhs = try self.resolveInst(bin_op.lhs);7348 const lhs = try self.resolveInst(bin_op.lhs);
7346 const rhs = try self.resolveInst(bin_op.rhs);7349 const rhs = try self.resolveInst(bin_op.rhs);
7347 const inst_ty = self.air.typeOfIndex(inst);7350 const inst_ty = self.typeOfIndex(inst);
7348 const inst_llvm_ty = try self.dg.lowerType(inst_ty);7351 const inst_llvm_ty = try self.dg.lowerType(inst_ty);
7349 const scalar_ty = inst_ty.scalarType(mod);7352 const scalar_ty = inst_ty.scalarType(mod);
73507353
...@@ -7386,7 +7389,7 @@ pub const FuncGen = struct {...@@ -7386,7 +7389,7 @@ pub const FuncGen = struct {
7386 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;7389 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
7387 const ptr = try self.resolveInst(bin_op.lhs);7390 const ptr = try self.resolveInst(bin_op.lhs);
7388 const offset = try self.resolveInst(bin_op.rhs);7391 const offset = try self.resolveInst(bin_op.rhs);
7389 const ptr_ty = self.air.typeOf(bin_op.lhs);7392 const ptr_ty = self.typeOf(bin_op.lhs);
7390 const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());7393 const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
7391 switch (ptr_ty.ptrSize()) {7394 switch (ptr_ty.ptrSize()) {
7392 .One => {7395 .One => {
...@@ -7412,7 +7415,7 @@ pub const FuncGen = struct {...@@ -7412,7 +7415,7 @@ pub const FuncGen = struct {
7412 const ptr = try self.resolveInst(bin_op.lhs);7415 const ptr = try self.resolveInst(bin_op.lhs);
7413 const offset = try self.resolveInst(bin_op.rhs);7416 const offset = try self.resolveInst(bin_op.rhs);
7414 const negative_offset = self.builder.buildNeg(offset, "");7417 const negative_offset = self.builder.buildNeg(offset, "");
7415 const ptr_ty = self.air.typeOf(bin_op.lhs);7418 const ptr_ty = self.typeOf(bin_op.lhs);
7416 const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());7419 const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
7417 switch (ptr_ty.ptrSize()) {7420 switch (ptr_ty.ptrSize()) {
7418 .One => {7421 .One => {
...@@ -7447,9 +7450,9 @@ pub const FuncGen = struct {...@@ -7447,9 +7450,9 @@ pub const FuncGen = struct {
7447 const lhs = try self.resolveInst(extra.lhs);7450 const lhs = try self.resolveInst(extra.lhs);
7448 const rhs = try self.resolveInst(extra.rhs);7451 const rhs = try self.resolveInst(extra.rhs);
74497452
7450 const lhs_ty = self.air.typeOf(extra.lhs);7453 const lhs_ty = self.typeOf(extra.lhs);
7451 const scalar_ty = lhs_ty.scalarType(mod);7454 const scalar_ty = lhs_ty.scalarType(mod);
7452 const dest_ty = self.air.typeOfIndex(inst);7455 const dest_ty = self.typeOfIndex(inst);
74537456
7454 const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;7457 const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
74557458
...@@ -7735,7 +7738,7 @@ pub const FuncGen = struct {...@@ -7735,7 +7738,7 @@ pub const FuncGen = struct {
7735 const mulend2 = try self.resolveInst(extra.rhs);7738 const mulend2 = try self.resolveInst(extra.rhs);
7736 const addend = try self.resolveInst(pl_op.operand);7739 const addend = try self.resolveInst(pl_op.operand);
77377740
7738 const ty = self.air.typeOfIndex(inst);7741 const ty = self.typeOfIndex(inst);
7739 return self.buildFloatOp(.fma, ty, 3, .{ mulend1, mulend2, addend });7742 return self.buildFloatOp(.fma, ty, 3, .{ mulend1, mulend2, addend });
7740 }7743 }
77417744
...@@ -7747,12 +7750,12 @@ pub const FuncGen = struct {...@@ -7747,12 +7750,12 @@ pub const FuncGen = struct {
7747 const lhs = try self.resolveInst(extra.lhs);7750 const lhs = try self.resolveInst(extra.lhs);
7748 const rhs = try self.resolveInst(extra.rhs);7751 const rhs = try self.resolveInst(extra.rhs);
77497752
7750 const lhs_ty = self.air.typeOf(extra.lhs);7753 const lhs_ty = self.typeOf(extra.lhs);
7751 const rhs_ty = self.air.typeOf(extra.rhs);7754 const rhs_ty = self.typeOf(extra.rhs);
7752 const lhs_scalar_ty = lhs_ty.scalarType(mod);7755 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7753 const rhs_scalar_ty = rhs_ty.scalarType(mod);7756 const rhs_scalar_ty = rhs_ty.scalarType(mod);
77547757
7755 const dest_ty = self.air.typeOfIndex(inst);7758 const dest_ty = self.typeOfIndex(inst);
7756 const llvm_dest_ty = try self.dg.lowerType(dest_ty);7759 const llvm_dest_ty = try self.dg.lowerType(dest_ty);
77577760
7758 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))7761 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
...@@ -7821,8 +7824,8 @@ pub const FuncGen = struct {...@@ -7821,8 +7824,8 @@ pub const FuncGen = struct {
7821 const lhs = try self.resolveInst(bin_op.lhs);7824 const lhs = try self.resolveInst(bin_op.lhs);
7822 const rhs = try self.resolveInst(bin_op.rhs);7825 const rhs = try self.resolveInst(bin_op.rhs);
78237826
7824 const lhs_ty = self.air.typeOf(bin_op.lhs);7827 const lhs_ty = self.typeOf(bin_op.lhs);
7825 const rhs_ty = self.air.typeOf(bin_op.rhs);7828 const rhs_ty = self.typeOf(bin_op.rhs);
7826 const lhs_scalar_ty = lhs_ty.scalarType(mod);7829 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7827 const rhs_scalar_ty = rhs_ty.scalarType(mod);7830 const rhs_scalar_ty = rhs_ty.scalarType(mod);
78287831
...@@ -7841,8 +7844,8 @@ pub const FuncGen = struct {...@@ -7841,8 +7844,8 @@ pub const FuncGen = struct {
7841 const lhs = try self.resolveInst(bin_op.lhs);7844 const lhs = try self.resolveInst(bin_op.lhs);
7842 const rhs = try self.resolveInst(bin_op.rhs);7845 const rhs = try self.resolveInst(bin_op.rhs);
78437846
7844 const lhs_type = self.air.typeOf(bin_op.lhs);7847 const lhs_type = self.typeOf(bin_op.lhs);
7845 const rhs_type = self.air.typeOf(bin_op.rhs);7848 const rhs_type = self.typeOf(bin_op.rhs);
7846 const lhs_scalar_ty = lhs_type.scalarType(mod);7849 const lhs_scalar_ty = lhs_type.scalarType(mod);
7847 const rhs_scalar_ty = rhs_type.scalarType(mod);7850 const rhs_scalar_ty = rhs_type.scalarType(mod);
78487851
...@@ -7860,8 +7863,8 @@ pub const FuncGen = struct {...@@ -7860,8 +7863,8 @@ pub const FuncGen = struct {
7860 const lhs = try self.resolveInst(bin_op.lhs);7863 const lhs = try self.resolveInst(bin_op.lhs);
7861 const rhs = try self.resolveInst(bin_op.rhs);7864 const rhs = try self.resolveInst(bin_op.rhs);
78627865
7863 const lhs_ty = self.air.typeOf(bin_op.lhs);7866 const lhs_ty = self.typeOf(bin_op.lhs);
7864 const rhs_ty = self.air.typeOf(bin_op.rhs);7867 const rhs_ty = self.typeOf(bin_op.rhs);
7865 const lhs_scalar_ty = lhs_ty.scalarType(mod);7868 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7866 const rhs_scalar_ty = rhs_ty.scalarType(mod);7869 const rhs_scalar_ty = rhs_ty.scalarType(mod);
7867 const lhs_bits = lhs_scalar_ty.bitSize(mod);7870 const lhs_bits = lhs_scalar_ty.bitSize(mod);
...@@ -7903,8 +7906,8 @@ pub const FuncGen = struct {...@@ -7903,8 +7906,8 @@ pub const FuncGen = struct {
7903 const lhs = try self.resolveInst(bin_op.lhs);7906 const lhs = try self.resolveInst(bin_op.lhs);
7904 const rhs = try self.resolveInst(bin_op.rhs);7907 const rhs = try self.resolveInst(bin_op.rhs);
79057908
7906 const lhs_ty = self.air.typeOf(bin_op.lhs);7909 const lhs_ty = self.typeOf(bin_op.lhs);
7907 const rhs_ty = self.air.typeOf(bin_op.rhs);7910 const rhs_ty = self.typeOf(bin_op.rhs);
7908 const lhs_scalar_ty = lhs_ty.scalarType(mod);7911 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7909 const rhs_scalar_ty = rhs_ty.scalarType(mod);7912 const rhs_scalar_ty = rhs_ty.scalarType(mod);
79107913
...@@ -7932,11 +7935,11 @@ pub const FuncGen = struct {...@@ -7932,11 +7935,11 @@ pub const FuncGen = struct {
7932 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7935 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7933 const mod = self.dg.module;7936 const mod = self.dg.module;
7934 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7937 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7935 const dest_ty = self.air.typeOfIndex(inst);7938 const dest_ty = self.typeOfIndex(inst);
7936 const dest_info = dest_ty.intInfo(mod);7939 const dest_info = dest_ty.intInfo(mod);
7937 const dest_llvm_ty = try self.dg.lowerType(dest_ty);7940 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
7938 const operand = try self.resolveInst(ty_op.operand);7941 const operand = try self.resolveInst(ty_op.operand);
7939 const operand_ty = self.air.typeOf(ty_op.operand);7942 const operand_ty = self.typeOf(ty_op.operand);
7940 const operand_info = operand_ty.intInfo(mod);7943 const operand_info = operand_ty.intInfo(mod);
79417944
7942 if (operand_info.bits < dest_info.bits) {7945 if (operand_info.bits < dest_info.bits) {
...@@ -7954,7 +7957,7 @@ pub const FuncGen = struct {...@@ -7954,7 +7957,7 @@ pub const FuncGen = struct {
7954 fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7957 fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7955 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7958 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7956 const operand = try self.resolveInst(ty_op.operand);7959 const operand = try self.resolveInst(ty_op.operand);
7957 const dest_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));7960 const dest_llvm_ty = try self.dg.lowerType(self.typeOfIndex(inst));
7958 return self.builder.buildTrunc(operand, dest_llvm_ty, "");7961 return self.builder.buildTrunc(operand, dest_llvm_ty, "");
7959 }7962 }
79607963
...@@ -7962,8 +7965,8 @@ pub const FuncGen = struct {...@@ -7962,8 +7965,8 @@ pub const FuncGen = struct {
7962 const mod = self.dg.module;7965 const mod = self.dg.module;
7963 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7966 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7964 const operand = try self.resolveInst(ty_op.operand);7967 const operand = try self.resolveInst(ty_op.operand);
7965 const operand_ty = self.air.typeOf(ty_op.operand);7968 const operand_ty = self.typeOf(ty_op.operand);
7966 const dest_ty = self.air.typeOfIndex(inst);7969 const dest_ty = self.typeOfIndex(inst);
7967 const target = mod.getTarget();7970 const target = mod.getTarget();
7968 const dest_bits = dest_ty.floatBits(target);7971 const dest_bits = dest_ty.floatBits(target);
7969 const src_bits = operand_ty.floatBits(target);7972 const src_bits = operand_ty.floatBits(target);
...@@ -7992,8 +7995,8 @@ pub const FuncGen = struct {...@@ -7992,8 +7995,8 @@ pub const FuncGen = struct {
7992 const mod = self.dg.module;7995 const mod = self.dg.module;
7993 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7996 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7994 const operand = try self.resolveInst(ty_op.operand);7997 const operand = try self.resolveInst(ty_op.operand);
7995 const operand_ty = self.air.typeOf(ty_op.operand);7998 const operand_ty = self.typeOf(ty_op.operand);
7996 const dest_ty = self.air.typeOfIndex(inst);7999 const dest_ty = self.typeOfIndex(inst);
7997 const target = mod.getTarget();8000 const target = mod.getTarget();
7998 const dest_bits = dest_ty.floatBits(target);8001 const dest_bits = dest_ty.floatBits(target);
7999 const src_bits = operand_ty.floatBits(target);8002 const src_bits = operand_ty.floatBits(target);
...@@ -8021,16 +8024,16 @@ pub const FuncGen = struct {...@@ -8021,16 +8024,16 @@ pub const FuncGen = struct {
8021 fn airPtrToInt(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8024 fn airPtrToInt(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8022 const un_op = self.air.instructions.items(.data)[inst].un_op;8025 const un_op = self.air.instructions.items(.data)[inst].un_op;
8023 const operand = try self.resolveInst(un_op);8026 const operand = try self.resolveInst(un_op);
8024 const ptr_ty = self.air.typeOf(un_op);8027 const ptr_ty = self.typeOf(un_op);
8025 const operand_ptr = self.sliceOrArrayPtr(operand, ptr_ty);8028 const operand_ptr = self.sliceOrArrayPtr(operand, ptr_ty);
8026 const dest_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));8029 const dest_llvm_ty = try self.dg.lowerType(self.typeOfIndex(inst));
8027 return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, "");8030 return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, "");
8028 }8031 }
80298032
8030 fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !*llvm.Value {8033 fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !*llvm.Value {
8031 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8034 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8032 const operand_ty = self.air.typeOf(ty_op.operand);8035 const operand_ty = self.typeOf(ty_op.operand);
8033 const inst_ty = self.air.typeOfIndex(inst);8036 const inst_ty = self.typeOfIndex(inst);
8034 const operand = try self.resolveInst(ty_op.operand);8037 const operand = try self.resolveInst(ty_op.operand);
8035 return self.bitCast(operand, operand_ty, inst_ty);8038 return self.bitCast(operand, operand_ty, inst_ty);
8036 }8039 }
...@@ -8159,17 +8162,17 @@ pub const FuncGen = struct {...@@ -8159,17 +8162,17 @@ pub const FuncGen = struct {
8159 }8162 }
81608163
8161 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8164 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8165 const mod = self.dg.module;
8162 const arg_val = self.args[self.arg_index];8166 const arg_val = self.args[self.arg_index];
8163 self.arg_index += 1;8167 self.arg_index += 1;
81648168
8165 const inst_ty = self.air.typeOfIndex(inst);8169 const inst_ty = self.typeOfIndex(inst);
8166 if (self.dg.object.di_builder) |dib| {8170 if (self.dg.object.di_builder) |dib| {
8167 if (needDbgVarWorkaround(self.dg)) {8171 if (needDbgVarWorkaround(self.dg)) {
8168 return arg_val;8172 return arg_val;
8169 }8173 }
81708174
8171 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;8175 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
8172 const mod = self.dg.module;
8173 const func = self.dg.decl.getFunction().?;8176 const func = self.dg.decl.getFunction().?;
8174 const lbrace_line = mod.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;8177 const lbrace_line = mod.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
8175 const lbrace_col = func.lbrace_column + 1;8178 const lbrace_col = func.lbrace_column + 1;
...@@ -8203,9 +8206,9 @@ pub const FuncGen = struct {...@@ -8203,9 +8206,9 @@ pub const FuncGen = struct {
8203 }8206 }
82048207
8205 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8208 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8206 const ptr_ty = self.air.typeOfIndex(inst);
8207 const pointee_type = ptr_ty.childType();
8208 const mod = self.dg.module;8209 const mod = self.dg.module;
8210 const ptr_ty = self.typeOfIndex(inst);
8211 const pointee_type = ptr_ty.childType();
8209 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);8212 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
82108213
8211 const pointee_llvm_ty = try self.dg.lowerType(pointee_type);8214 const pointee_llvm_ty = try self.dg.lowerType(pointee_type);
...@@ -8214,9 +8217,9 @@ pub const FuncGen = struct {...@@ -8214,9 +8217,9 @@ pub const FuncGen = struct {
8214 }8217 }
82158218
8216 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8219 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8217 const ptr_ty = self.air.typeOfIndex(inst);
8218 const ret_ty = ptr_ty.childType();
8219 const mod = self.dg.module;8220 const mod = self.dg.module;
8221 const ptr_ty = self.typeOfIndex(inst);
8222 const ret_ty = ptr_ty.childType();
8220 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);8223 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
8221 if (self.ret_ptr) |ret_ptr| return ret_ptr;8224 if (self.ret_ptr) |ret_ptr| return ret_ptr;
8222 const ret_llvm_ty = try self.dg.lowerType(ret_ty);8225 const ret_llvm_ty = try self.dg.lowerType(ret_ty);
...@@ -8232,7 +8235,7 @@ pub const FuncGen = struct {...@@ -8232,7 +8235,7 @@ pub const FuncGen = struct {
8232 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {8235 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {
8233 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8236 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8234 const dest_ptr = try self.resolveInst(bin_op.lhs);8237 const dest_ptr = try self.resolveInst(bin_op.lhs);
8235 const ptr_ty = self.air.typeOf(bin_op.lhs);8238 const ptr_ty = self.typeOf(bin_op.lhs);
8236 const operand_ty = ptr_ty.childType();8239 const operand_ty = ptr_ty.childType();
8237 const mod = self.dg.module;8240 const mod = self.dg.module;
82388241
...@@ -8285,7 +8288,7 @@ pub const FuncGen = struct {...@@ -8285,7 +8288,7 @@ pub const FuncGen = struct {
8285 const mod = fg.dg.module;8288 const mod = fg.dg.module;
8286 const inst = body_tail[0];8289 const inst = body_tail[0];
8287 const ty_op = fg.air.instructions.items(.data)[inst].ty_op;8290 const ty_op = fg.air.instructions.items(.data)[inst].ty_op;
8288 const ptr_ty = fg.air.typeOf(ty_op.operand);8291 const ptr_ty = fg.typeOf(ty_op.operand);
8289 const ptr_info = ptr_ty.ptrInfo().data;8292 const ptr_info = ptr_ty.ptrInfo().data;
8290 const ptr = try fg.resolveInst(ty_op.operand);8293 const ptr = try fg.resolveInst(ty_op.operand);
82918294
...@@ -8361,7 +8364,7 @@ pub const FuncGen = struct {...@@ -8361,7 +8364,7 @@ pub const FuncGen = struct {
8361 const ptr = try self.resolveInst(extra.ptr);8364 const ptr = try self.resolveInst(extra.ptr);
8362 var expected_value = try self.resolveInst(extra.expected_value);8365 var expected_value = try self.resolveInst(extra.expected_value);
8363 var new_value = try self.resolveInst(extra.new_value);8366 var new_value = try self.resolveInst(extra.new_value);
8364 const operand_ty = self.air.typeOf(extra.ptr).elemType();8367 const operand_ty = self.typeOf(extra.ptr).elemType();
8365 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);8368 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
8366 if (opt_abi_ty) |abi_ty| {8369 if (opt_abi_ty) |abi_ty| {
8367 // operand needs widening and truncating8370 // operand needs widening and truncating
...@@ -8383,7 +8386,7 @@ pub const FuncGen = struct {...@@ -8383,7 +8386,7 @@ pub const FuncGen = struct {
8383 );8386 );
8384 result.setWeak(llvm.Bool.fromBool(is_weak));8387 result.setWeak(llvm.Bool.fromBool(is_weak));
83858388
8386 const optional_ty = self.air.typeOfIndex(inst);8389 const optional_ty = self.typeOfIndex(inst);
83878390
8388 var payload = self.builder.buildExtractValue(result, 0, "");8391 var payload = self.builder.buildExtractValue(result, 0, "");
8389 if (opt_abi_ty != null) {8392 if (opt_abi_ty != null) {
...@@ -8406,7 +8409,7 @@ pub const FuncGen = struct {...@@ -8406,7 +8409,7 @@ pub const FuncGen = struct {
8406 const pl_op = self.air.instructions.items(.data)[inst].pl_op;8409 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
8407 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;8410 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
8408 const ptr = try self.resolveInst(pl_op.operand);8411 const ptr = try self.resolveInst(pl_op.operand);
8409 const ptr_ty = self.air.typeOf(pl_op.operand);8412 const ptr_ty = self.typeOf(pl_op.operand);
8410 const operand_ty = ptr_ty.elemType();8413 const operand_ty = ptr_ty.elemType();
8411 const operand = try self.resolveInst(extra.operand);8414 const operand = try self.resolveInst(extra.operand);
8412 const is_signed_int = operand_ty.isSignedInt(mod);8415 const is_signed_int = operand_ty.isSignedInt(mod);
...@@ -8461,7 +8464,7 @@ pub const FuncGen = struct {...@@ -8461,7 +8464,7 @@ pub const FuncGen = struct {
8461 const mod = self.dg.module;8464 const mod = self.dg.module;
8462 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;8465 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;
8463 const ptr = try self.resolveInst(atomic_load.ptr);8466 const ptr = try self.resolveInst(atomic_load.ptr);
8464 const ptr_ty = self.air.typeOf(atomic_load.ptr);8467 const ptr_ty = self.typeOf(atomic_load.ptr);
8465 const ptr_info = ptr_ty.ptrInfo().data;8468 const ptr_info = ptr_ty.ptrInfo().data;
8466 const elem_ty = ptr_info.pointee_type;8469 const elem_ty = ptr_info.pointee_type;
8467 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))8470 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))
...@@ -8494,7 +8497,7 @@ pub const FuncGen = struct {...@@ -8494,7 +8497,7 @@ pub const FuncGen = struct {
8494 ) !?*llvm.Value {8497 ) !?*llvm.Value {
8495 const mod = self.dg.module;8498 const mod = self.dg.module;
8496 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8499 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8497 const ptr_ty = self.air.typeOf(bin_op.lhs);8500 const ptr_ty = self.typeOf(bin_op.lhs);
8498 const operand_ty = ptr_ty.childType();8501 const operand_ty = ptr_ty.childType();
8499 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null;8502 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null;
8500 const ptr = try self.resolveInst(bin_op.lhs);8503 const ptr = try self.resolveInst(bin_op.lhs);
...@@ -8517,8 +8520,8 @@ pub const FuncGen = struct {...@@ -8517,8 +8520,8 @@ pub const FuncGen = struct {
8517 const mod = self.dg.module;8520 const mod = self.dg.module;
8518 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8521 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8519 const dest_slice = try self.resolveInst(bin_op.lhs);8522 const dest_slice = try self.resolveInst(bin_op.lhs);
8520 const ptr_ty = self.air.typeOf(bin_op.lhs);8523 const ptr_ty = self.typeOf(bin_op.lhs);
8521 const elem_ty = self.air.typeOf(bin_op.rhs);8524 const elem_ty = self.typeOf(bin_op.rhs);
8522 const module = self.dg.module;8525 const module = self.dg.module;
8523 const target = module.getTarget();8526 const target = module.getTarget();
8524 const dest_ptr_align = ptr_ty.ptrAlignment(mod);8527 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
...@@ -8641,9 +8644,9 @@ pub const FuncGen = struct {...@@ -8641,9 +8644,9 @@ pub const FuncGen = struct {
8641 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8644 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8642 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8645 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8643 const dest_slice = try self.resolveInst(bin_op.lhs);8646 const dest_slice = try self.resolveInst(bin_op.lhs);
8644 const dest_ptr_ty = self.air.typeOf(bin_op.lhs);8647 const dest_ptr_ty = self.typeOf(bin_op.lhs);
8645 const src_slice = try self.resolveInst(bin_op.rhs);8648 const src_slice = try self.resolveInst(bin_op.rhs);
8646 const src_ptr_ty = self.air.typeOf(bin_op.rhs);8649 const src_ptr_ty = self.typeOf(bin_op.rhs);
8647 const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);8650 const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);
8648 const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);8651 const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);
8649 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);8652 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
...@@ -8663,7 +8666,7 @@ pub const FuncGen = struct {...@@ -8663,7 +8666,7 @@ pub const FuncGen = struct {
8663 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8666 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8664 const mod = self.dg.module;8667 const mod = self.dg.module;
8665 const bin_op = self.air.instructions.items(.data)[inst].bin_op;8668 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
8666 const un_ty = self.air.typeOf(bin_op.lhs).childType();8669 const un_ty = self.typeOf(bin_op.lhs).childType();
8667 const layout = un_ty.unionGetLayout(mod);8670 const layout = un_ty.unionGetLayout(mod);
8668 if (layout.tag_size == 0) return null;8671 if (layout.tag_size == 0) return null;
8669 const union_ptr = try self.resolveInst(bin_op.lhs);8672 const union_ptr = try self.resolveInst(bin_op.lhs);
...@@ -8684,7 +8687,7 @@ pub const FuncGen = struct {...@@ -8684,7 +8687,7 @@ pub const FuncGen = struct {
8684 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8687 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8685 const mod = self.dg.module;8688 const mod = self.dg.module;
8686 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8689 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8687 const un_ty = self.air.typeOf(ty_op.operand);8690 const un_ty = self.typeOf(ty_op.operand);
8688 const layout = un_ty.unionGetLayout(mod);8691 const layout = un_ty.unionGetLayout(mod);
8689 if (layout.tag_size == 0) return null;8692 if (layout.tag_size == 0) return null;
8690 const union_handle = try self.resolveInst(ty_op.operand);8693 const union_handle = try self.resolveInst(ty_op.operand);
...@@ -8708,7 +8711,7 @@ pub const FuncGen = struct {...@@ -8708,7 +8711,7 @@ pub const FuncGen = struct {
8708 fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !?*llvm.Value {8711 fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !?*llvm.Value {
8709 const un_op = self.air.instructions.items(.data)[inst].un_op;8712 const un_op = self.air.instructions.items(.data)[inst].un_op;
8710 const operand = try self.resolveInst(un_op);8713 const operand = try self.resolveInst(un_op);
8711 const operand_ty = self.air.typeOf(un_op);8714 const operand_ty = self.typeOf(un_op);
87128715
8713 return self.buildFloatOp(op, operand_ty, 1, .{operand});8716 return self.buildFloatOp(op, operand_ty, 1, .{operand});
8714 }8717 }
...@@ -8718,7 +8721,7 @@ pub const FuncGen = struct {...@@ -8718,7 +8721,7 @@ pub const FuncGen = struct {
87188721
8719 const un_op = self.air.instructions.items(.data)[inst].un_op;8722 const un_op = self.air.instructions.items(.data)[inst].un_op;
8720 const operand = try self.resolveInst(un_op);8723 const operand = try self.resolveInst(un_op);
8721 const operand_ty = self.air.typeOf(un_op);8724 const operand_ty = self.typeOf(un_op);
87228725
8723 return self.buildFloatOp(.neg, operand_ty, 1, .{operand});8726 return self.buildFloatOp(.neg, operand_ty, 1, .{operand});
8724 }8727 }
...@@ -8726,7 +8729,7 @@ pub const FuncGen = struct {...@@ -8726,7 +8729,7 @@ pub const FuncGen = struct {
8726 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {8729 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8727 const mod = self.dg.module;8730 const mod = self.dg.module;
8728 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8731 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8729 const operand_ty = self.air.typeOf(ty_op.operand);8732 const operand_ty = self.typeOf(ty_op.operand);
8730 const operand = try self.resolveInst(ty_op.operand);8733 const operand = try self.resolveInst(ty_op.operand);
87318734
8732 const llvm_i1 = self.context.intType(1);8735 const llvm_i1 = self.context.intType(1);
...@@ -8735,7 +8738,7 @@ pub const FuncGen = struct {...@@ -8735,7 +8738,7 @@ pub const FuncGen = struct {
87358738
8736 const params = [_]*llvm.Value{ operand, llvm_i1.constNull() };8739 const params = [_]*llvm.Value{ operand, llvm_i1.constNull() };
8737 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");8740 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
8738 const result_ty = self.air.typeOfIndex(inst);8741 const result_ty = self.typeOfIndex(inst);
8739 const result_llvm_ty = try self.dg.lowerType(result_ty);8742 const result_llvm_ty = try self.dg.lowerType(result_ty);
87408743
8741 const bits = operand_ty.intInfo(mod).bits;8744 const bits = operand_ty.intInfo(mod).bits;
...@@ -8752,7 +8755,7 @@ pub const FuncGen = struct {...@@ -8752,7 +8755,7 @@ pub const FuncGen = struct {
8752 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {8755 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8753 const mod = self.dg.module;8756 const mod = self.dg.module;
8754 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8757 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8755 const operand_ty = self.air.typeOf(ty_op.operand);8758 const operand_ty = self.typeOf(ty_op.operand);
8756 const operand = try self.resolveInst(ty_op.operand);8759 const operand = try self.resolveInst(ty_op.operand);
87578760
8758 const params = [_]*llvm.Value{operand};8761 const params = [_]*llvm.Value{operand};
...@@ -8760,7 +8763,7 @@ pub const FuncGen = struct {...@@ -8760,7 +8763,7 @@ pub const FuncGen = struct {
8760 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});8763 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
87618764
8762 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");8765 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
8763 const result_ty = self.air.typeOfIndex(inst);8766 const result_ty = self.typeOfIndex(inst);
8764 const result_llvm_ty = try self.dg.lowerType(result_ty);8767 const result_llvm_ty = try self.dg.lowerType(result_ty);
87658768
8766 const bits = operand_ty.intInfo(mod).bits;8769 const bits = operand_ty.intInfo(mod).bits;
...@@ -8777,7 +8780,7 @@ pub const FuncGen = struct {...@@ -8777,7 +8780,7 @@ pub const FuncGen = struct {
8777 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {8780 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8778 const mod = self.dg.module;8781 const mod = self.dg.module;
8779 const ty_op = self.air.instructions.items(.data)[inst].ty_op;8782 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
8780 const operand_ty = self.air.typeOf(ty_op.operand);8783 const operand_ty = self.typeOf(ty_op.operand);
8781 var bits = operand_ty.intInfo(mod).bits;8784 var bits = operand_ty.intInfo(mod).bits;
8782 assert(bits % 8 == 0);8785 assert(bits % 8 == 0);
87838786
...@@ -8815,7 +8818,7 @@ pub const FuncGen = struct {...@@ -8815,7 +8818,7 @@ pub const FuncGen = struct {
88158818
8816 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");8819 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
88178820
8818 const result_ty = self.air.typeOfIndex(inst);8821 const result_ty = self.typeOfIndex(inst);
8819 const result_llvm_ty = try self.dg.lowerType(result_ty);8822 const result_llvm_ty = try self.dg.lowerType(result_ty);
8820 const result_bits = result_ty.intInfo(mod).bits;8823 const result_bits = result_ty.intInfo(mod).bits;
8821 if (bits > result_bits) {8824 if (bits > result_bits) {
...@@ -8876,7 +8879,7 @@ pub const FuncGen = struct {...@@ -8876,7 +8879,7 @@ pub const FuncGen = struct {
8876 fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8879 fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8877 const un_op = self.air.instructions.items(.data)[inst].un_op;8880 const un_op = self.air.instructions.items(.data)[inst].un_op;
8878 const operand = try self.resolveInst(un_op);8881 const operand = try self.resolveInst(un_op);
8879 const enum_ty = self.air.typeOf(un_op);8882 const enum_ty = self.typeOf(un_op);
88808883
8881 const llvm_fn = try self.getIsNamedEnumValueFunction(enum_ty);8884 const llvm_fn = try self.getIsNamedEnumValueFunction(enum_ty);
8882 const params = [_]*llvm.Value{operand};8885 const params = [_]*llvm.Value{operand};
...@@ -8954,7 +8957,7 @@ pub const FuncGen = struct {...@@ -8954,7 +8957,7 @@ pub const FuncGen = struct {
8954 fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8957 fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8955 const un_op = self.air.instructions.items(.data)[inst].un_op;8958 const un_op = self.air.instructions.items(.data)[inst].un_op;
8956 const operand = try self.resolveInst(un_op);8959 const operand = try self.resolveInst(un_op);
8957 const enum_ty = self.air.typeOf(un_op);8960 const enum_ty = self.typeOf(un_op);
89588961
8959 const llvm_fn = try self.getEnumTagNameFunction(enum_ty);8962 const llvm_fn = try self.getEnumTagNameFunction(enum_ty);
8960 const params = [_]*llvm.Value{operand};8963 const params = [_]*llvm.Value{operand};
...@@ -9083,7 +9086,7 @@ pub const FuncGen = struct {...@@ -9083,7 +9086,7 @@ pub const FuncGen = struct {
9083 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9086 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9084 const un_op = self.air.instructions.items(.data)[inst].un_op;9087 const un_op = self.air.instructions.items(.data)[inst].un_op;
9085 const operand = try self.resolveInst(un_op);9088 const operand = try self.resolveInst(un_op);
9086 const slice_ty = self.air.typeOfIndex(inst);9089 const slice_ty = self.typeOfIndex(inst);
9087 const slice_llvm_ty = try self.dg.lowerType(slice_ty);9090 const slice_llvm_ty = try self.dg.lowerType(slice_ty);
90889091
9089 const error_name_table_ptr = try self.getErrorNameTable();9092 const error_name_table_ptr = try self.getErrorNameTable();
...@@ -9097,7 +9100,7 @@ pub const FuncGen = struct {...@@ -9097,7 +9100,7 @@ pub const FuncGen = struct {
9097 fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9100 fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9098 const ty_op = self.air.instructions.items(.data)[inst].ty_op;9101 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
9099 const scalar = try self.resolveInst(ty_op.operand);9102 const scalar = try self.resolveInst(ty_op.operand);
9100 const vector_ty = self.air.typeOfIndex(inst);9103 const vector_ty = self.typeOfIndex(inst);
9101 const len = vector_ty.vectorLen();9104 const len = vector_ty.vectorLen();
9102 return self.builder.buildVectorSplat(len, scalar, "");9105 return self.builder.buildVectorSplat(len, scalar, "");
9103 }9106 }
...@@ -9120,7 +9123,7 @@ pub const FuncGen = struct {...@@ -9120,7 +9123,7 @@ pub const FuncGen = struct {
9120 const b = try self.resolveInst(extra.b);9123 const b = try self.resolveInst(extra.b);
9121 const mask = self.air.values[extra.mask];9124 const mask = self.air.values[extra.mask];
9122 const mask_len = extra.mask_len;9125 const mask_len = extra.mask_len;
9123 const a_len = self.air.typeOf(extra.a).vectorLen();9126 const a_len = self.typeOf(extra.a).vectorLen();
91249127
9125 // LLVM uses integers larger than the length of the first array to9128 // LLVM uses integers larger than the length of the first array to
9126 // index into the second array. This was deemed unnecessarily fragile9129 // index into the second array. This was deemed unnecessarily fragile
...@@ -9219,8 +9222,8 @@ pub const FuncGen = struct {...@@ -9219,8 +9222,8 @@ pub const FuncGen = struct {
92199222
9220 const reduce = self.air.instructions.items(.data)[inst].reduce;9223 const reduce = self.air.instructions.items(.data)[inst].reduce;
9221 const operand = try self.resolveInst(reduce.operand);9224 const operand = try self.resolveInst(reduce.operand);
9222 const operand_ty = self.air.typeOf(reduce.operand);9225 const operand_ty = self.typeOf(reduce.operand);
9223 const scalar_ty = self.air.typeOfIndex(inst);9226 const scalar_ty = self.typeOfIndex(inst);
92249227
9225 switch (reduce.operation) {9228 switch (reduce.operation) {
9226 .And => return self.builder.buildAndReduce(operand),9229 .And => return self.builder.buildAndReduce(operand),
...@@ -9300,12 +9303,12 @@ pub const FuncGen = struct {...@@ -9300,12 +9303,12 @@ pub const FuncGen = struct {
9300 }9303 }
93019304
9302 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9305 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9306 const mod = self.dg.module;
9303 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;9307 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
9304 const result_ty = self.air.typeOfIndex(inst);9308 const result_ty = self.typeOfIndex(inst);
9305 const len = @intCast(usize, result_ty.arrayLen());9309 const len = @intCast(usize, result_ty.arrayLen());
9306 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);9310 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
9307 const llvm_result_ty = try self.dg.lowerType(result_ty);9311 const llvm_result_ty = try self.dg.lowerType(result_ty);
9308 const mod = self.dg.module;
93099312
9310 switch (result_ty.zigTypeTag(mod)) {9313 switch (result_ty.zigTypeTag(mod)) {
9311 .Vector => {9314 .Vector => {
...@@ -9370,7 +9373,7 @@ pub const FuncGen = struct {...@@ -9370,7 +9373,7 @@ pub const FuncGen = struct {
9370 const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");9373 const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
9371 var field_ptr_payload: Type.Payload.Pointer = .{9374 var field_ptr_payload: Type.Payload.Pointer = .{
9372 .data = .{9375 .data = .{
9373 .pointee_type = self.air.typeOf(elem),9376 .pointee_type = self.typeOf(elem),
9374 .@"align" = result_ty.structFieldAlign(i, mod),9377 .@"align" = result_ty.structFieldAlign(i, mod),
9375 .@"addrspace" = .generic,9378 .@"addrspace" = .generic,
9376 },9379 },
...@@ -9440,7 +9443,7 @@ pub const FuncGen = struct {...@@ -9440,7 +9443,7 @@ pub const FuncGen = struct {
9440 const mod = self.dg.module;9443 const mod = self.dg.module;
9441 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;9444 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
9442 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;9445 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
9443 const union_ty = self.air.typeOfIndex(inst);9446 const union_ty = self.typeOfIndex(inst);
9444 const union_llvm_ty = try self.dg.lowerType(union_ty);9447 const union_llvm_ty = try self.dg.lowerType(union_ty);
9445 const layout = union_ty.unionGetLayout(mod);9448 const layout = union_ty.unionGetLayout(mod);
9446 const union_obj = union_ty.cast(Type.Payload.Union).?.data;9449 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
...@@ -9643,7 +9646,7 @@ pub const FuncGen = struct {...@@ -9643,7 +9646,7 @@ pub const FuncGen = struct {
96439646
9644 fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {9647 fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9645 const ty_op = self.air.instructions.items(.data)[inst].ty_op;9648 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
9646 const inst_ty = self.air.typeOfIndex(inst);9649 const inst_ty = self.typeOfIndex(inst);
9647 const operand = try self.resolveInst(ty_op.operand);9650 const operand = try self.resolveInst(ty_op.operand);
96489651
9649 const llvm_dest_ty = try self.dg.lowerType(inst_ty);9652 const llvm_dest_ty = try self.dg.lowerType(inst_ty);
...@@ -9830,7 +9833,7 @@ pub const FuncGen = struct {...@@ -9830,7 +9833,7 @@ pub const FuncGen = struct {
9830 switch (struct_ty.zigTypeTag(mod)) {9833 switch (struct_ty.zigTypeTag(mod)) {
9831 .Struct => switch (struct_ty.containerLayout()) {9834 .Struct => switch (struct_ty.containerLayout()) {
9832 .Packed => {9835 .Packed => {
9833 const result_ty = self.air.typeOfIndex(inst);9836 const result_ty = self.typeOfIndex(inst);
9834 const result_ty_info = result_ty.ptrInfo().data;9837 const result_ty_info = result_ty.ptrInfo().data;
98359838
9836 if (result_ty_info.host_size != 0) {9839 if (result_ty_info.host_size != 0) {
...@@ -10172,6 +10175,16 @@ pub const FuncGen = struct {...@@ -10172,6 +10175,16 @@ pub const FuncGen = struct {
10172 );10175 );
10173 return call;10176 return call;
10174 }10177 }
10178
10179 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {
10180 const mod = fg.dg.module;
10181 return fg.air.typeOf(inst, mod.intern_pool);
10182 }
10183
10184 fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {
10185 const mod = fg.dg.module;
10186 return fg.air.typeOfIndex(inst, mod.intern_pool);
10187 }
10175};10188};
1017610189
10177fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {10190fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
...@@ -10833,7 +10846,7 @@ const ParamTypeIterator = struct {...@@ -10833,7 +10846,7 @@ const ParamTypeIterator = struct {
10833 if (it.zig_index >= args.len) {10846 if (it.zig_index >= args.len) {
10834 return null;10847 return null;
10835 } else {10848 } else {
10836 return nextInner(it, fg.air.typeOf(args[it.zig_index]));10849 return nextInner(it, fg.typeOf(args[it.zig_index]));
10837 }10850 }
10838 } else {10851 } else {
10839 return nextInner(it, it.fn_info.param_types[it.zig_index]);10852 return nextInner(it, it.fn_info.param_types[it.zig_index]);
src/codegen/spirv.zig+65-54
...@@ -233,7 +233,7 @@ pub const DeclGen = struct {...@@ -233,7 +233,7 @@ pub const DeclGen = struct {
233 fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef {233 fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef {
234 const mod = self.module;234 const mod = self.module;
235 if (self.air.value(inst, mod)) |val| {235 if (self.air.value(inst, mod)) |val| {
236 const ty = self.air.typeOf(inst);236 const ty = self.typeOf(inst);
237 if (ty.zigTypeTag(mod) == .Fn) {237 if (ty.zigTypeTag(mod) == .Fn) {
238 const fn_decl_index = switch (val.tag()) {238 const fn_decl_index = switch (val.tag()) {
239 .extern_fn => val.castTag(.extern_fn).?.data.owner_decl,239 .extern_fn => val.castTag(.extern_fn).?.data.owner_decl,
...@@ -1720,10 +1720,11 @@ pub const DeclGen = struct {...@@ -1720,10 +1720,11 @@ pub const DeclGen = struct {
1720 }1720 }
17211721
1722 fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void {1722 fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void {
1723 const mod = self.module;
1724 const ip = &mod.intern_pool;
1723 // TODO: remove now-redundant isUnused calls from AIR handler functions1725 // TODO: remove now-redundant isUnused calls from AIR handler functions
1724 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst)) {1726 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip.*))
1725 return;1727 return;
1726 }
17271728
1728 const air_tags = self.air.instructions.items(.tag);1729 const air_tags = self.air.instructions.items(.tag);
1729 const maybe_result_id: ?IdRef = switch (air_tags[inst]) {1730 const maybe_result_id: ?IdRef = switch (air_tags[inst]) {
...@@ -1847,7 +1848,7 @@ pub const DeclGen = struct {...@@ -1847,7 +1848,7 @@ pub const DeclGen = struct {
1847 const lhs_id = try self.resolve(bin_op.lhs);1848 const lhs_id = try self.resolve(bin_op.lhs);
1848 const rhs_id = try self.resolve(bin_op.rhs);1849 const rhs_id = try self.resolve(bin_op.rhs);
1849 const result_id = self.spv.allocId();1850 const result_id = self.spv.allocId();
1850 const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst));1851 const result_type_id = try self.resolveTypeId(self.typeOfIndex(inst));
1851 try self.func.body.emit(self.spv.gpa, opcode, .{1852 try self.func.body.emit(self.spv.gpa, opcode, .{
1852 .id_result_type = result_type_id,1853 .id_result_type = result_type_id,
1853 .id_result = result_id,1854 .id_result = result_id,
...@@ -1862,7 +1863,7 @@ pub const DeclGen = struct {...@@ -1862,7 +1863,7 @@ pub const DeclGen = struct {
1862 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1863 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1863 const lhs_id = try self.resolve(bin_op.lhs);1864 const lhs_id = try self.resolve(bin_op.lhs);
1864 const rhs_id = try self.resolve(bin_op.rhs);1865 const rhs_id = try self.resolve(bin_op.rhs);
1865 const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst));1866 const result_type_id = try self.resolveTypeId(self.typeOfIndex(inst));
18661867
1867 // the shift and the base must be the same type in SPIR-V, but in Zig the shift is a smaller int.1868 // the shift and the base must be the same type in SPIR-V, but in Zig the shift is a smaller int.
1868 const shift_id = self.spv.allocId();1869 const shift_id = self.spv.allocId();
...@@ -1907,15 +1908,15 @@ pub const DeclGen = struct {...@@ -1907,15 +1908,15 @@ pub const DeclGen = struct {
1907 if (self.liveness.isUnused(inst)) return null;1908 if (self.liveness.isUnused(inst)) return null;
1908 // LHS and RHS are guaranteed to have the same type, and AIR guarantees1909 // LHS and RHS are guaranteed to have the same type, and AIR guarantees
1909 // the result to be the same as the LHS and RHS, which matches SPIR-V.1910 // the result to be the same as the LHS and RHS, which matches SPIR-V.
1910 const ty = self.air.typeOfIndex(inst);1911 const ty = self.typeOfIndex(inst);
1911 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1912 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1912 var lhs_id = try self.resolve(bin_op.lhs);1913 var lhs_id = try self.resolve(bin_op.lhs);
1913 var rhs_id = try self.resolve(bin_op.rhs);1914 var rhs_id = try self.resolve(bin_op.rhs);
19141915
1915 const result_ty_ref = try self.resolveType(ty, .direct);1916 const result_ty_ref = try self.resolveType(ty, .direct);
19161917
1917 assert(self.air.typeOf(bin_op.lhs).eql(ty, self.module));1918 assert(self.typeOf(bin_op.lhs).eql(ty, self.module));
1918 assert(self.air.typeOf(bin_op.rhs).eql(ty, self.module));1919 assert(self.typeOf(bin_op.rhs).eql(ty, self.module));
19191920
1920 // Binary operations are generally applicable to both scalar and vector operations1921 // Binary operations are generally applicable to both scalar and vector operations
1921 // in SPIR-V, but int and float versions of operations require different opcodes.1922 // in SPIR-V, but int and float versions of operations require different opcodes.
...@@ -1971,8 +1972,8 @@ pub const DeclGen = struct {...@@ -1971,8 +1972,8 @@ pub const DeclGen = struct {
1971 const lhs = try self.resolve(extra.lhs);1972 const lhs = try self.resolve(extra.lhs);
1972 const rhs = try self.resolve(extra.rhs);1973 const rhs = try self.resolve(extra.rhs);
19731974
1974 const operand_ty = self.air.typeOf(extra.lhs);1975 const operand_ty = self.typeOf(extra.lhs);
1975 const result_ty = self.air.typeOfIndex(inst);1976 const result_ty = self.typeOfIndex(inst);
19761977
1977 const info = try self.arithmeticTypeInfo(operand_ty);1978 const info = try self.arithmeticTypeInfo(operand_ty);
1978 switch (info.class) {1979 switch (info.class) {
...@@ -2064,14 +2065,14 @@ pub const DeclGen = struct {...@@ -2064,14 +2065,14 @@ pub const DeclGen = struct {
2064 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2065 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2065 const mod = self.module;2066 const mod = self.module;
2066 if (self.liveness.isUnused(inst)) return null;2067 if (self.liveness.isUnused(inst)) return null;
2067 const ty = self.air.typeOfIndex(inst);2068 const ty = self.typeOfIndex(inst);
2068 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2069 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2069 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;2070 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
2070 const a = try self.resolve(extra.a);2071 const a = try self.resolve(extra.a);
2071 const b = try self.resolve(extra.b);2072 const b = try self.resolve(extra.b);
2072 const mask = self.air.values[extra.mask];2073 const mask = self.air.values[extra.mask];
2073 const mask_len = extra.mask_len;2074 const mask_len = extra.mask_len;
2074 const a_len = self.air.typeOf(extra.a).vectorLen();2075 const a_len = self.typeOf(extra.a).vectorLen();
20752076
2076 const result_id = self.spv.allocId();2077 const result_id = self.spv.allocId();
2077 const result_type_id = try self.resolveTypeId(ty);2078 const result_type_id = try self.resolveTypeId(ty);
...@@ -2162,8 +2163,8 @@ pub const DeclGen = struct {...@@ -2162,8 +2163,8 @@ pub const DeclGen = struct {
2162 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;2163 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
2163 const ptr_id = try self.resolve(bin_op.lhs);2164 const ptr_id = try self.resolve(bin_op.lhs);
2164 const offset_id = try self.resolve(bin_op.rhs);2165 const offset_id = try self.resolve(bin_op.rhs);
2165 const ptr_ty = self.air.typeOf(bin_op.lhs);2166 const ptr_ty = self.typeOf(bin_op.lhs);
2166 const result_ty = self.air.typeOfIndex(inst);2167 const result_ty = self.typeOfIndex(inst);
21672168
2168 return try self.ptrAdd(result_ty, ptr_ty, ptr_id, offset_id);2169 return try self.ptrAdd(result_ty, ptr_ty, ptr_id, offset_id);
2169 }2170 }
...@@ -2173,11 +2174,11 @@ pub const DeclGen = struct {...@@ -2173,11 +2174,11 @@ pub const DeclGen = struct {
2173 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2174 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2174 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;2175 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
2175 const ptr_id = try self.resolve(bin_op.lhs);2176 const ptr_id = try self.resolve(bin_op.lhs);
2176 const ptr_ty = self.air.typeOf(bin_op.lhs);2177 const ptr_ty = self.typeOf(bin_op.lhs);
2177 const offset_id = try self.resolve(bin_op.rhs);2178 const offset_id = try self.resolve(bin_op.rhs);
2178 const offset_ty = self.air.typeOf(bin_op.rhs);2179 const offset_ty = self.typeOf(bin_op.rhs);
2179 const offset_ty_ref = try self.resolveType(offset_ty, .direct);2180 const offset_ty_ref = try self.resolveType(offset_ty, .direct);
2180 const result_ty = self.air.typeOfIndex(inst);2181 const result_ty = self.typeOfIndex(inst);
21812182
2182 const negative_offset_id = self.spv.allocId();2183 const negative_offset_id = self.spv.allocId();
2183 try self.func.body.emit(self.spv.gpa, .OpSNegate, .{2184 try self.func.body.emit(self.spv.gpa, .OpSNegate, .{
...@@ -2298,8 +2299,8 @@ pub const DeclGen = struct {...@@ -2298,8 +2299,8 @@ pub const DeclGen = struct {
2298 const lhs_id = try self.resolve(bin_op.lhs);2299 const lhs_id = try self.resolve(bin_op.lhs);
2299 const rhs_id = try self.resolve(bin_op.rhs);2300 const rhs_id = try self.resolve(bin_op.rhs);
2300 const bool_ty_id = try self.resolveTypeId(Type.bool);2301 const bool_ty_id = try self.resolveTypeId(Type.bool);
2301 const ty = self.air.typeOf(bin_op.lhs);2302 const ty = self.typeOf(bin_op.lhs);
2302 assert(ty.eql(self.air.typeOf(bin_op.rhs), self.module));2303 assert(ty.eql(self.typeOf(bin_op.rhs), self.module));
23032304
2304 return try self.cmp(op, bool_ty_id, ty, lhs_id, rhs_id);2305 return try self.cmp(op, bool_ty_id, ty, lhs_id, rhs_id);
2305 }2306 }
...@@ -2337,8 +2338,8 @@ pub const DeclGen = struct {...@@ -2337,8 +2338,8 @@ pub const DeclGen = struct {
2337 if (self.liveness.isUnused(inst)) return null;2338 if (self.liveness.isUnused(inst)) return null;
2338 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2339 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2339 const operand_id = try self.resolve(ty_op.operand);2340 const operand_id = try self.resolve(ty_op.operand);
2340 const operand_ty = self.air.typeOf(ty_op.operand);2341 const operand_ty = self.typeOf(ty_op.operand);
2341 const result_ty = self.air.typeOfIndex(inst);2342 const result_ty = self.typeOfIndex(inst);
2342 return try self.bitCast(result_ty, operand_ty, operand_id);2343 return try self.bitCast(result_ty, operand_ty, operand_id);
2343 }2344 }
23442345
...@@ -2347,7 +2348,7 @@ pub const DeclGen = struct {...@@ -2347,7 +2348,7 @@ pub const DeclGen = struct {
23472348
2348 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2349 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2349 const operand_id = try self.resolve(ty_op.operand);2350 const operand_id = try self.resolve(ty_op.operand);
2350 const dest_ty = self.air.typeOfIndex(inst);2351 const dest_ty = self.typeOfIndex(inst);
2351 const dest_ty_id = try self.resolveTypeId(dest_ty);2352 const dest_ty_id = try self.resolveTypeId(dest_ty);
23522353
2353 const mod = self.module;2354 const mod = self.module;
...@@ -2391,10 +2392,10 @@ pub const DeclGen = struct {...@@ -2391,10 +2392,10 @@ pub const DeclGen = struct {
2391 if (self.liveness.isUnused(inst)) return null;2392 if (self.liveness.isUnused(inst)) return null;
23922393
2393 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2394 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2394 const operand_ty = self.air.typeOf(ty_op.operand);2395 const operand_ty = self.typeOf(ty_op.operand);
2395 const operand_id = try self.resolve(ty_op.operand);2396 const operand_id = try self.resolve(ty_op.operand);
2396 const operand_info = try self.arithmeticTypeInfo(operand_ty);2397 const operand_info = try self.arithmeticTypeInfo(operand_ty);
2397 const dest_ty = self.air.typeOfIndex(inst);2398 const dest_ty = self.typeOfIndex(inst);
2398 const dest_ty_id = try self.resolveTypeId(dest_ty);2399 const dest_ty_id = try self.resolveTypeId(dest_ty);
23992400
2400 const result_id = self.spv.allocId();2401 const result_id = self.spv.allocId();
...@@ -2418,7 +2419,7 @@ pub const DeclGen = struct {...@@ -2418,7 +2419,7 @@ pub const DeclGen = struct {
24182419
2419 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2420 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2420 const operand_id = try self.resolve(ty_op.operand);2421 const operand_id = try self.resolve(ty_op.operand);
2421 const dest_ty = self.air.typeOfIndex(inst);2422 const dest_ty = self.typeOfIndex(inst);
2422 const dest_info = try self.arithmeticTypeInfo(dest_ty);2423 const dest_info = try self.arithmeticTypeInfo(dest_ty);
2423 const dest_ty_id = try self.resolveTypeId(dest_ty);2424 const dest_ty_id = try self.resolveTypeId(dest_ty);
24242425
...@@ -2455,20 +2456,20 @@ pub const DeclGen = struct {...@@ -2455,20 +2456,20 @@ pub const DeclGen = struct {
2455 fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef {2456 fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef {
2456 if (self.liveness.isUnused(inst)) return null;2457 if (self.liveness.isUnused(inst)) return null;
2457 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2458 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2458 const field_ty = self.air.typeOfIndex(inst);2459 const field_ty = self.typeOfIndex(inst);
2459 const operand_id = try self.resolve(ty_op.operand);2460 const operand_id = try self.resolve(ty_op.operand);
2460 return try self.extractField(field_ty, operand_id, field);2461 return try self.extractField(field_ty, operand_id, field);
2461 }2462 }
24622463
2463 fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2464 fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2464 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2465 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2465 const slice_ty = self.air.typeOf(bin_op.lhs);2466 const slice_ty = self.typeOf(bin_op.lhs);
2466 if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;2467 if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
24672468
2468 const slice_id = try self.resolve(bin_op.lhs);2469 const slice_id = try self.resolve(bin_op.lhs);
2469 const index_id = try self.resolve(bin_op.rhs);2470 const index_id = try self.resolve(bin_op.rhs);
24702471
2471 const ptr_ty = self.air.typeOfIndex(inst);2472 const ptr_ty = self.typeOfIndex(inst);
2472 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);2473 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
24732474
2474 const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);2475 const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);
...@@ -2477,7 +2478,7 @@ pub const DeclGen = struct {...@@ -2477,7 +2478,7 @@ pub const DeclGen = struct {
24772478
2478 fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2479 fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2479 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2480 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2480 const slice_ty = self.air.typeOf(bin_op.lhs);2481 const slice_ty = self.typeOf(bin_op.lhs);
2481 if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;2482 if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
24822483
2483 const slice_id = try self.resolve(bin_op.lhs);2484 const slice_id = try self.resolve(bin_op.lhs);
...@@ -2514,7 +2515,7 @@ pub const DeclGen = struct {...@@ -2514,7 +2515,7 @@ pub const DeclGen = struct {
2514 const mod = self.module;2515 const mod = self.module;
2515 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2516 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2516 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;2517 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
2517 const ptr_ty = self.air.typeOf(bin_op.lhs);2518 const ptr_ty = self.typeOf(bin_op.lhs);
2518 const elem_ty = ptr_ty.childType();2519 const elem_ty = ptr_ty.childType();
2519 // TODO: Make this return a null ptr or something2520 // TODO: Make this return a null ptr or something
2520 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;2521 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
...@@ -2526,7 +2527,7 @@ pub const DeclGen = struct {...@@ -2526,7 +2527,7 @@ pub const DeclGen = struct {
25262527
2527 fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2528 fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2528 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2529 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2529 const ptr_ty = self.air.typeOf(bin_op.lhs);2530 const ptr_ty = self.typeOf(bin_op.lhs);
2530 const ptr_id = try self.resolve(bin_op.lhs);2531 const ptr_id = try self.resolve(bin_op.lhs);
2531 const index_id = try self.resolve(bin_op.rhs);2532 const index_id = try self.resolve(bin_op.rhs);
25322533
...@@ -2544,7 +2545,7 @@ pub const DeclGen = struct {...@@ -2544,7 +2545,7 @@ pub const DeclGen = struct {
25442545
2545 fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2546 fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2546 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2547 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2547 const un_ty = self.air.typeOf(ty_op.operand);2548 const un_ty = self.typeOf(ty_op.operand);
25482549
2549 const mod = self.module;2550 const mod = self.module;
2550 const layout = un_ty.unionGetLayout(mod);2551 const layout = un_ty.unionGetLayout(mod);
...@@ -2565,7 +2566,7 @@ pub const DeclGen = struct {...@@ -2565,7 +2566,7 @@ pub const DeclGen = struct {
2565 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2566 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2566 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;2567 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
25672568
2568 const struct_ty = self.air.typeOf(struct_field.struct_operand);2569 const struct_ty = self.typeOf(struct_field.struct_operand);
2569 const object_id = try self.resolve(struct_field.struct_operand);2570 const object_id = try self.resolve(struct_field.struct_operand);
2570 const field_index = struct_field.field_index;2571 const field_index = struct_field.field_index;
2571 const field_ty = struct_ty.structFieldType(field_index);2572 const field_ty = struct_ty.structFieldType(field_index);
...@@ -2604,8 +2605,8 @@ pub const DeclGen = struct {...@@ -2604,8 +2605,8 @@ pub const DeclGen = struct {
2604 if (self.liveness.isUnused(inst)) return null;2605 if (self.liveness.isUnused(inst)) return null;
2605 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2606 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2606 const struct_ptr = try self.resolve(ty_op.operand);2607 const struct_ptr = try self.resolve(ty_op.operand);
2607 const struct_ptr_ty = self.air.typeOf(ty_op.operand);2608 const struct_ptr_ty = self.typeOf(ty_op.operand);
2608 const result_ptr_ty = self.air.typeOfIndex(inst);2609 const result_ptr_ty = self.typeOfIndex(inst);
2609 return try self.structFieldPtr(result_ptr_ty, struct_ptr_ty, struct_ptr, field_index);2610 return try self.structFieldPtr(result_ptr_ty, struct_ptr_ty, struct_ptr, field_index);
2610 }2611 }
26112612
...@@ -2661,7 +2662,7 @@ pub const DeclGen = struct {...@@ -2661,7 +2662,7 @@ pub const DeclGen = struct {
26612662
2662 fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2663 fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2663 if (self.liveness.isUnused(inst)) return null;2664 if (self.liveness.isUnused(inst)) return null;
2664 const ptr_ty = self.air.typeOfIndex(inst);2665 const ptr_ty = self.typeOfIndex(inst);
2665 assert(ptr_ty.ptrAddressSpace() == .generic);2666 assert(ptr_ty.ptrAddressSpace() == .generic);
2666 const child_ty = ptr_ty.childType();2667 const child_ty = ptr_ty.childType();
2667 const child_ty_ref = try self.resolveType(child_ty, .indirect);2668 const child_ty_ref = try self.resolveType(child_ty, .indirect);
...@@ -2694,7 +2695,7 @@ pub const DeclGen = struct {...@@ -2694,7 +2695,7 @@ pub const DeclGen = struct {
2694 incoming_blocks.deinit(self.gpa);2695 incoming_blocks.deinit(self.gpa);
2695 }2696 }
26962697
2697 const ty = self.air.typeOfIndex(inst);2698 const ty = self.typeOfIndex(inst);
2698 const inst_datas = self.air.instructions.items(.data);2699 const inst_datas = self.air.instructions.items(.data);
2699 const extra = self.air.extraData(Air.Block, inst_datas[inst].ty_pl.payload);2700 const extra = self.air.extraData(Air.Block, inst_datas[inst].ty_pl.payload);
2700 const body = self.air.extra[extra.end..][0..extra.data.body_len];2701 const body = self.air.extra[extra.end..][0..extra.data.body_len];
...@@ -2727,7 +2728,7 @@ pub const DeclGen = struct {...@@ -2727,7 +2728,7 @@ pub const DeclGen = struct {
2727 fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void {2728 fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void {
2728 const br = self.air.instructions.items(.data)[inst].br;2729 const br = self.air.instructions.items(.data)[inst].br;
2729 const block = self.blocks.get(br.block_inst).?;2730 const block = self.blocks.get(br.block_inst).?;
2730 const operand_ty = self.air.typeOf(br.operand);2731 const operand_ty = self.typeOf(br.operand);
27312732
2732 const mod = self.module;2733 const mod = self.module;
2733 if (operand_ty.hasRuntimeBits(mod)) {2734 if (operand_ty.hasRuntimeBits(mod)) {
...@@ -2777,7 +2778,7 @@ pub const DeclGen = struct {...@@ -2777,7 +2778,7 @@ pub const DeclGen = struct {
27772778
2778 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2779 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2779 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2780 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2780 const ptr_ty = self.air.typeOf(ty_op.operand);2781 const ptr_ty = self.typeOf(ty_op.operand);
2781 const operand = try self.resolve(ty_op.operand);2782 const operand = try self.resolve(ty_op.operand);
2782 if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;2783 if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
27832784
...@@ -2787,7 +2788,7 @@ pub const DeclGen = struct {...@@ -2787,7 +2788,7 @@ pub const DeclGen = struct {
2787 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {2788 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
2788 const mod = self.module;2789 const mod = self.module;
2789 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2790 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2790 const ptr_ty = self.air.typeOf(bin_op.lhs);2791 const ptr_ty = self.typeOf(bin_op.lhs);
2791 const ptr = try self.resolve(bin_op.lhs);2792 const ptr = try self.resolve(bin_op.lhs);
2792 const value = try self.resolve(bin_op.rhs);2793 const value = try self.resolve(bin_op.rhs);
2793 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);2794 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
...@@ -2819,7 +2820,7 @@ pub const DeclGen = struct {...@@ -2819,7 +2820,7 @@ pub const DeclGen = struct {
28192820
2820 fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {2821 fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {
2821 const operand = self.air.instructions.items(.data)[inst].un_op;2822 const operand = self.air.instructions.items(.data)[inst].un_op;
2822 const operand_ty = self.air.typeOf(operand);2823 const operand_ty = self.typeOf(operand);
2823 const mod = self.module;2824 const mod = self.module;
2824 if (operand_ty.hasRuntimeBits(mod)) {2825 if (operand_ty.hasRuntimeBits(mod)) {
2825 const operand_id = try self.resolve(operand);2826 const operand_id = try self.resolve(operand);
...@@ -2832,7 +2833,7 @@ pub const DeclGen = struct {...@@ -2832,7 +2833,7 @@ pub const DeclGen = struct {
2832 fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {2833 fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {
2833 const mod = self.module;2834 const mod = self.module;
2834 const un_op = self.air.instructions.items(.data)[inst].un_op;2835 const un_op = self.air.instructions.items(.data)[inst].un_op;
2835 const ptr_ty = self.air.typeOf(un_op);2836 const ptr_ty = self.typeOf(un_op);
2836 const ret_ty = ptr_ty.childType();2837 const ret_ty = ptr_ty.childType();
28372838
2838 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {2839 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -2853,8 +2854,8 @@ pub const DeclGen = struct {...@@ -2853,8 +2854,8 @@ pub const DeclGen = struct {
2853 const extra = self.air.extraData(Air.Try, pl_op.payload);2854 const extra = self.air.extraData(Air.Try, pl_op.payload);
2854 const body = self.air.extra[extra.end..][0..extra.data.body_len];2855 const body = self.air.extra[extra.end..][0..extra.data.body_len];
28552856
2856 const err_union_ty = self.air.typeOf(pl_op.operand);2857 const err_union_ty = self.typeOf(pl_op.operand);
2857 const payload_ty = self.air.typeOfIndex(inst);2858 const payload_ty = self.typeOfIndex(inst);
28582859
2859 const err_ty_ref = try self.resolveType(Type.anyerror, .direct);2860 const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
2860 const bool_ty_ref = try self.resolveType(Type.bool, .direct);2861 const bool_ty_ref = try self.resolveType(Type.bool, .direct);
...@@ -2911,7 +2912,7 @@ pub const DeclGen = struct {...@@ -2911,7 +2912,7 @@ pub const DeclGen = struct {
29112912
2912 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2913 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2913 const operand_id = try self.resolve(ty_op.operand);2914 const operand_id = try self.resolve(ty_op.operand);
2914 const err_union_ty = self.air.typeOf(ty_op.operand);2915 const err_union_ty = self.typeOf(ty_op.operand);
2915 const err_ty_ref = try self.resolveType(Type.anyerror, .direct);2916 const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
29162917
2917 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {2918 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
...@@ -2934,7 +2935,7 @@ pub const DeclGen = struct {...@@ -2934,7 +2935,7 @@ pub const DeclGen = struct {
2934 if (self.liveness.isUnused(inst)) return null;2935 if (self.liveness.isUnused(inst)) return null;
29352936
2936 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2937 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2937 const err_union_ty = self.air.typeOfIndex(inst);2938 const err_union_ty = self.typeOfIndex(inst);
2938 const payload_ty = err_union_ty.errorUnionPayload();2939 const payload_ty = err_union_ty.errorUnionPayload();
2939 const operand_id = try self.resolve(ty_op.operand);2940 const operand_id = try self.resolve(ty_op.operand);
2940 const eu_layout = self.errorUnionLayout(payload_ty);2941 const eu_layout = self.errorUnionLayout(payload_ty);
...@@ -2966,7 +2967,7 @@ pub const DeclGen = struct {...@@ -2966,7 +2967,7 @@ pub const DeclGen = struct {
2966 const mod = self.module;2967 const mod = self.module;
2967 const un_op = self.air.instructions.items(.data)[inst].un_op;2968 const un_op = self.air.instructions.items(.data)[inst].un_op;
2968 const operand_id = try self.resolve(un_op);2969 const operand_id = try self.resolve(un_op);
2969 const optional_ty = self.air.typeOf(un_op);2970 const optional_ty = self.typeOf(un_op);
29702971
2971 var buf: Type.Payload.ElemType = undefined;2972 var buf: Type.Payload.ElemType = undefined;
2972 const payload_ty = optional_ty.optionalChild(&buf);2973 const payload_ty = optional_ty.optionalChild(&buf);
...@@ -3030,8 +3031,8 @@ pub const DeclGen = struct {...@@ -3030,8 +3031,8 @@ pub const DeclGen = struct {
3030 const mod = self.module;3031 const mod = self.module;
3031 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3032 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3032 const operand_id = try self.resolve(ty_op.operand);3033 const operand_id = try self.resolve(ty_op.operand);
3033 const optional_ty = self.air.typeOf(ty_op.operand);3034 const optional_ty = self.typeOf(ty_op.operand);
3034 const payload_ty = self.air.typeOfIndex(inst);3035 const payload_ty = self.typeOfIndex(inst);
30353036
3036 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;3037 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
30373038
...@@ -3047,14 +3048,14 @@ pub const DeclGen = struct {...@@ -3047,14 +3048,14 @@ pub const DeclGen = struct {
30473048
3048 const mod = self.module;3049 const mod = self.module;
3049 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3050 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3050 const payload_ty = self.air.typeOf(ty_op.operand);3051 const payload_ty = self.typeOf(ty_op.operand);
30513052
3052 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3053 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3053 return try self.constBool(true, .direct);3054 return try self.constBool(true, .direct);
3054 }3055 }
30553056
3056 const operand_id = try self.resolve(ty_op.operand);3057 const operand_id = try self.resolve(ty_op.operand);
3057 const optional_ty = self.air.typeOfIndex(inst);3058 const optional_ty = self.typeOfIndex(inst);
3058 if (optional_ty.optionalReprIsPayload(mod)) {3059 if (optional_ty.optionalReprIsPayload(mod)) {
3059 return operand_id;3060 return operand_id;
3060 }3061 }
...@@ -3068,7 +3069,7 @@ pub const DeclGen = struct {...@@ -3068,7 +3069,7 @@ pub const DeclGen = struct {
3068 const mod = self.module;3069 const mod = self.module;
3069 const pl_op = self.air.instructions.items(.data)[inst].pl_op;3070 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
3070 const cond = try self.resolve(pl_op.operand);3071 const cond = try self.resolve(pl_op.operand);
3071 const cond_ty = self.air.typeOf(pl_op.operand);3072 const cond_ty = self.typeOf(pl_op.operand);
3072 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);3073 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
30733074
3074 const cond_words: u32 = switch (cond_ty.zigTypeTag(mod)) {3075 const cond_words: u32 = switch (cond_ty.zigTypeTag(mod)) {
...@@ -3317,7 +3318,7 @@ pub const DeclGen = struct {...@@ -3317,7 +3318,7 @@ pub const DeclGen = struct {
3317 const pl_op = self.air.instructions.items(.data)[inst].pl_op;3318 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
3318 const extra = self.air.extraData(Air.Call, pl_op.payload);3319 const extra = self.air.extraData(Air.Call, pl_op.payload);
3319 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);3320 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
3320 const callee_ty = self.air.typeOf(pl_op.operand);3321 const callee_ty = self.typeOf(pl_op.operand);
3321 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {3322 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
3322 .Fn => callee_ty,3323 .Fn => callee_ty,
3323 .Pointer => return self.fail("cannot call function pointers", .{}),3324 .Pointer => return self.fail("cannot call function pointers", .{}),
...@@ -3339,7 +3340,7 @@ pub const DeclGen = struct {...@@ -3339,7 +3340,7 @@ pub const DeclGen = struct {
3339 // before starting to emit OpFunctionCall instructions. Hence the3340 // before starting to emit OpFunctionCall instructions. Hence the
3340 // temporary params buffer.3341 // temporary params buffer.
3341 const arg_id = try self.resolve(arg);3342 const arg_id = try self.resolve(arg);
3342 const arg_ty = self.air.typeOf(arg);3343 const arg_ty = self.typeOf(arg);
3343 if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;3344 if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
33443345
3345 params[n_params] = arg_id;3346 params[n_params] = arg_id;
...@@ -3363,4 +3364,14 @@ pub const DeclGen = struct {...@@ -3363,4 +3364,14 @@ pub const DeclGen = struct {
33633364
3364 return result_id;3365 return result_id;
3365 }3366 }
3367
3368 fn typeOf(self: *DeclGen, inst: Air.Inst.Ref) Type {
3369 const mod = self.module;
3370 return self.air.typeOf(inst, mod.intern_pool);
3371 }
3372
3373 fn typeOfIndex(self: *DeclGen, inst: Air.Inst.Index) Type {
3374 const mod = self.module;
3375 return self.air.typeOfIndex(inst, mod.intern_pool);
3376 }
3366};3377};
src/print_air.zig+16-2
...@@ -306,6 +306,7 @@ const Writer = struct {...@@ -306,6 +306,7 @@ const Writer = struct {
306 .struct_field_ptr => try w.writeStructField(s, inst),306 .struct_field_ptr => try w.writeStructField(s, inst),
307 .struct_field_val => try w.writeStructField(s, inst),307 .struct_field_val => try w.writeStructField(s, inst),
308 .constant => try w.writeConstant(s, inst),308 .constant => try w.writeConstant(s, inst),
309 .interned => try w.writeInterned(s, inst),
309 .assembly => try w.writeAssembly(s, inst),310 .assembly => try w.writeAssembly(s, inst),
310 .dbg_stmt => try w.writeDbgStmt(s, inst),311 .dbg_stmt => try w.writeDbgStmt(s, inst),
311312
...@@ -515,7 +516,7 @@ const Writer = struct {...@@ -515,7 +516,7 @@ const Writer = struct {
515 const pl_op = w.air.instructions.items(.data)[inst].pl_op;516 const pl_op = w.air.instructions.items(.data)[inst].pl_op;
516 const extra = w.air.extraData(Air.Bin, pl_op.payload).data;517 const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
517518
518 const elem_ty = w.air.typeOfIndex(inst).childType();519 const elem_ty = w.typeOfIndex(inst).childType();
519 try w.writeType(s, elem_ty);520 try w.writeType(s, elem_ty);
520 try s.writeAll(", ");521 try s.writeAll(", ");
521 try w.writeOperand(s, inst, 0, pl_op.operand);522 try w.writeOperand(s, inst, 0, pl_op.operand);
...@@ -614,6 +615,14 @@ const Writer = struct {...@@ -614,6 +615,14 @@ const Writer = struct {
614 try s.print(", {}", .{val.fmtValue(ty, w.module)});615 try s.print(", {}", .{val.fmtValue(ty, w.module)});
615 }616 }
616617
618 fn writeInterned(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
619 const mod = w.module;
620 const ip_index = w.air.instructions.items(.data)[inst].interned;
621 const ty = ip_index.toType();
622 try w.writeType(s, ty);
623 try s.print(", {}", .{ip_index.toValue().fmtValue(ty, mod)});
624 }
625
617 fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {626 fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
618 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;627 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
619 const extra = w.air.extraData(Air.Asm, ty_pl.payload);628 const extra = w.air.extraData(Air.Asm, ty_pl.payload);
...@@ -622,7 +631,7 @@ const Writer = struct {...@@ -622,7 +631,7 @@ const Writer = struct {
622 var extra_i: usize = extra.end;631 var extra_i: usize = extra.end;
623 var op_index: usize = 0;632 var op_index: usize = 0;
624633
625 const ret_ty = w.air.typeOfIndex(inst);634 const ret_ty = w.typeOfIndex(inst);
626 try w.writeType(s, ret_ty);635 try w.writeType(s, ret_ty);
627636
628 if (is_volatile) {637 if (is_volatile) {
...@@ -985,4 +994,9 @@ const Writer = struct {...@@ -985,4 +994,9 @@ const Writer = struct {
985 try s.print("%{d}", .{inst});994 try s.print("%{d}", .{inst});
986 if (dies) try s.writeByte('!');995 if (dies) try s.writeByte('!');
987 }996 }
997
998 fn typeOfIndex(w: *Writer, inst: Air.Inst.Index) Type {
999 const mod = w.module;
1000 return w.air.typeOfIndex(inst, mod.intern_pool);
1001 }
988};1002};
src/type.zig+27-13
...@@ -2827,21 +2827,35 @@ pub const Type = struct {...@@ -2827,21 +2827,35 @@ pub const Type = struct {
2827 };2827 };
2828 }2828 }
28292829
2830 /// TODO add enums with no fields here
2831 pub fn isNoReturn(ty: Type) bool {2830 pub fn isNoReturn(ty: Type) bool {
2832 switch (ty.tag()) {2831 switch (@enumToInt(ty.ip_index)) {
2833 .noreturn => return true,2832 @enumToInt(InternPool.Index.first_type)...@enumToInt(InternPool.Index.noreturn_type) - 1 => return false,
2834 .error_set => {2833
2835 const err_set_obj = ty.castTag(.error_set).?.data;2834 @enumToInt(InternPool.Index.noreturn_type) => return true,
2836 const names = err_set_obj.names.keys();2835
2837 return names.len == 0;2836 @enumToInt(InternPool.Index.noreturn_type) + 1...@enumToInt(InternPool.Index.last_type) => return false,
2838 },2837
2839 .error_set_merged => {2838 @enumToInt(InternPool.Index.first_value)...@enumToInt(InternPool.Index.last_value) => unreachable,
2840 const name_map = ty.castTag(.error_set_merged).?.data;2839 @enumToInt(InternPool.Index.generic_poison) => unreachable,
2841 const names = name_map.keys();2840
2842 return names.len == 0;2841 // TODO add empty error sets here
2843 },2842 // TODO add enums with no fields here
2844 else => return false,2843 else => return false,
2844
2845 @enumToInt(InternPool.Index.none) => switch (ty.tag()) {
2846 .noreturn => return true,
2847 .error_set => {
2848 const err_set_obj = ty.castTag(.error_set).?.data;
2849 const names = err_set_obj.names.keys();
2850 return names.len == 0;
2851 },
2852 .error_set_merged => {
2853 const name_map = ty.castTag(.error_set_merged).?.data;
2854 const names = name_map.keys();
2855 return names.len == 0;
2856 },
2857 else => return false,
2858 },
2845 }2859 }
2846 }2860 }
28472861