authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-02 15:01:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:40:03-07:00
log9aec2758cc29d27c31dcb0b4bb040484a885ef23
treec171c40656f3b8f70375b4afca94a87784bb2dda
parent1e7dcaa3ae57294ab5998b44a8c13ccc5019e7ea

stage2: start the InternPool transition

Instead of doing everything at once which is a hopelessly large task, this introduces a piecemeal transition that can be done in small increments at a time. This is a minimal changeset that keeps the compiler compiling. It only uses the InternPool for a small set of types. Behavior tests are not passing. Air.Inst.Ref and Zir.Inst.Ref are separated into different enums but compile-time verified to have the same fields in the same order. The large set of changes is mainly to deal with the fact that most Type and Value methods now require a Module to be passed in, so that the InternPool object can be accessed.

38 files changed, 6473 insertions(+), 5784 deletions(-)

src/Air.zig+104-21
......@@ -5,10 +5,12 @@
55
66const std = @import("std");
77const builtin = @import("builtin");
8const Value = @import("value.zig").Value;
9const Type = @import("type.zig").Type;
108const assert = std.debug.assert;
9
1110const Air = @This();
11const Value = @import("value.zig").Value;
12const Type = @import("type.zig").Type;
13const InternPool = @import("InternPool.zig");
1214
1315instructions: std.MultiArrayList(Inst).Slice,
1416/// The meaning of this data is determined by `Inst.Tag` value.
......@@ -837,7 +839,88 @@ pub const Inst = struct {
837839 /// The position of an AIR instruction within the `Air` instructions array.
838840 pub const Index = u32;
839841
840 pub const Ref = @import("Zir.zig").Inst.Ref;
842 pub const Ref = enum(u32) {
843 u1_type = @enumToInt(InternPool.Index.u1_type),
844 u8_type = @enumToInt(InternPool.Index.u8_type),
845 i8_type = @enumToInt(InternPool.Index.i8_type),
846 u16_type = @enumToInt(InternPool.Index.u16_type),
847 i16_type = @enumToInt(InternPool.Index.i16_type),
848 u29_type = @enumToInt(InternPool.Index.u29_type),
849 u32_type = @enumToInt(InternPool.Index.u32_type),
850 i32_type = @enumToInt(InternPool.Index.i32_type),
851 u64_type = @enumToInt(InternPool.Index.u64_type),
852 i64_type = @enumToInt(InternPool.Index.i64_type),
853 u80_type = @enumToInt(InternPool.Index.u80_type),
854 u128_type = @enumToInt(InternPool.Index.u128_type),
855 i128_type = @enumToInt(InternPool.Index.i128_type),
856 usize_type = @enumToInt(InternPool.Index.usize_type),
857 isize_type = @enumToInt(InternPool.Index.isize_type),
858 c_char_type = @enumToInt(InternPool.Index.c_char_type),
859 c_short_type = @enumToInt(InternPool.Index.c_short_type),
860 c_ushort_type = @enumToInt(InternPool.Index.c_ushort_type),
861 c_int_type = @enumToInt(InternPool.Index.c_int_type),
862 c_uint_type = @enumToInt(InternPool.Index.c_uint_type),
863 c_long_type = @enumToInt(InternPool.Index.c_long_type),
864 c_ulong_type = @enumToInt(InternPool.Index.c_ulong_type),
865 c_longlong_type = @enumToInt(InternPool.Index.c_longlong_type),
866 c_ulonglong_type = @enumToInt(InternPool.Index.c_ulonglong_type),
867 c_longdouble_type = @enumToInt(InternPool.Index.c_longdouble_type),
868 f16_type = @enumToInt(InternPool.Index.f16_type),
869 f32_type = @enumToInt(InternPool.Index.f32_type),
870 f64_type = @enumToInt(InternPool.Index.f64_type),
871 f80_type = @enumToInt(InternPool.Index.f80_type),
872 f128_type = @enumToInt(InternPool.Index.f128_type),
873 anyopaque_type = @enumToInt(InternPool.Index.anyopaque_type),
874 bool_type = @enumToInt(InternPool.Index.bool_type),
875 void_type = @enumToInt(InternPool.Index.void_type),
876 type_type = @enumToInt(InternPool.Index.type_type),
877 anyerror_type = @enumToInt(InternPool.Index.anyerror_type),
878 comptime_int_type = @enumToInt(InternPool.Index.comptime_int_type),
879 comptime_float_type = @enumToInt(InternPool.Index.comptime_float_type),
880 noreturn_type = @enumToInt(InternPool.Index.noreturn_type),
881 anyframe_type = @enumToInt(InternPool.Index.anyframe_type),
882 null_type = @enumToInt(InternPool.Index.null_type),
883 undefined_type = @enumToInt(InternPool.Index.undefined_type),
884 enum_literal_type = @enumToInt(InternPool.Index.enum_literal_type),
885 atomic_order_type = @enumToInt(InternPool.Index.atomic_order_type),
886 atomic_rmw_op_type = @enumToInt(InternPool.Index.atomic_rmw_op_type),
887 calling_convention_type = @enumToInt(InternPool.Index.calling_convention_type),
888 address_space_type = @enumToInt(InternPool.Index.address_space_type),
889 float_mode_type = @enumToInt(InternPool.Index.float_mode_type),
890 reduce_op_type = @enumToInt(InternPool.Index.reduce_op_type),
891 call_modifier_type = @enumToInt(InternPool.Index.call_modifier_type),
892 prefetch_options_type = @enumToInt(InternPool.Index.prefetch_options_type),
893 export_options_type = @enumToInt(InternPool.Index.export_options_type),
894 extern_options_type = @enumToInt(InternPool.Index.extern_options_type),
895 type_info_type = @enumToInt(InternPool.Index.type_info_type),
896 manyptr_u8_type = @enumToInt(InternPool.Index.manyptr_u8_type),
897 manyptr_const_u8_type = @enumToInt(InternPool.Index.manyptr_const_u8_type),
898 single_const_pointer_to_comptime_int_type = @enumToInt(InternPool.Index.single_const_pointer_to_comptime_int_type),
899 const_slice_u8_type = @enumToInt(InternPool.Index.const_slice_u8_type),
900 anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),
901 generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),
902 var_args_param_type = @enumToInt(InternPool.Index.var_args_param_type),
903 empty_struct_type = @enumToInt(InternPool.Index.empty_struct_type),
904 undef = @enumToInt(InternPool.Index.undef),
905 zero = @enumToInt(InternPool.Index.zero),
906 zero_usize = @enumToInt(InternPool.Index.zero_usize),
907 one = @enumToInt(InternPool.Index.one),
908 one_usize = @enumToInt(InternPool.Index.one_usize),
909 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
910 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),
911 void_value = @enumToInt(InternPool.Index.void_value),
912 unreachable_value = @enumToInt(InternPool.Index.unreachable_value),
913 null_value = @enumToInt(InternPool.Index.null_value),
914 bool_true = @enumToInt(InternPool.Index.bool_true),
915 bool_false = @enumToInt(InternPool.Index.bool_false),
916 empty_struct = @enumToInt(InternPool.Index.empty_struct),
917 generic_poison = @enumToInt(InternPool.Index.generic_poison),
918
919 /// This Ref does not correspond to any AIR instruction or constant
920 /// value and may instead be used as a sentinel to indicate null.
921 none = std.math.maxInt(u32),
922 _,
923 };
841924
842925 /// All instructions have an 8-byte payload, which is contained within
843926 /// this union. `Tag` determines which union field is active, as well as
......@@ -1066,10 +1149,13 @@ pub fn getMainBody(air: Air) []const Air.Inst.Index {
10661149
10671150pub fn typeOf(air: Air, inst: Air.Inst.Ref) Type {
10681151 const ref_int = @enumToInt(inst);
1069 if (ref_int < Air.Inst.Ref.typed_value_map.len) {
1070 return Air.Inst.Ref.typed_value_map[ref_int].ty;
1152 if (ref_int < InternPool.static_keys.len) {
1153 return .{
1154 .ip_index = InternPool.static_keys[ref_int].typeOf(),
1155 .legacy = undefined,
1156 };
10711157 }
1072 return air.typeOfIndex(@intCast(Air.Inst.Index, ref_int - Air.Inst.Ref.typed_value_map.len));
1158 return air.typeOfIndex(ref_int - ref_start_index);
10731159}
10741160
10751161pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
......@@ -1286,11 +1372,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
12861372
12871373 .call, .call_always_tail, .call_never_tail, .call_never_inline => {
12881374 const callee_ty = air.typeOf(datas[inst].pl_op.operand);
1289 switch (callee_ty.zigTypeTag()) {
1290 .Fn => return callee_ty.fnReturnType(),
1291 .Pointer => return callee_ty.childType().fnReturnType(),
1292 else => unreachable,
1293 }
1375 return callee_ty.fnReturnType();
12941376 },
12951377
12961378 .slice_elem_val, .ptr_elem_val, .array_elem_val => {
......@@ -1328,11 +1410,11 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
13281410
13291411pub fn getRefType(air: Air, ref: Air.Inst.Ref) Type {
13301412 const ref_int = @enumToInt(ref);
1331 if (ref_int < Air.Inst.Ref.typed_value_map.len) {
1332 var buffer: Value.ToTypeBuffer = undefined;
1333 return Air.Inst.Ref.typed_value_map[ref_int].val.toType(&buffer);
1413 if (ref_int < ref_start_index) {
1414 const ip_index = @intToEnum(InternPool.Index, ref_int);
1415 return ip_index.toType();
13341416 }
1335 const inst_index = ref_int - Air.Inst.Ref.typed_value_map.len;
1417 const inst_index = ref_int - ref_start_index;
13361418 const air_tags = air.instructions.items(.tag);
13371419 const air_datas = air.instructions.items(.data);
13381420 assert(air_tags[inst_index] == .const_ty);
......@@ -1367,7 +1449,7 @@ pub fn deinit(air: *Air, gpa: std.mem.Allocator) void {
13671449 air.* = undefined;
13681450}
13691451
1370const ref_start_index: u32 = Air.Inst.Ref.typed_value_map.len;
1452pub const ref_start_index: u32 = InternPool.static_len;
13711453
13721454pub fn indexToRef(inst: Air.Inst.Index) Air.Inst.Ref {
13731455 return @intToEnum(Air.Inst.Ref, ref_start_index + inst);
......@@ -1383,17 +1465,18 @@ pub fn refToIndex(inst: Air.Inst.Ref) ?Air.Inst.Index {
13831465}
13841466
13851467/// Returns `null` if runtime-known.
1386pub fn value(air: Air, inst: Air.Inst.Ref) ?Value {
1468pub fn value(air: Air, inst: Air.Inst.Ref, mod: *const @import("Module.zig")) ?Value {
13871469 const ref_int = @enumToInt(inst);
1388 if (ref_int < Air.Inst.Ref.typed_value_map.len) {
1389 return Air.Inst.Ref.typed_value_map[ref_int].val;
1470 if (ref_int < ref_start_index) {
1471 const ip_index = @intToEnum(InternPool.Index, ref_int);
1472 return ip_index.toValue();
13901473 }
1391 const inst_index = @intCast(Air.Inst.Index, ref_int - Air.Inst.Ref.typed_value_map.len);
1474 const inst_index = @intCast(Air.Inst.Index, ref_int - ref_start_index);
13921475 const air_datas = air.instructions.items(.data);
13931476 switch (air.instructions.items(.tag)[inst_index]) {
13941477 .constant => return air.values[air_datas[inst_index].ty_pl.payload],
13951478 .const_ty => unreachable,
1396 else => return air.typeOfIndex(inst_index).onePossibleValue(),
1479 else => return air.typeOfIndex(inst_index).onePossibleValue(mod),
13971480 }
13981481}
13991482
src/AstGen.zig+1-5
......@@ -8530,7 +8530,7 @@ fn builtinCall(
85308530 return rvalue(gz, ri, result, node);
85318531 },
85328532 .call => {
8533 const modifier = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .modifier_type } }, params[0]);
8533 const modifier = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .call_modifier_type } }, params[0]);
85348534 const callee = try expr(gz, scope, .{ .rl = .none }, params[1]);
85358535 const args = try expr(gz, scope, .{ .rl = .none }, params[2]);
85368536 const result = try gz.addPlNode(.builtin_call, node, Zir.Inst.BuiltinCall{
......@@ -10298,10 +10298,6 @@ fn rvalue(
1029810298 as_ty | @enumToInt(Zir.Inst.Ref.noreturn_type),
1029910299 as_ty | @enumToInt(Zir.Inst.Ref.null_type),
1030010300 as_ty | @enumToInt(Zir.Inst.Ref.undefined_type),
10301 as_ty | @enumToInt(Zir.Inst.Ref.fn_noreturn_no_args_type),
10302 as_ty | @enumToInt(Zir.Inst.Ref.fn_void_no_args_type),
10303 as_ty | @enumToInt(Zir.Inst.Ref.fn_naked_noreturn_no_args_type),
10304 as_ty | @enumToInt(Zir.Inst.Ref.fn_ccc_void_no_args_type),
1030510301 as_ty | @enumToInt(Zir.Inst.Ref.single_const_pointer_to_comptime_int_type),
1030610302 as_ty | @enumToInt(Zir.Inst.Ref.const_slice_u8_type),
1030710303 as_ty | @enumToInt(Zir.Inst.Ref.enum_literal_type),
src/Autodoc.zig-2
......@@ -95,8 +95,6 @@ pub fn generateZirData(self: *Autodoc) !void {
9595 }
9696 }
9797
98 log.debug("Ref map size: {}", .{Ref.typed_value_map.len});
99
10098 const root_src_dir = self.comp_module.main_pkg.root_src_directory;
10199 const root_src_path = self.comp_module.main_pkg.root_src_path;
102100 const joined_src_path = try root_src_dir.join(self.arena, &.{root_src_path});
src/Compilation.zig+2-1
......@@ -1317,7 +1317,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
13171317 .emit_h = emit_h,
13181318 .error_name_list = .{},
13191319 };
1320 try module.error_name_list.append(gpa, "(no error)");
1320 try module.init();
13211321
13221322 break :blk module;
13231323 } else blk: {
......@@ -2064,6 +2064,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
20642064 if (!build_options.only_c and !build_options.only_core_functionality) {
20652065 if (comp.emit_docs) |doc_location| {
20662066 if (comp.bin_file.options.module) |module| {
2067 if (true) @panic("TODO: get autodoc working again in this branch");
20672068 var autodoc = Autodoc.init(module, doc_location);
20682069 defer autodoc.deinit();
20692070 try autodoc.generateZirData();
src/InternPool.zig+488-30
......@@ -1,11 +1,16 @@
1//! All interned objects have both a value and a type.
2
13map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
24items: std.MultiArrayList(Item) = .{},
35extra: std.ArrayListUnmanaged(u32) = .{},
46
5const InternPool = @This();
67const std = @import("std");
78const Allocator = std.mem.Allocator;
89const assert = std.debug.assert;
10const BigIntConst = std.math.big.int.Const;
11
12const InternPool = @This();
13const DeclIndex = enum(u32) { _ };
914
1015const KeyAdapter = struct {
1116 intern_pool: *const InternPool,
......@@ -17,24 +22,21 @@ const KeyAdapter = struct {
1722
1823 pub fn hash(ctx: @This(), a: Key) u32 {
1924 _ = ctx;
20 return a.hash();
25 return a.hash32();
2126 }
2227};
2328
2429pub const Key = union(enum) {
25 int_type: struct {
26 signedness: std.builtin.Signedness,
27 bits: u16,
28 },
30 int_type: IntType,
2931 ptr_type: struct {
3032 elem_type: Index,
31 sentinel: Index,
32 alignment: u16,
33 sentinel: Index = .none,
34 alignment: u16 = 0,
3335 size: std.builtin.Type.Pointer.Size,
34 is_const: bool,
35 is_volatile: bool,
36 is_allowzero: bool,
37 address_space: std.builtin.AddressSpace,
36 is_const: bool = false,
37 is_volatile: bool = false,
38 is_allowzero: bool = false,
39 address_space: std.builtin.AddressSpace = .generic,
3840 },
3941 array_type: struct {
4042 len: u64,
......@@ -52,20 +54,52 @@ pub const Key = union(enum) {
5254 error_set_type: Index,
5355 payload_type: Index,
5456 },
55 simple: Simple,
57 simple_type: SimpleType,
58 simple_value: SimpleValue,
59 extern_func: struct {
60 ty: Index,
61 /// The Decl that corresponds to the function itself.
62 owner_decl: DeclIndex,
63 /// Library name if specified.
64 /// For example `extern "c" fn write(...) usize` would have 'c' as library name.
65 /// Index into the string table bytes.
66 lib_name: u32,
67 },
68 int: struct {
69 ty: Index,
70 big_int: BigIntConst,
71 },
72 enum_tag: struct {
73 ty: Index,
74 tag: BigIntConst,
75 },
76 struct_type: struct {
77 fields_len: u32,
78 // TODO move Module.Struct data to here
79 },
80
81 pub const IntType = std.builtin.Type.Int;
5682
57 pub fn hash(key: Key) u32 {
83 pub fn hash32(key: Key) u32 {
84 return @truncate(u32, key.hash64());
85 }
86
87 pub fn hash64(key: Key) u64 {
5888 var hasher = std.hash.Wyhash.init(0);
89 key.hashWithHasher(&hasher);
90 return hasher.final();
91 }
92
93 pub fn hashWithHasher(key: Key, hasher: *std.hash.Wyhash) void {
5994 switch (key) {
6095 .int_type => |int_type| {
61 std.hash.autoHash(&hasher, int_type);
96 std.hash.autoHash(hasher, int_type);
6297 },
6398 .array_type => |array_type| {
64 std.hash.autoHash(&hasher, array_type);
99 std.hash.autoHash(hasher, array_type);
65100 },
66101 else => @panic("TODO"),
67102 }
68 return @truncate(u32, hasher.final());
69103 }
70104
71105 pub fn eql(a: Key, b: Key) bool {
......@@ -85,6 +119,34 @@ pub const Key = union(enum) {
85119 else => @panic("TODO"),
86120 }
87121 }
122
123 pub fn typeOf(key: Key) Index {
124 switch (key) {
125 .int_type,
126 .ptr_type,
127 .array_type,
128 .vector_type,
129 .optional_type,
130 .error_union_type,
131 .simple_type,
132 .struct_type,
133 => return .type_type,
134
135 .int => |x| return x.ty,
136 .extern_func => |x| return x.ty,
137 .enum_tag => |x| return x.ty,
138
139 .simple_value => |s| switch (s) {
140 .undefined => return .undefined_type,
141 .void => return .void_type,
142 .null => return .null_type,
143 .false, .true => return .bool_type,
144 .empty_struct => return .empty_struct_type,
145 .@"unreachable" => return .noreturn_type,
146 .generic_poison => unreachable,
147 },
148 }
149 }
88150};
89151
90152pub const Item = struct {
......@@ -98,11 +160,330 @@ pub const Item = struct {
98160/// Two values which have the same type can be equality compared simply
99161/// by checking if their indexes are equal, provided they are both in
100162/// the same `InternPool`.
163/// When adding a tag to this enum, consider adding a corresponding entry to
164/// `primitives` in AstGen.zig.
101165pub const Index = enum(u32) {
166 u1_type,
167 u8_type,
168 i8_type,
169 u16_type,
170 i16_type,
171 u29_type,
172 u32_type,
173 i32_type,
174 u64_type,
175 i64_type,
176 u80_type,
177 u128_type,
178 i128_type,
179 usize_type,
180 isize_type,
181 c_char_type,
182 c_short_type,
183 c_ushort_type,
184 c_int_type,
185 c_uint_type,
186 c_long_type,
187 c_ulong_type,
188 c_longlong_type,
189 c_ulonglong_type,
190 c_longdouble_type,
191 f16_type,
192 f32_type,
193 f64_type,
194 f80_type,
195 f128_type,
196 anyopaque_type,
197 bool_type,
198 void_type,
199 type_type,
200 anyerror_type,
201 comptime_int_type,
202 comptime_float_type,
203 noreturn_type,
204 anyframe_type,
205 null_type,
206 undefined_type,
207 enum_literal_type,
208 atomic_order_type,
209 atomic_rmw_op_type,
210 calling_convention_type,
211 address_space_type,
212 float_mode_type,
213 reduce_op_type,
214 call_modifier_type,
215 prefetch_options_type,
216 export_options_type,
217 extern_options_type,
218 type_info_type,
219 manyptr_u8_type,
220 manyptr_const_u8_type,
221 single_const_pointer_to_comptime_int_type,
222 const_slice_u8_type,
223 anyerror_void_error_union_type,
224 generic_poison_type,
225 var_args_param_type,
226 empty_struct_type,
227
228 /// `undefined` (untyped)
229 undef,
230 /// `0` (comptime_int)
231 zero,
232 /// `0` (usize)
233 zero_usize,
234 /// `1` (comptime_int)
235 one,
236 /// `1` (usize)
237 one_usize,
238 /// `std.builtin.CallingConvention.C`
239 calling_convention_c,
240 /// `std.builtin.CallingConvention.Inline`
241 calling_convention_inline,
242 /// `{}`
243 void_value,
244 /// `unreachable` (noreturn type)
245 unreachable_value,
246 /// `null` (untyped)
247 null_value,
248 /// `true`
249 bool_true,
250 /// `false`
251 bool_false,
252 /// `.{}` (untyped)
253 empty_struct,
254 /// Used for generic parameters where the type and value
255 /// is not known until generic function instantiation.
256 generic_poison,
257
102258 none = std.math.maxInt(u32),
259
103260 _,
261
262 pub fn toType(i: Index) @import("type.zig").Type {
263 assert(i != .none);
264 return .{
265 .ip_index = i,
266 .legacy = undefined,
267 };
268 }
269
270 pub fn toValue(i: Index) @import("value.zig").Value {
271 assert(i != .none);
272 return .{
273 .ip_index = i,
274 .legacy = undefined,
275 };
276 }
277};
278
279pub const static_keys = [_]Key{
280 .{ .int_type = .{
281 .signedness = .unsigned,
282 .bits = 1,
283 } },
284
285 .{ .int_type = .{
286 .signedness = .unsigned,
287 .bits = 8,
288 } },
289
290 .{ .int_type = .{
291 .signedness = .signed,
292 .bits = 8,
293 } },
294
295 .{ .int_type = .{
296 .signedness = .unsigned,
297 .bits = 16,
298 } },
299
300 .{ .int_type = .{
301 .signedness = .signed,
302 .bits = 16,
303 } },
304
305 .{ .int_type = .{
306 .signedness = .unsigned,
307 .bits = 29,
308 } },
309
310 .{ .int_type = .{
311 .signedness = .unsigned,
312 .bits = 32,
313 } },
314
315 .{ .int_type = .{
316 .signedness = .signed,
317 .bits = 32,
318 } },
319
320 .{ .int_type = .{
321 .signedness = .unsigned,
322 .bits = 64,
323 } },
324
325 .{ .int_type = .{
326 .signedness = .signed,
327 .bits = 64,
328 } },
329
330 .{ .int_type = .{
331 .signedness = .unsigned,
332 .bits = 80,
333 } },
334
335 .{ .int_type = .{
336 .signedness = .unsigned,
337 .bits = 128,
338 } },
339
340 .{ .int_type = .{
341 .signedness = .signed,
342 .bits = 128,
343 } },
344
345 .{ .simple_type = .usize },
346 .{ .simple_type = .isize },
347 .{ .simple_type = .c_char },
348 .{ .simple_type = .c_short },
349 .{ .simple_type = .c_ushort },
350 .{ .simple_type = .c_int },
351 .{ .simple_type = .c_uint },
352 .{ .simple_type = .c_long },
353 .{ .simple_type = .c_ulong },
354 .{ .simple_type = .c_longlong },
355 .{ .simple_type = .c_ulonglong },
356 .{ .simple_type = .c_longdouble },
357 .{ .simple_type = .f16 },
358 .{ .simple_type = .f32 },
359 .{ .simple_type = .f64 },
360 .{ .simple_type = .f80 },
361 .{ .simple_type = .f128 },
362 .{ .simple_type = .anyopaque },
363 .{ .simple_type = .bool },
364 .{ .simple_type = .void },
365 .{ .simple_type = .type },
366 .{ .simple_type = .anyerror },
367 .{ .simple_type = .comptime_int },
368 .{ .simple_type = .comptime_float },
369 .{ .simple_type = .noreturn },
370 .{ .simple_type = .@"anyframe" },
371 .{ .simple_type = .null },
372 .{ .simple_type = .undefined },
373 .{ .simple_type = .enum_literal },
374 .{ .simple_type = .atomic_order },
375 .{ .simple_type = .atomic_rmw_op },
376 .{ .simple_type = .calling_convention },
377 .{ .simple_type = .address_space },
378 .{ .simple_type = .float_mode },
379 .{ .simple_type = .reduce_op },
380 .{ .simple_type = .call_modifier },
381 .{ .simple_type = .prefetch_options },
382 .{ .simple_type = .export_options },
383 .{ .simple_type = .extern_options },
384 .{ .simple_type = .type_info },
385
386 .{ .ptr_type = .{
387 .elem_type = .u8_type,
388 .size = .Many,
389 } },
390
391 .{ .ptr_type = .{
392 .elem_type = .u8_type,
393 .size = .Many,
394 .is_const = true,
395 } },
396
397 .{ .ptr_type = .{
398 .elem_type = .comptime_int_type,
399 .size = .One,
400 .is_const = true,
401 } },
402
403 .{ .ptr_type = .{
404 .elem_type = .u8_type,
405 .size = .Slice,
406 .is_const = true,
407 } },
408
409 .{ .error_union_type = .{
410 .error_set_type = .anyerror_type,
411 .payload_type = .void_type,
412 } },
413
414 // generic_poison_type
415 .{ .simple_type = .generic_poison },
416
417 // var_args_param_type
418 .{ .simple_type = .var_args_param },
419
420 // empty_struct_type
421 .{ .struct_type = .{
422 .fields_len = 0,
423 } },
424
425 .{ .simple_value = .undefined },
426
427 .{ .int = .{
428 .ty = .comptime_int_type,
429 .big_int = .{
430 .limbs = &.{0},
431 .positive = true,
432 },
433 } },
434
435 .{ .int = .{
436 .ty = .usize_type,
437 .big_int = .{
438 .limbs = &.{0},
439 .positive = true,
440 },
441 } },
442
443 .{ .int = .{
444 .ty = .comptime_int_type,
445 .big_int = .{
446 .limbs = &.{1},
447 .positive = true,
448 },
449 } },
450
451 .{ .int = .{
452 .ty = .usize_type,
453 .big_int = .{
454 .limbs = &.{1},
455 .positive = true,
456 },
457 } },
458
459 .{ .enum_tag = .{
460 .ty = .calling_convention_type,
461 .tag = .{
462 .limbs = &.{@enumToInt(std.builtin.CallingConvention.C)},
463 .positive = true,
464 },
465 } },
466
467 .{ .enum_tag = .{
468 .ty = .calling_convention_type,
469 .tag = .{
470 .limbs = &.{@enumToInt(std.builtin.CallingConvention.Inline)},
471 .positive = true,
472 },
473 } },
474
475 .{ .simple_value = .void },
476 .{ .simple_value = .@"unreachable" },
477 .{ .simple_value = .null },
478 .{ .simple_value = .true },
479 .{ .simple_value = .false },
480 .{ .simple_value = .empty_struct },
481 .{ .simple_value = .generic_poison },
104482};
105483
484/// How many items in the InternPool are statically known.
485pub const static_len: u32 = static_keys.len;
486
106487pub const Tag = enum(u8) {
107488 /// An integer type.
108489 /// data is number of bits
......@@ -113,9 +494,12 @@ pub const Tag = enum(u8) {
113494 /// An array type.
114495 /// data is payload to Array.
115496 type_array,
116 /// A type or value that can be represented with only an enum tag.
117 /// data is Simple enum value
118 simple,
497 /// A type that can be represented with only an enum tag.
498 /// data is SimpleType enum value.
499 simple_type,
500 /// A value that can be represented with only an enum tag.
501 /// data is SimpleValue enum value.
502 simple_value,
119503 /// An unsigned integer value that can be represented by u32.
120504 /// data is integer value
121505 int_u32,
......@@ -137,9 +521,20 @@ pub const Tag = enum(u8) {
137521 /// A float value that can be represented by f128.
138522 /// data is payload index to Float128.
139523 float_f128,
524 /// An extern function.
525 extern_func,
526 /// A regular function.
527 func,
528 /// Represents the data that an enum declaration provides, when the fields
529 /// are auto-numbered, and there are no declarations.
530 /// data is payload index to `EnumSimple`.
531 enum_simple,
140532};
141533
142pub const Simple = enum(u32) {
534/// Having `SimpleType` and `SimpleValue` in separate enums makes it easier to
535/// implement logic that only wants to deal with types because the logic can
536/// ignore all simple values. Note that technically, types are values.
537pub const SimpleType = enum(u32) {
143538 f16,
144539 f32,
145540 f64,
......@@ -147,6 +542,7 @@ pub const Simple = enum(u32) {
147542 f128,
148543 usize,
149544 isize,
545 c_char,
150546 c_short,
151547 c_ushort,
152548 c_int,
......@@ -165,14 +561,36 @@ pub const Simple = enum(u32) {
165561 comptime_float,
166562 noreturn,
167563 @"anyframe",
168 null_type,
169 undefined_type,
170 enum_literal_type,
564 null,
171565 undefined,
172 void_value,
566 enum_literal,
567
568 atomic_order,
569 atomic_rmw_op,
570 calling_convention,
571 address_space,
572 float_mode,
573 reduce_op,
574 call_modifier,
575 prefetch_options,
576 export_options,
577 extern_options,
578 type_info,
579
580 generic_poison,
581 var_args_param,
582};
583
584pub const SimpleValue = enum(u32) {
585 undefined,
586 void,
173587 null,
174 bool_true,
175 bool_false,
588 empty_struct,
589 true,
590 false,
591 @"unreachable",
592
593 generic_poison,
176594};
177595
178596pub const Array = struct {
......@@ -180,10 +598,44 @@ pub const Array = struct {
180598 child: Index,
181599};
182600
601/// Trailing:
602/// 0. field name: null-terminated string index for each fields_len; declaration order
603pub const EnumSimple = struct {
604 /// The Decl that corresponds to the enum itself.
605 owner_decl: DeclIndex,
606 /// An integer type which is used for the numerical value of the enum. This
607 /// is inferred by Zig to be the smallest power of two unsigned int that
608 /// fits the number of fields. It is stored here to avoid unnecessary
609 /// calculations and possibly allocation failure when querying the tag type
610 /// of enums.
611 int_tag_ty: Index,
612 fields_len: u32,
613};
614
615pub fn init(ip: *InternPool, gpa: Allocator) !void {
616 assert(ip.items.len == 0);
617
618 // So that we can use `catch unreachable` below.
619 try ip.items.ensureUnusedCapacity(gpa, static_keys.len);
620 try ip.map.ensureUnusedCapacity(gpa, static_keys.len);
621 try ip.extra.ensureUnusedCapacity(gpa, static_keys.len);
622
623 // This inserts all the statically-known values into the intern pool in the
624 // order expected.
625 for (static_keys) |key| _ = ip.get(gpa, key) catch unreachable;
626
627 // Sanity check.
628 assert(ip.indexToKey(.bool_true).simple_value == .true);
629 assert(ip.indexToKey(.bool_false).simple_value == .false);
630
631 assert(ip.items.len == static_keys.len);
632}
633
183634pub fn deinit(ip: *InternPool, gpa: Allocator) void {
184635 ip.map.deinit(gpa);
185636 ip.items.deinit(gpa);
186637 ip.extra.deinit(gpa);
638 ip.* = undefined;
187639}
188640
189641pub fn indexToKey(ip: InternPool, index: Index) Key {
......@@ -210,7 +662,8 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
210662 .sentinel = .none,
211663 } };
212664 },
213 .simple => .{ .simple = @intToEnum(Simple, data) },
665 .simple_type => .{ .simple_type = @intToEnum(SimpleType, data) },
666 .simple_value => .{ .simple_value = @intToEnum(SimpleValue, data) },
214667
215668 else => @panic("TODO"),
216669 };
......@@ -224,12 +677,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
224677 }
225678 switch (key) {
226679 .int_type => |int_type| {
227 const tag: Tag = switch (int_type.signedness) {
680 const t: Tag = switch (int_type.signedness) {
228681 .signed => .type_int_signed,
229682 .unsigned => .type_int_unsigned,
230683 };
231684 try ip.items.append(gpa, .{
232 .tag = tag,
685 .tag = t,
233686 .data = int_type.bits,
234687 });
235688 },
......@@ -249,6 +702,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
249702 return @intToEnum(Index, ip.items.len - 1);
250703}
251704
705pub fn tag(ip: InternPool, index: Index) Tag {
706 const tags = ip.items.items(.tag);
707 return tags[@enumToInt(index)];
708}
709
252710fn addExtra(ip: *InternPool, gpa: Allocator, extra: anytype) Allocator.Error!u32 {
253711 const fields = std.meta.fields(@TypeOf(extra));
254712 try ip.extra.ensureUnusedCapacity(gpa, fields.len);
src/Liveness.zig+5-3
......@@ -5,15 +5,17 @@
55//! Some instructions are special, such as:
66//! * Conditional Branches
77//! * Switch Branches
8const Liveness = @This();
98const std = @import("std");
10const trace = @import("tracy.zig").trace;
119const log = std.log.scoped(.liveness);
1210const assert = std.debug.assert;
1311const Allocator = std.mem.Allocator;
14const Air = @import("Air.zig");
1512const Log2Int = std.math.Log2Int;
1613
14const Liveness = @This();
15const trace = @import("tracy.zig").trace;
16const Air = @import("Air.zig");
17const InternPool = @import("InternPool.zig");
18
1719pub const Verify = @import("Liveness/Verify.zig");
1820
1921/// This array is split into sets of 4 bits per AIR instruction.
src/Module.zig+276-59
......@@ -32,6 +32,19 @@ const build_options = @import("build_options");
3232const Liveness = @import("Liveness.zig");
3333const isUpDir = @import("introspect.zig").isUpDir;
3434const clang = @import("clang.zig");
35const InternPool = @import("InternPool.zig");
36
37comptime {
38 @setEvalBranchQuota(4000);
39 for (
40 @typeInfo(Zir.Inst.Ref).Enum.fields,
41 @typeInfo(Air.Inst.Ref).Enum.fields,
42 @typeInfo(InternPool.Index).Enum.fields,
43 ) |zir_field, air_field, ip_field| {
44 assert(mem.eql(u8, zir_field.name, ip_field.name));
45 assert(mem.eql(u8, air_field.name, ip_field.name));
46 }
47}
3548
3649/// General-purpose allocator. Used for both temporary and long-term storage.
3750gpa: Allocator,
......@@ -83,6 +96,9 @@ embed_table: std.StringHashMapUnmanaged(*EmbedFile) = .{},
8396string_literal_table: std.HashMapUnmanaged(StringLiteralContext.Key, Decl.OptionalIndex, StringLiteralContext, std.hash_map.default_max_load_percentage) = .{},
8497string_literal_bytes: ArrayListUnmanaged(u8) = .{},
8598
99/// Stores all Type and Value objects; periodically garbage collected.
100intern_pool: InternPool = .{},
101
86102/// The set of all the generic function instantiations. This is used so that when a generic
87103/// function is called twice with the same comptime parameter arguments, both calls dispatch
88104/// to the same function.
......@@ -807,9 +823,9 @@ pub const Decl = struct {
807823 return (try decl.typedValue()).val;
808824 }
809825
810 pub fn isFunction(decl: Decl) !bool {
826 pub fn isFunction(decl: Decl, mod: *const Module) !bool {
811827 const tv = try decl.typedValue();
812 return tv.ty.zigTypeTag() == .Fn;
828 return tv.ty.zigTypeTag(mod) == .Fn;
813829 }
814830
815831 /// If the Decl has a value and it is a struct, return it,
......@@ -921,14 +937,14 @@ pub const Decl = struct {
921937 };
922938 }
923939
924 pub fn getAlignment(decl: Decl, target: Target) u32 {
940 pub fn getAlignment(decl: Decl, mod: *const Module) u32 {
925941 assert(decl.has_tv);
926942 if (decl.@"align" != 0) {
927943 // Explicit alignment.
928944 return decl.@"align";
929945 } else {
930946 // Natural alignment.
931 return decl.ty.abiAlignment(target);
947 return decl.ty.abiAlignment(mod);
932948 }
933949 }
934950};
......@@ -1030,7 +1046,7 @@ pub const Struct = struct {
10301046 /// Returns the field alignment. If the struct is packed, returns 0.
10311047 pub fn alignment(
10321048 field: Field,
1033 target: Target,
1049 mod: *const Module,
10341050 layout: std.builtin.Type.ContainerLayout,
10351051 ) u32 {
10361052 if (field.abi_align != 0) {
......@@ -1038,24 +1054,26 @@ pub const Struct = struct {
10381054 return field.abi_align;
10391055 }
10401056
1057 const target = mod.getTarget();
1058
10411059 switch (layout) {
10421060 .Packed => return 0,
10431061 .Auto => {
10441062 if (target.ofmt == .c) {
1045 return alignmentExtern(field, target);
1063 return alignmentExtern(field, mod);
10461064 } else {
1047 return field.ty.abiAlignment(target);
1065 return field.ty.abiAlignment(mod);
10481066 }
10491067 },
1050 .Extern => return alignmentExtern(field, target),
1068 .Extern => return alignmentExtern(field, mod),
10511069 }
10521070 }
10531071
1054 pub fn alignmentExtern(field: Field, target: Target) u32 {
1072 pub fn alignmentExtern(field: Field, mod: *const Module) u32 {
10551073 // This logic is duplicated in Type.abiAlignmentAdvanced.
1056 const ty_abi_align = field.ty.abiAlignment(target);
1074 const ty_abi_align = field.ty.abiAlignment(mod);
10571075
1058 if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) {
1076 if (field.ty.isAbiInt(mod) and field.ty.intInfo(mod).bits >= 128) {
10591077 // The C ABI requires 128 bit integer fields of structs
10601078 // to be 16-bytes aligned.
10611079 return @max(ty_abi_align, 16);
......@@ -1132,7 +1150,7 @@ pub const Struct = struct {
11321150 };
11331151 }
11341152
1135 pub fn packedFieldBitOffset(s: Struct, target: Target, index: usize) u16 {
1153 pub fn packedFieldBitOffset(s: Struct, mod: *const Module, index: usize) u16 {
11361154 assert(s.layout == .Packed);
11371155 assert(s.haveLayout());
11381156 var bit_sum: u64 = 0;
......@@ -1140,12 +1158,13 @@ pub const Struct = struct {
11401158 if (i == index) {
11411159 return @intCast(u16, bit_sum);
11421160 }
1143 bit_sum += field.ty.bitSize(target);
1161 bit_sum += field.ty.bitSize(mod);
11441162 }
11451163 unreachable; // index out of bounds
11461164 }
11471165
11481166 pub const RuntimeFieldIterator = struct {
1167 module: *const Module,
11491168 struct_obj: *const Struct,
11501169 index: u32 = 0,
11511170
......@@ -1155,6 +1174,7 @@ pub const Struct = struct {
11551174 };
11561175
11571176 pub fn next(it: *RuntimeFieldIterator) ?FieldAndIndex {
1177 const mod = it.module;
11581178 while (true) {
11591179 var i = it.index;
11601180 it.index += 1;
......@@ -1167,15 +1187,18 @@ pub const Struct = struct {
11671187 }
11681188 const field = it.struct_obj.fields.values()[i];
11691189
1170 if (!field.is_comptime and field.ty.hasRuntimeBits()) {
1190 if (!field.is_comptime and field.ty.hasRuntimeBits(mod)) {
11711191 return FieldAndIndex{ .index = i, .field = field };
11721192 }
11731193 }
11741194 }
11751195 };
11761196
1177 pub fn runtimeFieldIterator(s: *const Struct) RuntimeFieldIterator {
1178 return .{ .struct_obj = s };
1197 pub fn runtimeFieldIterator(s: *const Struct, module: *const Module) RuntimeFieldIterator {
1198 return .{
1199 .struct_obj = s,
1200 .module = module,
1201 };
11791202 }
11801203};
11811204
......@@ -1323,9 +1346,9 @@ pub const Union = struct {
13231346 /// Returns the field alignment, assuming the union is not packed.
13241347 /// Keep implementation in sync with `Sema.unionFieldAlignment`.
13251348 /// Prefer to call that function instead of this one during Sema.
1326 pub fn normalAlignment(field: Field, target: Target) u32 {
1349 pub fn normalAlignment(field: Field, mod: *const Module) u32 {
13271350 if (field.abi_align == 0) {
1328 return field.ty.abiAlignment(target);
1351 return field.ty.abiAlignment(mod);
13291352 } else {
13301353 return field.abi_align;
13311354 }
......@@ -1383,22 +1406,22 @@ pub const Union = struct {
13831406 };
13841407 }
13851408
1386 pub fn hasAllZeroBitFieldTypes(u: Union) bool {
1409 pub fn hasAllZeroBitFieldTypes(u: Union, mod: *const Module) bool {
13871410 assert(u.haveFieldTypes());
13881411 for (u.fields.values()) |field| {
1389 if (field.ty.hasRuntimeBits()) return false;
1412 if (field.ty.hasRuntimeBits(mod)) return false;
13901413 }
13911414 return true;
13921415 }
13931416
1394 pub fn mostAlignedField(u: Union, target: Target) u32 {
1417 pub fn mostAlignedField(u: Union, mod: *const Module) u32 {
13951418 assert(u.haveFieldTypes());
13961419 var most_alignment: u32 = 0;
13971420 var most_index: usize = undefined;
13981421 for (u.fields.values(), 0..) |field, i| {
1399 if (!field.ty.hasRuntimeBits()) continue;
1422 if (!field.ty.hasRuntimeBits(mod)) continue;
14001423
1401 const field_align = field.normalAlignment(target);
1424 const field_align = field.normalAlignment(mod);
14021425 if (field_align > most_alignment) {
14031426 most_alignment = field_align;
14041427 most_index = i;
......@@ -1408,20 +1431,20 @@ pub const Union = struct {
14081431 }
14091432
14101433 /// Returns 0 if the union is represented with 0 bits at runtime.
1411 pub fn abiAlignment(u: Union, target: Target, have_tag: bool) u32 {
1434 pub fn abiAlignment(u: Union, mod: *const Module, have_tag: bool) u32 {
14121435 var max_align: u32 = 0;
1413 if (have_tag) max_align = u.tag_ty.abiAlignment(target);
1436 if (have_tag) max_align = u.tag_ty.abiAlignment(mod);
14141437 for (u.fields.values()) |field| {
1415 if (!field.ty.hasRuntimeBits()) continue;
1438 if (!field.ty.hasRuntimeBits(mod)) continue;
14161439
1417 const field_align = field.normalAlignment(target);
1440 const field_align = field.normalAlignment(mod);
14181441 max_align = @max(max_align, field_align);
14191442 }
14201443 return max_align;
14211444 }
14221445
1423 pub fn abiSize(u: Union, target: Target, have_tag: bool) u64 {
1424 return u.getLayout(target, have_tag).abi_size;
1446 pub fn abiSize(u: Union, mod: *const Module, have_tag: bool) u64 {
1447 return u.getLayout(mod, have_tag).abi_size;
14251448 }
14261449
14271450 pub const Layout = struct {
......@@ -1451,7 +1474,7 @@ pub const Union = struct {
14511474 };
14521475 }
14531476
1454 pub fn getLayout(u: Union, target: Target, have_tag: bool) Layout {
1477 pub fn getLayout(u: Union, mod: *const Module, have_tag: bool) Layout {
14551478 assert(u.haveLayout());
14561479 var most_aligned_field: u32 = undefined;
14571480 var most_aligned_field_size: u64 = undefined;
......@@ -1460,16 +1483,16 @@ pub const Union = struct {
14601483 var payload_align: u32 = 0;
14611484 const fields = u.fields.values();
14621485 for (fields, 0..) |field, i| {
1463 if (!field.ty.hasRuntimeBitsIgnoreComptime()) continue;
1486 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
14641487
14651488 const field_align = a: {
14661489 if (field.abi_align == 0) {
1467 break :a field.ty.abiAlignment(target);
1490 break :a field.ty.abiAlignment(mod);
14681491 } else {
14691492 break :a field.abi_align;
14701493 }
14711494 };
1472 const field_size = field.ty.abiSize(target);
1495 const field_size = field.ty.abiSize(mod);
14731496 if (field_size > payload_size) {
14741497 payload_size = field_size;
14751498 biggest_field = @intCast(u32, i);
......@@ -1481,7 +1504,7 @@ pub const Union = struct {
14811504 }
14821505 }
14831506 payload_align = @max(payload_align, 1);
1484 if (!have_tag or !u.tag_ty.hasRuntimeBits()) {
1507 if (!have_tag or !u.tag_ty.hasRuntimeBits(mod)) {
14851508 return .{
14861509 .abi_size = std.mem.alignForwardGeneric(u64, payload_size, payload_align),
14871510 .abi_align = payload_align,
......@@ -1497,8 +1520,8 @@ pub const Union = struct {
14971520 }
14981521 // Put the tag before or after the payload depending on which one's
14991522 // alignment is greater.
1500 const tag_size = u.tag_ty.abiSize(target);
1501 const tag_align = @max(1, u.tag_ty.abiAlignment(target));
1523 const tag_size = u.tag_ty.abiSize(mod);
1524 const tag_align = @max(1, u.tag_ty.abiAlignment(mod));
15021525 var size: u64 = 0;
15031526 var padding: u32 = undefined;
15041527 if (tag_align >= payload_align) {
......@@ -2281,7 +2304,7 @@ pub const ErrorMsg = struct {
22812304 ) !*ErrorMsg {
22822305 const err_msg = try gpa.create(ErrorMsg);
22832306 errdefer gpa.destroy(err_msg);
2284 err_msg.* = try init(gpa, src_loc, format, args);
2307 err_msg.* = try ErrorMsg.init(gpa, src_loc, format, args);
22852308 return err_msg;
22862309 }
22872310
......@@ -3391,6 +3414,12 @@ pub const CompileError = error{
33913414 ComptimeBreak,
33923415};
33933416
3417pub fn init(mod: *Module) !void {
3418 const gpa = mod.gpa;
3419 try mod.error_name_list.append(gpa, "(no error)");
3420 try mod.intern_pool.init(gpa);
3421}
3422
33943423pub fn deinit(mod: *Module) void {
33953424 const gpa = mod.gpa;
33963425
......@@ -3518,6 +3547,8 @@ pub fn deinit(mod: *Module) void {
35183547
35193548 mod.string_literal_table.deinit(gpa);
35203549 mod.string_literal_bytes.deinit(gpa);
3550
3551 mod.intern_pool.deinit(gpa);
35213552}
35223553
35233554pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
......@@ -4277,7 +4308,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
42774308 // Update all dependents which have at least this level of dependency.
42784309 // If our type remained the same and we're a function, only update
42794310 // decls which depend on our body; otherwise, update all dependents.
4280 const update_level: Decl.DepType = if (!type_changed and decl.ty.zigTypeTag() == .Fn) .function_body else .normal;
4311 const update_level: Decl.DepType = if (!type_changed and decl.ty.zigTypeTag(mod) == .Fn) .function_body else .normal;
42814312
42824313 for (decl.dependants.keys(), decl.dependants.values()) |dep_index, dep_type| {
42834314 if (@enumToInt(dep_type) < @enumToInt(update_level)) continue;
......@@ -4748,8 +4779,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
47484779 decl_tv.ty.fmt(mod),
47494780 });
47504781 }
4751 var buffer: Value.ToTypeBuffer = undefined;
4752 const ty = try decl_tv.val.toType(&buffer).copy(decl_arena_allocator);
4782 const ty = try decl_tv.val.toType().copy(decl_arena_allocator);
47534783 if (ty.getNamespace() == null) {
47544784 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)});
47554785 }
......@@ -4775,7 +4805,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
47754805 var type_changed = true;
47764806
47774807 if (decl.has_tv) {
4778 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits();
4808 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits(mod);
47794809 type_changed = !decl.ty.eql(decl_tv.ty, mod);
47804810 if (decl.getFunction()) |prev_func| {
47814811 prev_is_inline = prev_func.state == .inline_only;
......@@ -5510,7 +5540,7 @@ pub fn clearDecl(
55105540 try mod.deleteDeclExports(decl_index);
55115541
55125542 if (decl.has_tv) {
5513 if (decl.ty.isFnOrHasRuntimeBits()) {
5543 if (decl.ty.isFnOrHasRuntimeBits(mod)) {
55145544 mod.comp.bin_file.freeDecl(decl_index);
55155545 }
55165546 if (decl.getInnerNamespace()) |namespace| {
......@@ -5699,7 +5729,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
56995729
57005730 const arg_val = if (arg_tv.val.tag() != .generic_poison)
57015731 arg_tv.val
5702 else if (arg_tv.ty.onePossibleValue()) |opv|
5732 else if (arg_tv.ty.onePossibleValue(mod)) |opv|
57035733 opv
57045734 else
57055735 break :t arg_tv.ty;
......@@ -5773,7 +5803,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
57735803 // If we don't get an error return trace from a caller, create our own.
57745804 if (func.calls_or_awaits_errorable_fn and
57755805 mod.comp.bin_file.options.error_return_tracing and
5776 !sema.fn_ret_ty.isError())
5806 !sema.fn_ret_ty.isError(mod))
57775807 {
57785808 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {
57795809 // TODO make these unreachable instead of @panic
......@@ -5995,25 +6025,11 @@ pub fn initNewAnonDecl(
59956025 // if the Decl is referenced by an instruction or another constant. Otherwise,
59966026 // the Decl will be garbage collected by the `codegen_decl` task instead of sent
59976027 // to the linker.
5998 if (typed_value.ty.isFnOrHasRuntimeBits()) {
6028 if (typed_value.ty.isFnOrHasRuntimeBits(mod)) {
59996029 try mod.comp.anon_work_queue.writeItem(.{ .codegen_decl = new_decl_index });
60006030 }
60016031}
60026032
6003pub fn makeIntType(arena: Allocator, signedness: std.builtin.Signedness, bits: u16) !Type {
6004 const int_payload = try arena.create(Type.Payload.Bits);
6005 int_payload.* = .{
6006 .base = .{
6007 .tag = switch (signedness) {
6008 .signed => .int_signed,
6009 .unsigned => .int_unsigned,
6010 },
6011 },
6012 .data = bits,
6013 };
6014 return Type.initPayload(&int_payload.base);
6015}
6016
60176033pub fn errNoteNonLazy(
60186034 mod: *Module,
60196035 src_loc: SrcLoc,
......@@ -6779,3 +6795,204 @@ pub fn backendSupportsFeature(mod: Module, feature: Feature) bool {
67796795 .field_reordering => mod.comp.bin_file.options.use_llvm,
67806796 };
67816797}
6798
6799/// Shortcut for calling `intern_pool.get`.
6800pub fn intern(mod: *Module, key: InternPool.Key) Allocator.Error!InternPool.Index {
6801 return mod.intern_pool.get(mod.gpa, key);
6802}
6803
6804pub fn intType(mod: *Module, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {
6805 const i = try intern(mod, .{ .int_type = .{
6806 .signedness = signedness,
6807 .bits = bits,
6808 } });
6809 return i.toType();
6810}
6811
6812pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type {
6813 return intType(mod, .unsigned, Type.smallestUnsignedBits(max));
6814}
6815
6816/// Returns the smallest possible integer type containing both `min` and
6817/// `max`. Asserts that neither value is undef.
6818/// TODO: if #3806 is implemented, this becomes trivial
6819pub fn intFittingRange(mod: *Module, min: Value, max: Value) !Type {
6820 assert(!min.isUndef());
6821 assert(!max.isUndef());
6822
6823 if (std.debug.runtime_safety) {
6824 assert(Value.order(min, max, mod).compare(.lte));
6825 }
6826
6827 const sign = min.orderAgainstZero(mod) == .lt;
6828
6829 const min_val_bits = intBitsForValue(mod, min, sign);
6830 const max_val_bits = intBitsForValue(mod, max, sign);
6831
6832 return mod.intType(
6833 if (sign) .signed else .unsigned,
6834 @max(min_val_bits, max_val_bits),
6835 );
6836}
6837
6838/// Given a value representing an integer, returns the number of bits necessary to represent
6839/// this value in an integer. If `sign` is true, returns the number of bits necessary in a
6840/// twos-complement integer; otherwise in an unsigned integer.
6841/// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.
6842pub fn intBitsForValue(mod: *Module, val: Value, sign: bool) u16 {
6843 assert(!val.isUndef());
6844 switch (val.tag()) {
6845 .int_big_positive => {
6846 const limbs = val.castTag(.int_big_positive).?.data;
6847 const big: std.math.big.int.Const = .{ .limbs = limbs, .positive = true };
6848 return @intCast(u16, big.bitCountAbs() + @boolToInt(sign));
6849 },
6850 .int_big_negative => {
6851 const limbs = val.castTag(.int_big_negative).?.data;
6852 // Zero is still a possibility, in which case unsigned is fine
6853 for (limbs) |limb| {
6854 if (limb != 0) break;
6855 } else return 0; // val == 0
6856 assert(sign);
6857 const big: std.math.big.int.Const = .{ .limbs = limbs, .positive = false };
6858 return @intCast(u16, big.bitCountTwosComp());
6859 },
6860 .int_i64 => {
6861 const x = val.castTag(.int_i64).?.data;
6862 if (x >= 0) return Type.smallestUnsignedBits(@intCast(u64, x));
6863 assert(sign);
6864 return Type.smallestUnsignedBits(@intCast(u64, -x - 1)) + 1;
6865 },
6866 else => {
6867 const x = val.toUnsignedInt(mod);
6868 return Type.smallestUnsignedBits(x) + @boolToInt(sign);
6869 },
6870 }
6871}
6872
6873pub const AtomicPtrAlignmentError = error{
6874 FloatTooBig,
6875 IntTooBig,
6876 BadType,
6877};
6878
6879pub const AtomicPtrAlignmentDiagnostics = struct {
6880 bits: u16 = undefined,
6881 max_bits: u16 = undefined,
6882};
6883
6884/// If ABI alignment of `ty` is OK for atomic operations, returns 0.
6885/// Otherwise returns the alignment required on a pointer for the target
6886/// to perform atomic operations.
6887// TODO this function does not take into account CPU features, which can affect
6888// this value. Audit this!
6889pub fn atomicPtrAlignment(
6890 mod: *const Module,
6891 ty: Type,
6892 diags: *AtomicPtrAlignmentDiagnostics,
6893) AtomicPtrAlignmentError!u32 {
6894 const target = mod.getTarget();
6895 const max_atomic_bits: u16 = switch (target.cpu.arch) {
6896 .avr,
6897 .msp430,
6898 .spu_2,
6899 => 16,
6900
6901 .arc,
6902 .arm,
6903 .armeb,
6904 .hexagon,
6905 .m68k,
6906 .le32,
6907 .mips,
6908 .mipsel,
6909 .nvptx,
6910 .powerpc,
6911 .powerpcle,
6912 .r600,
6913 .riscv32,
6914 .sparc,
6915 .sparcel,
6916 .tce,
6917 .tcele,
6918 .thumb,
6919 .thumbeb,
6920 .x86,
6921 .xcore,
6922 .amdil,
6923 .hsail,
6924 .spir,
6925 .kalimba,
6926 .lanai,
6927 .shave,
6928 .wasm32,
6929 .renderscript32,
6930 .csky,
6931 .spirv32,
6932 .dxil,
6933 .loongarch32,
6934 .xtensa,
6935 => 32,
6936
6937 .amdgcn,
6938 .bpfel,
6939 .bpfeb,
6940 .le64,
6941 .mips64,
6942 .mips64el,
6943 .nvptx64,
6944 .powerpc64,
6945 .powerpc64le,
6946 .riscv64,
6947 .sparc64,
6948 .s390x,
6949 .amdil64,
6950 .hsail64,
6951 .spir64,
6952 .wasm64,
6953 .renderscript64,
6954 .ve,
6955 .spirv64,
6956 .loongarch64,
6957 => 64,
6958
6959 .aarch64,
6960 .aarch64_be,
6961 .aarch64_32,
6962 => 128,
6963
6964 .x86_64 => if (std.Target.x86.featureSetHas(target.cpu.features, .cx16)) 128 else 64,
6965 };
6966
6967 const int_ty = switch (ty.zigTypeTag(mod)) {
6968 .Int => ty,
6969 .Enum => ty.intTagType(),
6970 .Float => {
6971 const bit_count = ty.floatBits(target);
6972 if (bit_count > max_atomic_bits) {
6973 diags.* = .{
6974 .bits = bit_count,
6975 .max_bits = max_atomic_bits,
6976 };
6977 return error.FloatTooBig;
6978 }
6979 return 0;
6980 },
6981 .Bool => return 0,
6982 else => {
6983 if (ty.isPtrAtRuntime(mod)) return 0;
6984 return error.BadType;
6985 },
6986 };
6987
6988 const bit_count = int_ty.intInfo(mod).bits;
6989 if (bit_count > max_atomic_bits) {
6990 diags.* = .{
6991 .bits = bit_count,
6992 .max_bits = max_atomic_bits,
6993 };
6994 return error.IntTooBig;
6995 }
6996
6997 return 0;
6998}
src/RangeSet.zig+6-7
......@@ -60,13 +60,14 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
6060 if (self.ranges.items.len == 0)
6161 return false;
6262
63 const mod = self.module;
6364 std.mem.sort(Range, self.ranges.items, LessThanContext{
6465 .ty = ty,
65 .module = self.module,
66 .module = mod,
6667 }, lessThan);
6768
68 if (!self.ranges.items[0].first.eql(first, ty, self.module) or
69 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty, self.module))
69 if (!self.ranges.items[0].first.eql(first, ty, mod) or
70 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty, mod))
7071 {
7172 return false;
7273 }
......@@ -76,18 +77,16 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
7677 var counter = try std.math.big.int.Managed.init(self.ranges.allocator);
7778 defer counter.deinit();
7879
79 const target = self.module.getTarget();
80
8180 // look for gaps
8281 for (self.ranges.items[1..], 0..) |cur, i| {
8382 // i starts counting from the second item.
8483 const prev = self.ranges.items[i];
8584
8685 // prev.last + 1 == cur.first
87 try counter.copy(prev.last.toBigInt(&space, target));
86 try counter.copy(prev.last.toBigInt(&space, mod));
8887 try counter.addScalar(&counter, 1);
8988
90 const cur_start_int = cur.first.toBigInt(&space, target);
89 const cur_start_int = cur.first.toBigInt(&space, mod);
9190 if (!cur_start_int.eq(counter.toConst())) {
9291 return false;
9392 }
src/Sema.zig+1290-1093
......@@ -114,6 +114,7 @@ const Package = @import("Package.zig");
114114const crash_report = @import("crash_report.zig");
115115const build_options = @import("build_options");
116116const Compilation = @import("Compilation.zig");
117const InternPool = @import("InternPool.zig");
117118
118119pub const default_branch_quota = 1000;
119120pub const default_reference_trace_len = 2;
......@@ -1614,6 +1615,7 @@ fn analyzeBodyInner(
16141615 },
16151616 .@"try" => blk: {
16161617 if (!block.is_comptime) break :blk try sema.zirTry(block, inst);
1618 const mod = sema.mod;
16171619 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
16181620 const src = inst_data.src();
16191621 const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
......@@ -1621,18 +1623,18 @@ fn analyzeBodyInner(
16211623 const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len];
16221624 const err_union = try sema.resolveInst(extra.data.operand);
16231625 const err_union_ty = sema.typeOf(err_union);
1624 if (err_union_ty.zigTypeTag() != .ErrorUnion) {
1626 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
16251627 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
16261628 err_union_ty.fmt(sema.mod),
16271629 });
16281630 }
16291631 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);
16301632 assert(is_non_err != .none);
1631 const is_non_err_tv = sema.resolveInstConst(block, operand_src, is_non_err, "try operand inside comptime block must be comptime-known") catch |err| {
1633 const is_non_err_val = sema.resolveConstValue(block, operand_src, is_non_err, "try operand inside comptime block must be comptime-known") catch |err| {
16321634 if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
16331635 return err;
16341636 };
1635 if (is_non_err_tv.val.toBool()) {
1637 if (is_non_err_val.toBool()) {
16361638 break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false);
16371639 }
16381640 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
......@@ -1654,11 +1656,11 @@ fn analyzeBodyInner(
16541656 const err_union = try sema.analyzeLoad(block, src, operand, operand_src);
16551657 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);
16561658 assert(is_non_err != .none);
1657 const is_non_err_tv = sema.resolveInstConst(block, operand_src, is_non_err, "try operand inside comptime block must be comptime-known") catch |err| {
1659 const is_non_err_val = sema.resolveConstValue(block, operand_src, is_non_err, "try operand inside comptime block must be comptime-known") catch |err| {
16581660 if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err);
16591661 return err;
16601662 };
1661 if (is_non_err_tv.val.toBool()) {
1663 if (is_non_err_val.toBool()) {
16621664 break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
16631665 }
16641666 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
......@@ -1721,17 +1723,12 @@ fn analyzeBodyInner(
17211723}
17221724
17231725pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
1724 var i: usize = @enumToInt(zir_ref);
1725
1726 const i = @enumToInt(zir_ref);
17261727 // First section of indexes correspond to a set number of constant values.
1727 if (i < Zir.Inst.Ref.typed_value_map.len) {
1728 // We intentionally map the same indexes to the same values between ZIR and AIR.
1729 return zir_ref;
1730 }
1731 i -= Zir.Inst.Ref.typed_value_map.len;
1732
1733 // Finally, the last section of indexes refers to the map of ZIR=>AIR.
1734 const inst = sema.inst_map.get(@intCast(u32, i)).?;
1728 // We intentionally map the same indexes to the same values between ZIR and AIR.
1729 if (i < InternPool.static_len) return @intToEnum(Air.Inst.Ref, i);
1730 // The last section of indexes refers to the map of ZIR => AIR.
1731 const inst = sema.inst_map.get(i - InternPool.static_len).?;
17351732 const ty = sema.typeOf(inst);
17361733 if (ty.tag() == .generic_poison) return error.GenericPoison;
17371734 return inst;
......@@ -1766,9 +1763,8 @@ pub fn resolveConstString(
17661763}
17671764
17681765pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {
1769 assert(zir_ref != .var_args_param);
17701766 const air_inst = try sema.resolveInst(zir_ref);
1771 assert(air_inst != .var_args_param);
1767 assert(air_inst != .var_args_param_type);
17721768 const ty = try sema.analyzeAsType(block, src, air_inst);
17731769 if (ty.tag() == .generic_poison) return error.GenericPoison;
17741770 return ty;
......@@ -1783,8 +1779,7 @@ fn analyzeAsType(
17831779 const wanted_type = Type.initTag(.type);
17841780 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
17851781 const val = try sema.resolveConstValue(block, src, coerced_inst, "types must be comptime-known");
1786 var buffer: Value.ToTypeBuffer = undefined;
1787 const ty = val.toType(&buffer);
1782 const ty = val.toType();
17881783 return ty.copy(sema.arena);
17891784}
17901785
......@@ -1950,12 +1945,12 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime(
19501945 make_runtime: *bool,
19511946) CompileError!?Value {
19521947 // First section of indexes correspond to a set number of constant values.
1953 var i: usize = @enumToInt(inst);
1954 if (i < Air.Inst.Ref.typed_value_map.len) {
1955 return Air.Inst.Ref.typed_value_map[i].val;
1948 const int = @enumToInt(inst);
1949 if (int < InternPool.static_len) {
1950 return @intToEnum(InternPool.Index, int).toValue();
19561951 }
1957 i -= Air.Inst.Ref.typed_value_map.len;
19581952
1953 const i = int - InternPool.static_len;
19591954 const air_tags = sema.air_instructions.items(.tag);
19601955 if (try sema.typeHasOnePossibleValue(sema.typeOf(inst))) |opv| {
19611956 if (air_tags[i] == .constant) {
......@@ -2010,13 +2005,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, opt
20102005}
20112006
20122007fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
2008 const mod = sema.mod;
20132009 const msg = msg: {
20142010 const msg = try sema.errMsg(block, src, "type '{}' does not support array initialization syntax", .{
2015 ty.fmt(sema.mod),
2011 ty.fmt(mod),
20162012 });
20172013 errdefer msg.destroy(sema.gpa);
20182014 if (ty.isSlice()) {
2019 try sema.errNote(block, src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2().fmt(sema.mod)});
2015 try sema.errNote(block, src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2(mod).fmt(mod)});
20202016 }
20212017 break :msg msg;
20222018 };
......@@ -2042,7 +2038,8 @@ fn failWithErrorSetCodeMissing(
20422038}
20432039
20442040fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value, vector_index: usize) CompileError {
2045 if (int_ty.zigTypeTag() == .Vector) {
2041 const mod = sema.mod;
2042 if (int_ty.zigTypeTag(mod) == .Vector) {
20462043 const msg = msg: {
20472044 const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{
20482045 int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod),
......@@ -2084,12 +2081,13 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
20842081}
20852082
20862083fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {
2084 const mod = sema.mod;
20872085 const inner_ty = if (object_ty.isSinglePointer()) object_ty.childType() else object_ty;
20882086
2089 if (inner_ty.zigTypeTag() == .Optional) opt: {
2087 if (inner_ty.zigTypeTag(mod) == .Optional) opt: {
20902088 var buf: Type.Payload.ElemType = undefined;
20912089 const child_ty = inner_ty.optionalChild(&buf);
2092 if (!typeSupportsFieldAccess(child_ty, field_name)) break :opt;
2090 if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :opt;
20932091 const msg = msg: {
20942092 const msg = try sema.errMsg(block, src, "optional type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
20952093 errdefer msg.destroy(sema.gpa);
......@@ -2097,9 +2095,9 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec
20972095 break :msg msg;
20982096 };
20992097 return sema.failWithOwnedErrorMsg(msg);
2100 } else if (inner_ty.zigTypeTag() == .ErrorUnion) err: {
2098 } else if (inner_ty.zigTypeTag(mod) == .ErrorUnion) err: {
21012099 const child_ty = inner_ty.errorUnionPayload();
2102 if (!typeSupportsFieldAccess(child_ty, field_name)) break :err;
2100 if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :err;
21032101 const msg = msg: {
21042102 const msg = try sema.errMsg(block, src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
21052103 errdefer msg.destroy(sema.gpa);
......@@ -2111,14 +2109,14 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec
21112109 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
21122110}
21132111
2114fn typeSupportsFieldAccess(ty: Type, field_name: []const u8) bool {
2115 switch (ty.zigTypeTag()) {
2112fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: []const u8) bool {
2113 switch (ty.zigTypeTag(mod)) {
21162114 .Array => return mem.eql(u8, field_name, "len"),
21172115 .Pointer => {
21182116 const ptr_info = ty.ptrInfo().data;
21192117 if (ptr_info.size == .Slice) {
21202118 return mem.eql(u8, field_name, "ptr") or mem.eql(u8, field_name, "len");
2121 } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {
2119 } else if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
21222120 return mem.eql(u8, field_name, "len");
21232121 } else return false;
21242122 },
......@@ -2352,10 +2350,10 @@ fn analyzeAsInt(
23522350 dest_ty: Type,
23532351 reason: []const u8,
23542352) !u64 {
2353 const mod = sema.mod;
23552354 const coerced = try sema.coerce(block, dest_ty, air_ref, src);
23562355 const val = try sema.resolveConstValue(block, src, coerced, reason);
2357 const target = sema.mod.getTarget();
2358 return (try val.getUnsignedIntAdvanced(target, sema)).?;
2356 return (try val.getUnsignedIntAdvanced(mod, sema)).?;
23592357}
23602358
23612359// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for
......@@ -2926,23 +2924,23 @@ fn zirEnumDecl(
29262924
29272925 if (tag_type_ref != .none) {
29282926 const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref);
2929 if (ty.zigTypeTag() != .Int and ty.zigTypeTag() != .ComptimeInt) {
2927 if (ty.zigTypeTag(mod) != .Int and ty.zigTypeTag(mod) != .ComptimeInt) {
29302928 return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)});
29312929 }
29322930 enum_obj.tag_ty = try ty.copy(decl_arena_allocator);
29332931 enum_obj.tag_ty_inferred = false;
29342932 } else if (fields_len == 0) {
2935 enum_obj.tag_ty = try Type.Tag.int_unsigned.create(decl_arena_allocator, 0);
2933 enum_obj.tag_ty = try mod.intType(.unsigned, 0);
29362934 enum_obj.tag_ty_inferred = true;
29372935 } else {
29382936 const bits = std.math.log2_int_ceil(usize, fields_len);
2939 enum_obj.tag_ty = try Type.Tag.int_unsigned.create(decl_arena_allocator, bits);
2937 enum_obj.tag_ty = try mod.intType(.unsigned, bits);
29402938 enum_obj.tag_ty_inferred = true;
29412939 }
29422940 }
29432941
2944 if (small.nonexhaustive and enum_obj.tag_ty.zigTypeTag() != .ComptimeInt) {
2945 if (fields_len > 1 and std.math.log2_int(u64, fields_len) == enum_obj.tag_ty.bitSize(sema.mod.getTarget())) {
2942 if (small.nonexhaustive and enum_obj.tag_ty.zigTypeTag(mod) != .ComptimeInt) {
2943 if (fields_len > 1 and std.math.log2_int(u64, fields_len) == enum_obj.tag_ty.bitSize(mod)) {
29462944 return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});
29472945 }
29482946 }
......@@ -3319,7 +3317,8 @@ fn ensureResultUsed(
33193317 ty: Type,
33203318 src: LazySrcLoc,
33213319) CompileError!void {
3322 switch (ty.zigTypeTag()) {
3320 const mod = sema.mod;
3321 switch (ty.zigTypeTag(mod)) {
33233322 .Void, .NoReturn => return,
33243323 .ErrorSet, .ErrorUnion => {
33253324 const msg = msg: {
......@@ -3347,11 +3346,12 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
33473346 const tracy = trace(@src());
33483347 defer tracy.end();
33493348
3349 const mod = sema.mod;
33503350 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
33513351 const operand = try sema.resolveInst(inst_data.operand);
33523352 const src = inst_data.src();
33533353 const operand_ty = sema.typeOf(operand);
3354 switch (operand_ty.zigTypeTag()) {
3354 switch (operand_ty.zigTypeTag(mod)) {
33553355 .ErrorSet, .ErrorUnion => {
33563356 const msg = msg: {
33573357 const msg = try sema.errMsg(block, src, "error is discarded", .{});
......@@ -3369,16 +3369,17 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index
33693369 const tracy = trace(@src());
33703370 defer tracy.end();
33713371
3372 const mod = sema.mod;
33723373 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
33733374 const src = inst_data.src();
33743375 const operand = try sema.resolveInst(inst_data.operand);
33753376 const operand_ty = sema.typeOf(operand);
3376 const err_union_ty = if (operand_ty.zigTypeTag() == .Pointer)
3377 const err_union_ty = if (operand_ty.zigTypeTag(mod) == .Pointer)
33773378 operand_ty.childType()
33783379 else
33793380 operand_ty;
3380 if (err_union_ty.zigTypeTag() != .ErrorUnion) return;
3381 const payload_ty = err_union_ty.errorUnionPayload().zigTypeTag();
3381 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) return;
3382 const payload_ty = err_union_ty.errorUnionPayload().zigTypeTag(mod);
33823383 if (payload_ty != .Void and payload_ty != .NoReturn) {
33833384 const msg = msg: {
33843385 const msg = try sema.errMsg(block, src, "error union payload is ignored", .{});
......@@ -3920,19 +3921,20 @@ fn zirArrayBasePtr(
39203921 block: *Block,
39213922 inst: Zir.Inst.Index,
39223923) CompileError!Air.Inst.Ref {
3924 const mod = sema.mod;
39233925 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
39243926 const src = inst_data.src();
39253927
39263928 const start_ptr = try sema.resolveInst(inst_data.operand);
39273929 var base_ptr = start_ptr;
3928 while (true) switch (sema.typeOf(base_ptr).childType().zigTypeTag()) {
3930 while (true) switch (sema.typeOf(base_ptr).childType().zigTypeTag(mod)) {
39293931 .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),
39303932 .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false, true),
39313933 else => break,
39323934 };
39333935
39343936 const elem_ty = sema.typeOf(base_ptr).childType();
3935 switch (elem_ty.zigTypeTag()) {
3937 switch (elem_ty.zigTypeTag(mod)) {
39363938 .Array, .Vector => return base_ptr,
39373939 .Struct => if (elem_ty.isTuple()) {
39383940 // TODO validate element count
......@@ -3948,19 +3950,20 @@ fn zirFieldBasePtr(
39483950 block: *Block,
39493951 inst: Zir.Inst.Index,
39503952) CompileError!Air.Inst.Ref {
3953 const mod = sema.mod;
39513954 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
39523955 const src = inst_data.src();
39533956
39543957 const start_ptr = try sema.resolveInst(inst_data.operand);
39553958 var base_ptr = start_ptr;
3956 while (true) switch (sema.typeOf(base_ptr).childType().zigTypeTag()) {
3959 while (true) switch (sema.typeOf(base_ptr).childType().zigTypeTag(mod)) {
39573960 .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),
39583961 .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false, true),
39593962 else => break,
39603963 };
39613964
39623965 const elem_ty = sema.typeOf(base_ptr).childType();
3963 switch (elem_ty.zigTypeTag()) {
3966 switch (elem_ty.zigTypeTag(mod)) {
39643967 .Struct, .Union => return base_ptr,
39653968 else => {},
39663969 }
......@@ -3968,6 +3971,7 @@ fn zirFieldBasePtr(
39683971}
39693972
39703973fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3974 const mod = sema.mod;
39713975 const gpa = sema.gpa;
39723976 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
39733977 const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
......@@ -3991,7 +3995,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
39913995 const object_ty = sema.typeOf(object);
39923996 // Each arg could be an indexable, or a range, in which case the length
39933997 // is passed directly as an integer.
3994 const is_int = switch (object_ty.zigTypeTag()) {
3998 const is_int = switch (object_ty.zigTypeTag(mod)) {
39953999 .Int, .ComptimeInt => true,
39964000 else => false,
39974001 };
......@@ -4000,7 +4004,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
40004004 .input_index = i,
40014005 } };
40024006 const arg_len_uncoerced = if (is_int) object else l: {
4003 if (!object_ty.isIndexable()) {
4007 if (!object_ty.isIndexable(mod)) {
40044008 // Instead of using checkIndexable we customize this error.
40054009 const msg = msg: {
40064010 const msg = try sema.errMsg(block, arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(sema.mod)});
......@@ -4010,7 +4014,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
40104014 };
40114015 return sema.failWithOwnedErrorMsg(msg);
40124016 }
4013 if (!object_ty.indexableHasLen()) continue;
4017 if (!object_ty.indexableHasLen(mod)) continue;
40144018
40154019 break :l try sema.fieldVal(block, arg_src, object, "len", arg_src);
40164020 };
......@@ -4061,7 +4065,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
40614065 const object_ty = sema.typeOf(object);
40624066 // Each arg could be an indexable, or a range, in which case the length
40634067 // is passed directly as an integer.
4064 switch (object_ty.zigTypeTag()) {
4068 switch (object_ty.zigTypeTag(mod)) {
40654069 .Int, .ComptimeInt => continue,
40664070 else => {},
40674071 }
......@@ -4096,13 +4100,14 @@ fn validateArrayInitTy(
40964100 block: *Block,
40974101 inst: Zir.Inst.Index,
40984102) CompileError!void {
4103 const mod = sema.mod;
40994104 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
41004105 const src = inst_data.src();
41014106 const ty_src: LazySrcLoc = .{ .node_offset_init_ty = inst_data.src_node };
41024107 const extra = sema.code.extraData(Zir.Inst.ArrayInit, inst_data.payload_index).data;
41034108 const ty = try sema.resolveType(block, ty_src, extra.ty);
41044109
4105 switch (ty.zigTypeTag()) {
4110 switch (ty.zigTypeTag(mod)) {
41064111 .Array => {
41074112 const array_len = ty.arrayLen();
41084113 if (extra.init_count != array_len) {
......@@ -4141,11 +4146,12 @@ fn validateStructInitTy(
41414146 block: *Block,
41424147 inst: Zir.Inst.Index,
41434148) CompileError!void {
4149 const mod = sema.mod;
41444150 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
41454151 const src = inst_data.src();
41464152 const ty = try sema.resolveType(block, src, inst_data.operand);
41474153
4148 switch (ty.zigTypeTag()) {
4154 switch (ty.zigTypeTag(mod)) {
41494155 .Struct, .Union => return,
41504156 else => {},
41514157 }
......@@ -4160,6 +4166,7 @@ fn zirValidateStructInit(
41604166 const tracy = trace(@src());
41614167 defer tracy.end();
41624168
4169 const mod = sema.mod;
41634170 const validate_inst = sema.code.instructions.items(.data)[inst].pl_node;
41644171 const init_src = validate_inst.src();
41654172 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);
......@@ -4168,7 +4175,7 @@ fn zirValidateStructInit(
41684175 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
41694176 const object_ptr = try sema.resolveInst(field_ptr_extra.lhs);
41704177 const agg_ty = sema.typeOf(object_ptr).childType();
4171 switch (agg_ty.zigTypeTag()) {
4178 switch (agg_ty.zigTypeTag(mod)) {
41724179 .Struct => return sema.validateStructInit(
41734180 block,
41744181 agg_ty,
......@@ -4589,6 +4596,7 @@ fn zirValidateArrayInit(
45894596 block: *Block,
45904597 inst: Zir.Inst.Index,
45914598) CompileError!void {
4599 const mod = sema.mod;
45924600 const validate_inst = sema.code.instructions.items(.data)[inst].pl_node;
45934601 const init_src = validate_inst.src();
45944602 const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index);
......@@ -4599,7 +4607,7 @@ fn zirValidateArrayInit(
45994607 const array_ty = sema.typeOf(array_ptr).childType();
46004608 const array_len = array_ty.arrayLen();
46014609
4602 if (instrs.len != array_len) switch (array_ty.zigTypeTag()) {
4610 if (instrs.len != array_len) switch (array_ty.zigTypeTag(mod)) {
46034611 .Struct => {
46044612 var root_msg: ?*Module.ErrorMsg = null;
46054613 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
......@@ -4667,7 +4675,7 @@ fn zirValidateArrayInit(
46674675 // Determine whether the value stored to this pointer is comptime-known.
46684676
46694677 if (array_ty.isTuple()) {
4670 if (array_ty.structFieldValueComptime(i)) |opv| {
4678 if (array_ty.structFieldValueComptime(mod, i)) |opv| {
46714679 element_vals[i] = opv;
46724680 continue;
46734681 }
......@@ -4770,12 +4778,13 @@ fn zirValidateArrayInit(
47704778}
47714779
47724780fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
4781 const mod = sema.mod;
47734782 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
47744783 const src = inst_data.src();
47754784 const operand = try sema.resolveInst(inst_data.operand);
47764785 const operand_ty = sema.typeOf(operand);
47774786
4778 if (operand_ty.zigTypeTag() != .Pointer) {
4787 if (operand_ty.zigTypeTag(mod) != .Pointer) {
47794788 return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(sema.mod)});
47804789 } else switch (operand_ty.ptrSize()) {
47814790 .One, .C => {},
......@@ -4788,7 +4797,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
47884797 return;
47894798 }
47904799
4791 const elem_ty = operand_ty.elemType2();
4800 const elem_ty = operand_ty.elemType2(mod);
47924801 if (try sema.resolveMaybeUndefVal(operand)) |val| {
47934802 if (val.isUndef()) {
47944803 return sema.fail(block, src, "cannot dereference undefined value", .{});
......@@ -4818,7 +4827,8 @@ fn failWithBadMemberAccess(
48184827 field_src: LazySrcLoc,
48194828 field_name: []const u8,
48204829) CompileError {
4821 const kw_name = switch (agg_ty.zigTypeTag()) {
4830 const mod = sema.mod;
4831 const kw_name = switch (agg_ty.zigTypeTag(mod)) {
48224832 .Union => "union",
48234833 .Struct => "struct",
48244834 .Opaque => "opaque",
......@@ -4894,8 +4904,9 @@ fn failWithBadUnionFieldAccess(
48944904}
48954905
48964906fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void {
4897 const src_loc = decl_ty.declSrcLocOrNull(sema.mod) orelse return;
4898 const category = switch (decl_ty.zigTypeTag()) {
4907 const mod = sema.mod;
4908 const src_loc = decl_ty.declSrcLocOrNull(mod) orelse return;
4909 const category = switch (decl_ty.zigTypeTag(mod)) {
48994910 .Union => "union",
49004911 .Struct => "struct",
49014912 .Enum => "enum",
......@@ -4903,7 +4914,7 @@ fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !vo
49034914 .ErrorSet => "error set",
49044915 else => unreachable,
49054916 };
4906 try sema.mod.errNoteNonLazy(src_loc, parent, "{s} declared here", .{category});
4917 try mod.errNoteNonLazy(src_loc, parent, "{s} declared here", .{category});
49074918}
49084919
49094920fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
......@@ -5028,6 +5039,7 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
50285039 const tracy = trace(@src());
50295040 defer tracy.end();
50305041
5042 const mod = sema.mod;
50315043 const zir_tags = sema.code.instructions.items(.tag);
50325044 const zir_datas = sema.code.instructions.items(.data);
50335045 const inst_data = zir_datas[inst].pl_node;
......@@ -5046,9 +5058,9 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
50465058 // %b = store(%a, %c)
50475059 // Where %c is an error union or error set. In such case we need to add
50485060 // to the current function's inferred error set, if any.
5049 if (is_ret and (sema.typeOf(operand).zigTypeTag() == .ErrorUnion or
5050 sema.typeOf(operand).zigTypeTag() == .ErrorSet) and
5051 sema.fn_ret_ty.zigTypeTag() == .ErrorUnion)
5061 if (is_ret and (sema.typeOf(operand).zigTypeTag(mod) == .ErrorUnion or
5062 sema.typeOf(operand).zigTypeTag(mod) == .ErrorSet) and
5063 sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion)
50525064 {
50535065 try sema.addToInferredErrorSet(operand);
50545066 }
......@@ -6270,6 +6282,7 @@ fn zirCall(
62706282 const tracy = trace(@src());
62716283 defer tracy.end();
62726284
6285 const mod = sema.mod;
62736286 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
62746287 const callee_src: LazySrcLoc = .{ .node_offset_call_func = inst_data.src_node };
62756288 const call_src = inst_data.src();
......@@ -6342,7 +6355,7 @@ fn zirCall(
63426355
63436356 sema.inst_map.putAssumeCapacity(inst, inst: {
63446357 if (arg_index >= fn_params_len)
6345 break :inst Air.Inst.Ref.var_args_param;
6358 break :inst Air.Inst.Ref.var_args_param_type;
63466359
63476360 if (func_ty_info.param_types[arg_index].tag() == .generic_poison)
63486361 break :inst Air.Inst.Ref.generic_poison_type;
......@@ -6352,10 +6365,10 @@ fn zirCall(
63526365
63536366 const resolved = try sema.resolveBody(block, args_body[arg_start..arg_end], inst);
63546367 const resolved_ty = sema.typeOf(resolved);
6355 if (resolved_ty.zigTypeTag() == .NoReturn) {
6368 if (resolved_ty.zigTypeTag(mod) == .NoReturn) {
63566369 return resolved;
63576370 }
6358 if (resolved_ty.isError()) {
6371 if (resolved_ty.isError(mod)) {
63596372 input_is_error = true;
63606373 }
63616374 resolved_args[arg_index] = resolved;
......@@ -6380,7 +6393,7 @@ fn zirCall(
63806393
63816394 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
63826395 // need to clean-up our own trace if we were passed to a non-error-handling expression.
6383 if (input_is_error or (pop_error_return_trace and modifier != .always_tail and return_ty.isError())) {
6396 if (input_is_error or (pop_error_return_trace and modifier != .always_tail and return_ty.isError(mod))) {
63846397 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
63856398 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
63866399 const field_index = try sema.structFieldIndex(block, stack_trace_ty, "index", call_src);
......@@ -6417,20 +6430,21 @@ fn checkCallArgumentCount(
64176430 total_args: usize,
64186431 member_fn: bool,
64196432) !Type {
6433 const mod = sema.mod;
64206434 const func_ty = func_ty: {
6421 switch (callee_ty.zigTypeTag()) {
6435 switch (callee_ty.zigTypeTag(mod)) {
64226436 .Fn => break :func_ty callee_ty,
64236437 .Pointer => {
64246438 const ptr_info = callee_ty.ptrInfo().data;
6425 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag() == .Fn) {
6439 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) {
64266440 break :func_ty ptr_info.pointee_type;
64276441 }
64286442 },
64296443 .Optional => {
64306444 var buf: Type.Payload.ElemType = undefined;
64316445 const opt_child = callee_ty.optionalChild(&buf);
6432 if (opt_child.zigTypeTag() == .Fn or (opt_child.isSinglePointer() and
6433 opt_child.childType().zigTypeTag() == .Fn))
6446 if (opt_child.zigTypeTag(mod) == .Fn or (opt_child.isSinglePointer() and
6447 opt_child.childType().zigTypeTag(mod) == .Fn))
64346448 {
64356449 const msg = msg: {
64366450 const msg = try sema.errMsg(block, func_src, "cannot call optional type '{}'", .{
......@@ -6488,13 +6502,14 @@ fn callBuiltin(
64886502 modifier: std.builtin.CallModifier,
64896503 args: []const Air.Inst.Ref,
64906504) !void {
6505 const mod = sema.mod;
64916506 const callee_ty = sema.typeOf(builtin_fn);
64926507 const func_ty = func_ty: {
6493 switch (callee_ty.zigTypeTag()) {
6508 switch (callee_ty.zigTypeTag(mod)) {
64946509 .Fn => break :func_ty callee_ty,
64956510 .Pointer => {
64966511 const ptr_info = callee_ty.ptrInfo().data;
6497 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag() == .Fn) {
6512 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) {
64986513 break :func_ty ptr_info.pointee_type;
64996514 }
65006515 },
......@@ -6715,7 +6730,7 @@ fn analyzeCall(
67156730 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
67166731 }),
67176732 else => {
6718 assert(callee_ty.isPtrAtRuntime());
6733 assert(callee_ty.isPtrAtRuntime(mod));
67196734 return sema.fail(block, call_src, "{s} call of function pointer", .{
67206735 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
67216736 });
......@@ -6978,7 +6993,7 @@ fn analyzeCall(
69786993 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
69796994 };
69806995
6981 if (!is_comptime_call and !block.is_typeof and sema.typeOf(result).zigTypeTag() != .NoReturn) {
6996 if (!is_comptime_call and !block.is_typeof and sema.typeOf(result).zigTypeTag(mod) != .NoReturn) {
69826997 try sema.emitDbgInline(
69836998 block,
69846999 module_fn,
......@@ -7068,7 +7083,7 @@ fn analyzeCall(
70687083 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
70697084
70707085 try sema.queueFullTypeResolution(func_ty_info.return_type);
7071 if (sema.owner_func != null and func_ty_info.return_type.isError()) {
7086 if (sema.owner_func != null and func_ty_info.return_type.isError(mod)) {
70727087 sema.owner_func.?.calls_or_awaits_errorable_fn = true;
70737088 }
70747089
......@@ -7301,8 +7316,9 @@ fn analyzeGenericCallArg(
73017316 new_fn_info: Type.Payload.Function.Data,
73027317 runtime_i: *u32,
73037318) !void {
7319 const mod = sema.mod;
73047320 const is_runtime = comptime_arg.val.tag() == .generic_poison and
7305 comptime_arg.ty.hasRuntimeBits() and
7321 comptime_arg.ty.hasRuntimeBits(mod) and
73067322 !(try sema.typeRequiresComptime(comptime_arg.ty));
73077323 if (is_runtime) {
73087324 const param_ty = new_fn_info.param_types[runtime_i.*];
......@@ -7591,7 +7607,7 @@ fn instantiateGenericCall(
75917607
75927608 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
75937609
7594 if (sema.owner_func != null and new_fn_info.return_type.isError()) {
7610 if (sema.owner_func != null and new_fn_info.return_type.isError(mod)) {
75957611 sema.owner_func.?.calls_or_awaits_errorable_fn = true;
75967612 }
75977613
......@@ -7872,8 +7888,9 @@ fn zirIntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
78727888 const tracy = trace(@src());
78737889 defer tracy.end();
78747890
7891 const mod = sema.mod;
78757892 const int_type = sema.code.instructions.items(.data)[inst].int_type;
7876 const ty = try Module.makeIntType(sema.arena, int_type.signedness, int_type.bit_count);
7893 const ty = try mod.intType(int_type.signedness, int_type.bit_count);
78777894
78787895 return sema.addType(ty);
78797896}
......@@ -7882,12 +7899,13 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
78827899 const tracy = trace(@src());
78837900 defer tracy.end();
78847901
7902 const mod = sema.mod;
78857903 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
78867904 const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
78877905 const child_type = try sema.resolveType(block, operand_src, inst_data.operand);
7888 if (child_type.zigTypeTag() == .Opaque) {
7906 if (child_type.zigTypeTag(mod) == .Opaque) {
78897907 return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(sema.mod)});
7890 } else if (child_type.zigTypeTag() == .Null) {
7908 } else if (child_type.zigTypeTag(mod) == .Null) {
78917909 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(sema.mod)});
78927910 }
78937911 const opt_type = try Type.optional(sema.arena, child_type);
......@@ -7896,14 +7914,15 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
78967914}
78977915
78987916fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
7917 const mod = sema.mod;
78997918 const bin = sema.code.instructions.items(.data)[inst].bin;
79007919 const indexable_ty = try sema.resolveType(block, .unneeded, bin.lhs);
7901 assert(indexable_ty.isIndexable()); // validated by a previous instruction
7902 if (indexable_ty.zigTypeTag() == .Struct) {
7920 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction
7921 if (indexable_ty.zigTypeTag(mod) == .Struct) {
79037922 const elem_type = indexable_ty.structFieldType(@enumToInt(bin.rhs));
79047923 return sema.addType(elem_type);
79057924 } else {
7906 const elem_type = indexable_ty.elemType2();
7925 const elem_type = indexable_ty.elemType2(mod);
79077926 return sema.addType(elem_type);
79087927 }
79097928}
......@@ -7960,9 +7979,10 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
79607979}
79617980
79627981fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void {
7963 if (elem_type.zigTypeTag() == .Opaque) {
7982 const mod = sema.mod;
7983 if (elem_type.zigTypeTag(mod) == .Opaque) {
79647984 return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(sema.mod)});
7965 } else if (elem_type.zigTypeTag() == .NoReturn) {
7985 } else if (elem_type.zigTypeTag(mod) == .NoReturn) {
79667986 return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{});
79677987 }
79687988}
......@@ -7986,6 +8006,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
79868006 const tracy = trace(@src());
79878007 defer tracy.end();
79888008
8009 const mod = sema.mod;
79898010 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
79908011 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
79918012 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
......@@ -7993,7 +8014,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
79938014 const error_set = try sema.resolveType(block, lhs_src, extra.lhs);
79948015 const payload = try sema.resolveType(block, rhs_src, extra.rhs);
79958016
7996 if (error_set.zigTypeTag() != .ErrorSet) {
8017 if (error_set.zigTypeTag(mod) != .ErrorSet) {
79978018 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{
79988019 error_set.fmt(sema.mod),
79998020 });
......@@ -8004,11 +8025,12 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
80048025}
80058026
80068027fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, payload_src: LazySrcLoc) !void {
8007 if (payload_ty.zigTypeTag() == .Opaque) {
8028 const mod = sema.mod;
8029 if (payload_ty.zigTypeTag(mod) == .Opaque) {
80088030 return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{
80098031 payload_ty.fmt(sema.mod),
80108032 });
8011 } else if (payload_ty.zigTypeTag() == .ErrorSet) {
8033 } else if (payload_ty.zigTypeTag(mod) == .ErrorSet) {
80128034 return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{
80138035 payload_ty.fmt(sema.mod),
80148036 });
......@@ -8089,10 +8111,10 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
80898111 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
80908112 const uncasted_operand = try sema.resolveInst(extra.operand);
80918113 const operand = try sema.coerce(block, Type.err_int, uncasted_operand, operand_src);
8092 const target = sema.mod.getTarget();
8114 const mod = sema.mod;
80938115
80948116 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
8095 const int = try sema.usizeCast(block, operand_src, value.toUnsignedInt(target));
8117 const int = try sema.usizeCast(block, operand_src, value.toUnsignedInt(mod));
80968118 if (int > sema.mod.global_error_set.count() or int == 0)
80978119 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
80988120 const payload = try sema.arena.create(Value.Payload.Error);
......@@ -8123,6 +8145,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
81238145 const tracy = trace(@src());
81248146 defer tracy.end();
81258147
8148 const mod = sema.mod;
81268149 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
81278150 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
81288151 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
......@@ -8130,7 +8153,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
81308153 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
81318154 const lhs = try sema.resolveInst(extra.lhs);
81328155 const rhs = try sema.resolveInst(extra.rhs);
8133 if (sema.typeOf(lhs).zigTypeTag() == .Bool and sema.typeOf(rhs).zigTypeTag() == .Bool) {
8156 if (sema.typeOf(lhs).zigTypeTag(mod) == .Bool and sema.typeOf(rhs).zigTypeTag(mod) == .Bool) {
81348157 const msg = msg: {
81358158 const msg = try sema.errMsg(block, lhs_src, "expected error set type, found 'bool'", .{});
81368159 errdefer msg.destroy(sema.gpa);
......@@ -8141,9 +8164,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
81418164 }
81428165 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);
81438166 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);
8144 if (lhs_ty.zigTypeTag() != .ErrorSet)
8167 if (lhs_ty.zigTypeTag(mod) != .ErrorSet)
81458168 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(sema.mod)});
8146 if (rhs_ty.zigTypeTag() != .ErrorSet)
8169 if (rhs_ty.zigTypeTag(mod) != .ErrorSet)
81478170 return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(sema.mod)});
81488171
81498172 // Anything merged with anyerror is anyerror.
......@@ -8184,6 +8207,7 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
81848207}
81858208
81868209fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8210 const mod = sema.mod;
81878211 const arena = sema.arena;
81888212 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
81898213 const src = inst_data.src();
......@@ -8191,7 +8215,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
81918215 const operand = try sema.resolveInst(inst_data.operand);
81928216 const operand_ty = sema.typeOf(operand);
81938217
8194 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {
8218 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {
81958219 .Enum => operand,
81968220 .Union => blk: {
81978221 const union_ty = try sema.resolveTypeFields(operand_ty);
......@@ -8213,8 +8237,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
82138237 };
82148238 const enum_tag_ty = sema.typeOf(enum_tag);
82158239
8216 var int_tag_type_buffer: Type.Payload.Bits = undefined;
8217 const int_tag_ty = try enum_tag_ty.intTagType(&int_tag_type_buffer).copy(arena);
8240 const int_tag_ty = try enum_tag_ty.intTagType().copy(arena);
82188241
82198242 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {
82208243 return sema.addConstant(int_tag_ty, opv);
......@@ -8231,6 +8254,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
82318254}
82328255
82338256fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8257 const mod = sema.mod;
82348258 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
82358259 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
82368260 const src = inst_data.src();
......@@ -8239,15 +8263,14 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
82398263 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
82408264 const operand = try sema.resolveInst(extra.rhs);
82418265
8242 if (dest_ty.zigTypeTag() != .Enum) {
8266 if (dest_ty.zigTypeTag(mod) != .Enum) {
82438267 return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(sema.mod)});
82448268 }
82458269 _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));
82468270
82478271 if (try sema.resolveMaybeUndefVal(operand)) |int_val| {
82488272 if (dest_ty.isNonexhaustiveEnum()) {
8249 var buffer: Type.Payload.Bits = undefined;
8250 const int_tag_ty = dest_ty.intTagType(&buffer);
8273 const int_tag_ty = dest_ty.intTagType();
82518274 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
82528275 return sema.addConstant(dest_ty, int_val);
82538276 }
......@@ -8329,11 +8352,12 @@ fn analyzeOptionalPayloadPtr(
83298352 safety_check: bool,
83308353 initializing: bool,
83318354) CompileError!Air.Inst.Ref {
8355 const mod = sema.mod;
83328356 const optional_ptr_ty = sema.typeOf(optional_ptr);
8333 assert(optional_ptr_ty.zigTypeTag() == .Pointer);
8357 assert(optional_ptr_ty.zigTypeTag(mod) == .Pointer);
83348358
83358359 const opt_type = optional_ptr_ty.elemType();
8336 if (opt_type.zigTypeTag() != .Optional) {
8360 if (opt_type.zigTypeTag(mod) != .Optional) {
83378361 return sema.fail(block, src, "expected optional type, found '{}'", .{opt_type.fmt(sema.mod)});
83388362 }
83398363
......@@ -8361,7 +8385,7 @@ fn analyzeOptionalPayloadPtr(
83618385 );
83628386 }
83638387 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {
8364 if (val.isNull()) {
8388 if (val.isNull(mod)) {
83658389 return sema.fail(block, src, "unable to unwrap null", .{});
83668390 }
83678391 // The same Value represents the pointer to the optional and the payload.
......@@ -8397,11 +8421,12 @@ fn zirOptionalPayload(
83978421 const tracy = trace(@src());
83988422 defer tracy.end();
83998423
8424 const mod = sema.mod;
84008425 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
84018426 const src = inst_data.src();
84028427 const operand = try sema.resolveInst(inst_data.operand);
84038428 const operand_ty = sema.typeOf(operand);
8404 const result_ty = switch (operand_ty.zigTypeTag()) {
8429 const result_ty = switch (operand_ty.zigTypeTag(mod)) {
84058430 .Optional => try operand_ty.optionalChildAlloc(sema.arena),
84068431 .Pointer => t: {
84078432 if (operand_ty.ptrSize() != .C) {
......@@ -8424,7 +8449,7 @@ fn zirOptionalPayload(
84248449 };
84258450
84268451 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
8427 if (val.isNull()) {
8452 if (val.isNull(mod)) {
84288453 return sema.fail(block, src, "unable to unwrap null", .{});
84298454 }
84308455 if (val.castTag(.opt_payload)) |payload| {
......@@ -8450,12 +8475,13 @@ fn zirErrUnionPayload(
84508475 const tracy = trace(@src());
84518476 defer tracy.end();
84528477
8478 const mod = sema.mod;
84538479 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
84548480 const src = inst_data.src();
84558481 const operand = try sema.resolveInst(inst_data.operand);
84568482 const operand_src = src;
84578483 const err_union_ty = sema.typeOf(operand);
8458 if (err_union_ty.zigTypeTag() != .ErrorUnion) {
8484 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
84598485 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
84608486 err_union_ty.fmt(sema.mod),
84618487 });
......@@ -8468,7 +8494,7 @@ fn analyzeErrUnionPayload(
84688494 block: *Block,
84698495 src: LazySrcLoc,
84708496 err_union_ty: Type,
8471 operand: Zir.Inst.Ref,
8497 operand: Air.Inst.Ref,
84728498 operand_src: LazySrcLoc,
84738499 safety_check: bool,
84748500) CompileError!Air.Inst.Ref {
......@@ -8517,10 +8543,11 @@ fn analyzeErrUnionPayloadPtr(
85178543 safety_check: bool,
85188544 initializing: bool,
85198545) CompileError!Air.Inst.Ref {
8546 const mod = sema.mod;
85208547 const operand_ty = sema.typeOf(operand);
8521 assert(operand_ty.zigTypeTag() == .Pointer);
8548 assert(operand_ty.zigTypeTag(mod) == .Pointer);
85228549
8523 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {
8550 if (operand_ty.elemType().zigTypeTag(mod) != .ErrorUnion) {
85248551 return sema.fail(block, src, "expected error union type, found '{}'", .{
85258552 operand_ty.elemType().fmt(sema.mod),
85268553 });
......@@ -8594,8 +8621,9 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
85948621}
85958622
85968623fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {
8624 const mod = sema.mod;
85978625 const operand_ty = sema.typeOf(operand);
8598 if (operand_ty.zigTypeTag() != .ErrorUnion) {
8626 if (operand_ty.zigTypeTag(mod) != .ErrorUnion) {
85998627 return sema.fail(block, src, "expected error union type, found '{}'", .{
86008628 operand_ty.fmt(sema.mod),
86018629 });
......@@ -8617,13 +8645,14 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
86178645 const tracy = trace(@src());
86188646 defer tracy.end();
86198647
8648 const mod = sema.mod;
86208649 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
86218650 const src = inst_data.src();
86228651 const operand = try sema.resolveInst(inst_data.operand);
86238652 const operand_ty = sema.typeOf(operand);
8624 assert(operand_ty.zigTypeTag() == .Pointer);
8653 assert(operand_ty.zigTypeTag(mod) == .Pointer);
86258654
8626 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {
8655 if (operand_ty.elemType().zigTypeTag(mod) != .ErrorUnion) {
86278656 return sema.fail(block, src, "expected error union type, found '{}'", .{
86288657 operand_ty.elemType().fmt(sema.mod),
86298658 });
......@@ -8677,8 +8706,7 @@ fn zirFunc(
86778706 extra_index += ret_ty_body.len;
86788707
86798708 const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, Type.type, "return type must be comptime-known");
8680 var buffer: Value.ToTypeBuffer = undefined;
8681 break :blk try ret_ty_val.toType(&buffer).copy(sema.arena);
8709 break :blk try ret_ty_val.toType().copy(sema.arena);
86828710 },
86838711 };
86848712
......@@ -8849,6 +8877,7 @@ fn funcCommon(
88498877 noalias_bits: u32,
88508878 is_noinline: bool,
88518879) CompileError!Air.Inst.Ref {
8880 const mod = sema.mod;
88528881 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
88538882 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };
88548883 const func_src = LazySrcLoc.nodeOffset(src_node_offset);
......@@ -8890,31 +8919,6 @@ fn funcCommon(
88908919
88918920 const target = sema.mod.getTarget();
88928921 const fn_ty: Type = fn_ty: {
8893 // Hot path for some common function types.
8894 // TODO can we eliminate some of these Type tag values? seems unnecessarily complicated.
8895 if (!is_generic and block.params.items.len == 0 and !var_args and !inferred_error_set and
8896 alignment.? == 0 and
8897 address_space.? == target_util.defaultAddressSpace(target, .function) and
8898 section == .default and
8899 !is_noinline)
8900 {
8901 if (bare_return_type.zigTypeTag() == .NoReturn and cc.? == .Unspecified) {
8902 break :fn_ty Type.initTag(.fn_noreturn_no_args);
8903 }
8904
8905 if (bare_return_type.zigTypeTag() == .Void and cc.? == .Unspecified) {
8906 break :fn_ty Type.initTag(.fn_void_no_args);
8907 }
8908
8909 if (bare_return_type.zigTypeTag() == .NoReturn and cc.? == .Naked) {
8910 break :fn_ty Type.initTag(.fn_naked_noreturn_no_args);
8911 }
8912
8913 if (bare_return_type.zigTypeTag() == .Void and cc.? == .C) {
8914 break :fn_ty Type.initTag(.fn_ccc_void_no_args);
8915 }
8916 }
8917
89188922 // In the case of generic calling convention, or generic alignment, we use
89198923 // default values which are only meaningful for the generic function, *not*
89208924 // the instantiation, which can depend on comptime parameters.
......@@ -8985,8 +8989,8 @@ fn funcCommon(
89858989 });
89868990 };
89878991
8988 if (!return_type.isValidReturnType()) {
8989 const opaque_str = if (return_type.zigTypeTag() == .Opaque) "opaque " else "";
8992 if (!return_type.isValidReturnType(mod)) {
8993 const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else "";
89908994 const msg = msg: {
89918995 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{
89928996 opaque_str, return_type.fmt(sema.mod),
......@@ -9201,22 +9205,23 @@ fn analyzeParameter(
92019205 has_body: bool,
92029206 is_noalias: bool,
92039207) !void {
9208 const mod = sema.mod;
92049209 const requires_comptime = try sema.typeRequiresComptime(param.ty);
92059210 comptime_params[i] = param.is_comptime or requires_comptime;
92069211 const this_generic = param.ty.tag() == .generic_poison;
92079212 is_generic.* = is_generic.* or this_generic;
9208 const target = sema.mod.getTarget();
9213 const target = mod.getTarget();
92099214 if (param.is_comptime and !Type.fnCallingConventionAllowsZigTypes(target, cc)) {
92109215 return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});
92119216 }
92129217 if (this_generic and !sema.no_partial_func_ty and !Type.fnCallingConventionAllowsZigTypes(target, cc)) {
92139218 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});
92149219 }
9215 if (!param.ty.isValidParamType()) {
9216 const opaque_str = if (param.ty.zigTypeTag() == .Opaque) "opaque " else "";
9220 if (!param.ty.isValidParamType(mod)) {
9221 const opaque_str = if (param.ty.zigTypeTag(mod) == .Opaque) "opaque " else "";
92179222 const msg = msg: {
92189223 const msg = try sema.errMsg(block, param_src, "parameter of {s}type '{}' not allowed", .{
9219 opaque_str, param.ty.fmt(sema.mod),
9224 opaque_str, param.ty.fmt(mod),
92209225 });
92219226 errdefer msg.destroy(sema.gpa);
92229227
......@@ -9228,11 +9233,11 @@ fn analyzeParameter(
92289233 if (!this_generic and !Type.fnCallingConventionAllowsZigTypes(target, cc) and !try sema.validateExternType(param.ty, .param_ty)) {
92299234 const msg = msg: {
92309235 const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{
9231 param.ty.fmt(sema.mod), @tagName(cc),
9236 param.ty.fmt(mod), @tagName(cc),
92329237 });
92339238 errdefer msg.destroy(sema.gpa);
92349239
9235 const src_decl = sema.mod.declPtr(block.src_decl);
9240 const src_decl = mod.declPtr(block.src_decl);
92369241 try sema.explainWhyTypeIsNotExtern(msg, param_src.toSrcLoc(src_decl), param.ty, .param_ty);
92379242
92389243 try sema.addDeclaredHereNote(msg, param.ty);
......@@ -9243,11 +9248,11 @@ fn analyzeParameter(
92439248 if (!sema.is_generic_instantiation and requires_comptime and !param.is_comptime and has_body) {
92449249 const msg = msg: {
92459250 const msg = try sema.errMsg(block, param_src, "parameter of type '{}' must be declared comptime", .{
9246 param.ty.fmt(sema.mod),
9251 param.ty.fmt(mod),
92479252 });
92489253 errdefer msg.destroy(sema.gpa);
92499254
9250 const src_decl = sema.mod.declPtr(block.src_decl);
9255 const src_decl = mod.declPtr(block.src_decl);
92519256 try sema.explainWhyTypeIsComptime(msg, param_src.toSrcLoc(src_decl), param.ty);
92529257
92539258 try sema.addDeclaredHereNote(msg, param.ty);
......@@ -9256,7 +9261,7 @@ fn analyzeParameter(
92569261 return sema.failWithOwnedErrorMsg(msg);
92579262 }
92589263 if (!sema.is_generic_instantiation and !this_generic and is_noalias and
9259 !(param.ty.zigTypeTag() == .Pointer or param.ty.isPtrLikeOptional()))
9264 !(param.ty.zigTypeTag(mod) == .Pointer or param.ty.isPtrLikeOptional(mod)))
92609265 {
92619266 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});
92629267 }
......@@ -9472,13 +9477,14 @@ fn analyzeAs(
94729477 zir_operand: Zir.Inst.Ref,
94739478 no_cast_to_comptime_int: bool,
94749479) CompileError!Air.Inst.Ref {
9480 const mod = sema.mod;
94759481 const operand = try sema.resolveInst(zir_operand);
9476 if (zir_dest_type == .var_args_param) return operand;
9482 if (zir_dest_type == .var_args_param_type) return operand;
94779483 const dest_ty = sema.resolveType(block, src, zir_dest_type) catch |err| switch (err) {
94789484 error.GenericPoison => return operand,
94799485 else => |e| return e,
94809486 };
9481 if (dest_ty.zigTypeTag() == .NoReturn) {
9487 if (dest_ty.zigTypeTag(mod) == .NoReturn) {
94829488 return sema.fail(block, src, "cannot cast to noreturn", .{});
94839489 }
94849490 const is_ret = if (Zir.refToIndex(zir_dest_type)) |ptr_index|
......@@ -9495,11 +9501,12 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
94959501 const tracy = trace(@src());
94969502 defer tracy.end();
94979503
9504 const mod = sema.mod;
94989505 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
94999506 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
95009507 const ptr = try sema.resolveInst(inst_data.operand);
95019508 const ptr_ty = sema.typeOf(ptr);
9502 if (!ptr_ty.isPtrAtRuntime()) {
9509 if (!ptr_ty.isPtrAtRuntime(mod)) {
95039510 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)});
95049511 }
95059512 if (try sema.resolveMaybeUndefValIntable(ptr)) |ptr_val| {
......@@ -9586,25 +9593,25 @@ fn intCast(
95869593 operand_src: LazySrcLoc,
95879594 runtime_safety: bool,
95889595) CompileError!Air.Inst.Ref {
9596 const mod = sema.mod;
95899597 const operand_ty = sema.typeOf(operand);
95909598 const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, dest_ty_src);
95919599 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);
95929600
95939601 if (try sema.isComptimeKnown(operand)) {
95949602 return sema.coerce(block, dest_ty, operand, operand_src);
9595 } else if (dest_scalar_ty.zigTypeTag() == .ComptimeInt) {
9603 } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
95969604 return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_int'", .{});
95979605 }
95989606
95999607 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, dest_ty_src, operand_src);
9600 const is_vector = dest_ty.zigTypeTag() == .Vector;
9608 const is_vector = dest_ty.zigTypeTag(mod) == .Vector;
96019609
96029610 if ((try sema.typeHasOnePossibleValue(dest_ty))) |opv| {
96039611 // requirement: intCast(u0, input) iff input == 0
96049612 if (runtime_safety and block.wantSafety()) {
96059613 try sema.requireRuntimeBlock(block, src, operand_src);
9606 const target = sema.mod.getTarget();
9607 const wanted_info = dest_scalar_ty.intInfo(target);
9614 const wanted_info = dest_scalar_ty.intInfo(mod);
96089615 const wanted_bits = wanted_info.bits;
96099616
96109617 if (wanted_bits == 0) {
......@@ -9631,9 +9638,8 @@ fn intCast(
96319638
96329639 try sema.requireRuntimeBlock(block, src, operand_src);
96339640 if (runtime_safety and block.wantSafety()) {
9634 const target = sema.mod.getTarget();
9635 const actual_info = operand_scalar_ty.intInfo(target);
9636 const wanted_info = dest_scalar_ty.intInfo(target);
9641 const actual_info = operand_scalar_ty.intInfo(mod);
9642 const wanted_info = dest_scalar_ty.intInfo(mod);
96379643 const actual_bits = actual_info.bits;
96389644 const wanted_bits = wanted_info.bits;
96399645 const actual_value_bits = actual_bits - @boolToInt(actual_info.signedness == .signed);
......@@ -9642,7 +9648,7 @@ fn intCast(
96429648 // range shrinkage
96439649 // requirement: int value fits into target type
96449650 if (wanted_value_bits < actual_value_bits) {
9645 const dest_max_val_scalar = try dest_scalar_ty.maxInt(sema.arena, target);
9651 const dest_max_val_scalar = try dest_scalar_ty.maxInt(sema.arena, mod);
96469652 const dest_max_val = if (is_vector)
96479653 try Value.Tag.repeated.create(sema.arena, dest_max_val_scalar)
96489654 else
......@@ -9653,7 +9659,7 @@ fn intCast(
96539659 if (actual_info.signedness == .signed) {
96549660 // Reinterpret the sign-bit as part of the value. This will make
96559661 // negative differences (`operand` > `dest_max`) appear too big.
9656 const unsigned_operand_ty = try Type.Tag.int_unsigned.create(sema.arena, actual_bits);
9662 const unsigned_operand_ty = try mod.intType(.unsigned, actual_bits);
96579663 const diff_unsigned = try block.addBitCast(unsigned_operand_ty, diff);
96589664
96599665 // If the destination type is signed, then we need to double its
......@@ -9727,6 +9733,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
97279733 const tracy = trace(@src());
97289734 defer tracy.end();
97299735
9736 const mod = sema.mod;
97309737 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
97319738 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
97329739 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
......@@ -9735,7 +9742,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
97359742 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
97369743 const operand = try sema.resolveInst(extra.rhs);
97379744 const operand_ty = sema.typeOf(operand);
9738 switch (dest_ty.zigTypeTag()) {
9745 switch (dest_ty.zigTypeTag(mod)) {
97399746 .AnyFrame,
97409747 .ComptimeFloat,
97419748 .ComptimeInt,
......@@ -9757,7 +9764,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
97579764 const msg = msg: {
97589765 const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});
97599766 errdefer msg.destroy(sema.gpa);
9760 switch (operand_ty.zigTypeTag()) {
9767 switch (operand_ty.zigTypeTag(mod)) {
97619768 .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToEnum to cast from '{}'", .{operand_ty.fmt(sema.mod)}),
97629769 else => {},
97639770 }
......@@ -9771,7 +9778,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
97719778 const msg = msg: {
97729779 const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});
97739780 errdefer msg.destroy(sema.gpa);
9774 switch (operand_ty.zigTypeTag()) {
9781 switch (operand_ty.zigTypeTag(mod)) {
97759782 .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToPtr to cast from '{}'", .{operand_ty.fmt(sema.mod)}),
97769783 .Pointer => try sema.errNote(block, dest_ty_src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(sema.mod)}),
97779784 else => {},
......@@ -9782,7 +9789,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
97829789 return sema.failWithOwnedErrorMsg(msg);
97839790 },
97849791 .Struct, .Union => if (dest_ty.containerLayout() == .Auto) {
9785 const container = switch (dest_ty.zigTypeTag()) {
9792 const container = switch (dest_ty.zigTypeTag(mod)) {
97869793 .Struct => "struct",
97879794 .Union => "union",
97889795 else => unreachable,
......@@ -9799,7 +9806,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
97999806 .Vector,
98009807 => {},
98019808 }
9802 switch (operand_ty.zigTypeTag()) {
9809 switch (operand_ty.zigTypeTag(mod)) {
98039810 .AnyFrame,
98049811 .ComptimeFloat,
98059812 .ComptimeInt,
......@@ -9821,7 +9828,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
98219828 const msg = msg: {
98229829 const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)});
98239830 errdefer msg.destroy(sema.gpa);
9824 switch (dest_ty.zigTypeTag()) {
9831 switch (dest_ty.zigTypeTag(mod)) {
98259832 .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @enumToInt to cast to '{}'", .{dest_ty.fmt(sema.mod)}),
98269833 else => {},
98279834 }
......@@ -9834,7 +9841,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
98349841 const msg = msg: {
98359842 const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)});
98369843 errdefer msg.destroy(sema.gpa);
9837 switch (dest_ty.zigTypeTag()) {
9844 switch (dest_ty.zigTypeTag(mod)) {
98389845 .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @ptrToInt to cast to '{}'", .{dest_ty.fmt(sema.mod)}),
98399846 .Pointer => try sema.errNote(block, operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(sema.mod)}),
98409847 else => {},
......@@ -9845,7 +9852,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
98459852 return sema.failWithOwnedErrorMsg(msg);
98469853 },
98479854 .Struct, .Union => if (operand_ty.containerLayout() == .Auto) {
9848 const container = switch (operand_ty.zigTypeTag()) {
9855 const container = switch (operand_ty.zigTypeTag(mod)) {
98499856 .Struct => "struct",
98509857 .Union => "union",
98519858 else => unreachable,
......@@ -9869,6 +9876,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
98699876 const tracy = trace(@src());
98709877 defer tracy.end();
98719878
9879 const mod = sema.mod;
98729880 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
98739881 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
98749882 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
......@@ -9878,7 +9886,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
98789886 const operand = try sema.resolveInst(extra.rhs);
98799887
98809888 const target = sema.mod.getTarget();
9881 const dest_is_comptime_float = switch (dest_ty.zigTypeTag()) {
9889 const dest_is_comptime_float = switch (dest_ty.zigTypeTag(mod)) {
98829890 .ComptimeFloat => true,
98839891 .Float => false,
98849892 else => return sema.fail(
......@@ -9890,7 +9898,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
98909898 };
98919899
98929900 const operand_ty = sema.typeOf(operand);
9893 switch (operand_ty.zigTypeTag()) {
9901 switch (operand_ty.zigTypeTag(mod)) {
98949902 .ComptimeFloat, .Float, .ComptimeInt => {},
98959903 else => return sema.fail(
98969904 block,
......@@ -9944,20 +9952,21 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
99449952 const tracy = trace(@src());
99459953 defer tracy.end();
99469954
9955 const mod = sema.mod;
99479956 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
99489957 const src = inst_data.src();
99499958 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
99509959 const array_ptr = try sema.resolveInst(extra.lhs);
99519960 const elem_index = try sema.resolveInst(extra.rhs);
99529961 const indexable_ty = sema.typeOf(array_ptr);
9953 if (indexable_ty.zigTypeTag() != .Pointer) {
9962 if (indexable_ty.zigTypeTag(mod) != .Pointer) {
99549963 const capture_src: LazySrcLoc = .{ .for_capture_from_input = inst_data.src_node };
99559964 const msg = msg: {
99569965 const msg = try sema.errMsg(block, capture_src, "pointer capture of non pointer type '{}'", .{
99579966 indexable_ty.fmt(sema.mod),
99589967 });
99599968 errdefer msg.destroy(sema.gpa);
9960 if (indexable_ty.zigTypeTag() == .Array) {
9969 if (indexable_ty.zigTypeTag(mod) == .Array) {
99619970 try sema.errNote(block, src, msg, "consider using '&' here", .{});
99629971 }
99639972 break :msg msg;
......@@ -10076,6 +10085,7 @@ fn zirSwitchCapture(
1007610085 const tracy = trace(@src());
1007710086 defer tracy.end();
1007810087
10088 const mod = sema.mod;
1007910089 const zir_datas = sema.code.instructions.items(.data);
1008010090 const capture_info = zir_datas[inst].switch_capture;
1008110091 const switch_info = zir_datas[capture_info.switch_inst].pl_node;
......@@ -10091,7 +10101,7 @@ fn zirSwitchCapture(
1009110101
1009210102 if (block.inline_case_capture != .none) {
1009310103 const item_val = sema.resolveConstValue(block, .unneeded, block.inline_case_capture, undefined) catch unreachable;
10094 if (operand_ty.zigTypeTag() == .Union) {
10104 if (operand_ty.zigTypeTag(mod) == .Union) {
1009510105 const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, sema.mod).?);
1009610106 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
1009710107 const field_ty = union_obj.fields.values()[field_index].ty;
......@@ -10144,7 +10154,7 @@ fn zirSwitchCapture(
1014410154 return operand_ptr;
1014510155 }
1014610156
10147 switch (operand_ty.zigTypeTag()) {
10157 switch (operand_ty.zigTypeTag(mod)) {
1014810158 .ErrorSet => if (block.switch_else_err_ty) |some| {
1014910159 return sema.bitCast(block, some, operand, operand_src, null);
1015010160 } else {
......@@ -10162,7 +10172,7 @@ fn zirSwitchCapture(
1016210172 switch_extra.data.getScalarProng(sema.code, switch_extra.end, capture_info.prong_index).item,
1016310173 };
1016410174
10165 switch (operand_ty.zigTypeTag()) {
10175 switch (operand_ty.zigTypeTag(mod)) {
1016610176 .Union => {
1016710177 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
1016810178 const first_item = try sema.resolveInst(items[0]);
......@@ -10269,6 +10279,7 @@ fn zirSwitchCapture(
1026910279}
1027010280
1027110281fn zirSwitchCaptureTag(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
10282 const mod = sema.mod;
1027210283 const zir_datas = sema.code.instructions.items(.data);
1027310284 const inst_data = zir_datas[inst].un_tok;
1027410285 const src = inst_data.src();
......@@ -10280,7 +10291,7 @@ fn zirSwitchCaptureTag(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
1028010291 const operand_ptr_ty = sema.typeOf(operand_ptr);
1028110292 const operand_ty = if (is_ref) operand_ptr_ty.childType() else operand_ptr_ty;
1028210293
10283 if (operand_ty.zigTypeTag() != .Union) {
10294 if (operand_ty.zigTypeTag(mod) != .Union) {
1028410295 const msg = msg: {
1028510296 const msg = try sema.errMsg(block, src, "cannot capture tag of non-union type '{}'", .{
1028610297 operand_ty.fmt(sema.mod),
......@@ -10301,6 +10312,7 @@ fn zirSwitchCond(
1030110312 inst: Zir.Inst.Index,
1030210313 is_ref: bool,
1030310314) CompileError!Air.Inst.Ref {
10315 const mod = sema.mod;
1030410316 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1030510317 const src = inst_data.src();
1030610318 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = inst_data.src_node };
......@@ -10311,7 +10323,7 @@ fn zirSwitchCond(
1031110323 operand_ptr;
1031210324 const operand_ty = sema.typeOf(operand);
1031310325
10314 switch (operand_ty.zigTypeTag()) {
10326 switch (operand_ty.zigTypeTag(mod)) {
1031510327 .Type,
1031610328 .Void,
1031710329 .Bool,
......@@ -10371,6 +10383,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1037110383 const tracy = trace(@src());
1037210384 defer tracy.end();
1037310385
10386 const mod = sema.mod;
1037410387 const gpa = sema.gpa;
1037510388 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1037610389 const src = inst_data.src();
......@@ -10415,7 +10428,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1041510428 const target_ty = sema.typeOf(raw_operand);
1041610429 break :blk if (zir_tags[cond_index] == .switch_cond_ref) target_ty.elemType() else target_ty;
1041710430 };
10418 const union_originally = maybe_union_ty.zigTypeTag() == .Union;
10431 const union_originally = maybe_union_ty.zigTypeTag(mod) == .Union;
1041910432
1042010433 // Duplicate checking variables later also used for `inline else`.
1042110434 var seen_enum_fields: []?Module.SwitchProngSrc = &.{};
......@@ -10433,7 +10446,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1043310446 var empty_enum = false;
1043410447
1043510448 const operand_ty = sema.typeOf(operand);
10436 const err_set = operand_ty.zigTypeTag() == .ErrorSet;
10449 const err_set = operand_ty.zigTypeTag(mod) == .ErrorSet;
1043710450
1043810451 var else_error_ty: ?Type = null;
1043910452
......@@ -10459,10 +10472,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1045910472 return sema.failWithOwnedErrorMsg(msg);
1046010473 }
1046110474
10462 const target = sema.mod.getTarget();
10463
1046410475 // Validate for duplicate items, missing else prong, and invalid range.
10465 switch (operand_ty.zigTypeTag()) {
10476 switch (operand_ty.zigTypeTag(mod)) {
1046610477 .Union => unreachable, // handled in zirSwitchCond
1046710478 .Enum => {
1046810479 seen_enum_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount());
......@@ -10774,12 +10785,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1077410785 }
1077510786
1077610787 check_range: {
10777 if (operand_ty.zigTypeTag() == .Int) {
10788 if (operand_ty.zigTypeTag(mod) == .Int) {
1077810789 var arena = std.heap.ArenaAllocator.init(gpa);
1077910790 defer arena.deinit();
1078010791
10781 const min_int = try operand_ty.minInt(arena.allocator(), target);
10782 const max_int = try operand_ty.maxInt(arena.allocator(), target);
10792 const min_int = try operand_ty.minInt(arena.allocator(), mod);
10793 const max_int = try operand_ty.maxInt(arena.allocator(), mod);
1078310794 if (try range_set.spans(min_int, max_int, operand_ty)) {
1078410795 if (special_prong == .@"else") {
1078510796 return sema.fail(
......@@ -11080,7 +11091,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1108011091 if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) {
1108111092 return Air.Inst.Ref.unreachable_value;
1108211093 }
11083 if (sema.mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag() == .Enum and
11094 if (sema.mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag(mod) == .Enum and
1108411095 (!operand_ty.isNonexhaustiveEnum() or union_originally))
1108511096 {
1108611097 try sema.zirDbgStmt(block, cond_dbg_node_index);
......@@ -11135,7 +11146,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1113511146 const analyze_body = if (union_originally) blk: {
1113611147 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;
1113711148 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);
11138 break :blk field_ty.zigTypeTag() != .NoReturn;
11149 break :blk field_ty.zigTypeTag(mod) != .NoReturn;
1113911150 } else true;
1114011151
1114111152 if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) {
......@@ -11242,7 +11253,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1124211253 const analyze_body = if (union_originally) blk: {
1124311254 const item_val = sema.resolveConstValue(block, .unneeded, item, undefined) catch unreachable;
1124411255 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);
11245 break :blk field_ty.zigTypeTag() != .NoReturn;
11256 break :blk field_ty.zigTypeTag(mod) != .NoReturn;
1124611257 } else true;
1124711258
1124811259 if (emit_bb) sema.emitBackwardBranch(block, .unneeded) catch |err| switch (err) {
......@@ -11286,7 +11297,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1128611297 const item = try sema.resolveInst(item_ref);
1128711298 const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable;
1128811299 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);
11289 if (field_ty.zigTypeTag() != .NoReturn) break true;
11300 if (field_ty.zigTypeTag(mod) != .NoReturn) break true;
1129011301 } else false
1129111302 else
1129211303 true;
......@@ -11409,7 +11420,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1140911420 var final_else_body: []const Air.Inst.Index = &.{};
1141011421 if (special.body.len != 0 or !is_first or case_block.wantSafety()) {
1141111422 var emit_bb = false;
11412 if (special.is_inline) switch (operand_ty.zigTypeTag()) {
11423 if (special.is_inline) switch (operand_ty.zigTypeTag(mod)) {
1141311424 .Enum => {
1141411425 if (operand_ty.isNonexhaustiveEnum() and !union_originally) {
1141511426 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
......@@ -11429,7 +11440,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1142911440
1143011441 const analyze_body = if (union_originally) blk: {
1143111442 const field_ty = maybe_union_ty.unionFieldType(item_val, sema.mod);
11432 break :blk field_ty.zigTypeTag() != .NoReturn;
11443 break :blk field_ty.zigTypeTag(mod) != .NoReturn;
1143311444 } else true;
1143411445
1143511446 if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src);
......@@ -11551,7 +11562,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1155111562 case_block.inline_case_capture = .none;
1155211563
1155311564 if (sema.mod.backendSupportsFeature(.is_named_enum_value) and special.body.len != 0 and block.wantSafety() and
11554 operand_ty.zigTypeTag() == .Enum and (!operand_ty.isNonexhaustiveEnum() or union_originally))
11565 operand_ty.zigTypeTag(mod) == .Enum and (!operand_ty.isNonexhaustiveEnum() or union_originally))
1155511566 {
1155611567 try sema.zirDbgStmt(&case_block, cond_dbg_node_index);
1155711568 const ok = try case_block.addUnOp(.is_named_enum_value, operand);
......@@ -11563,7 +11574,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1156311574 if (seen_field != null) continue;
1156411575 const union_obj = maybe_union_ty.cast(Type.Payload.Union).?.data;
1156511576 const field_ty = union_obj.fields.values()[index].ty;
11566 if (field_ty.zigTypeTag() != .NoReturn) break true;
11577 if (field_ty.zigTypeTag(mod) != .NoReturn) break true;
1156711578 } else false
1156811579 else
1156911580 true;
......@@ -11629,9 +11640,9 @@ const RangeSetUnhandledIterator = struct {
1162911640 first: bool = true,
1163011641
1163111642 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {
11632 const target = sema.mod.getTarget();
11633 const min = try ty.minInt(sema.arena, target);
11634 const max = try ty.maxInt(sema.arena, target);
11643 const mod = sema.mod;
11644 const min = try ty.minInt(sema.arena, mod);
11645 const max = try ty.maxInt(sema.arena, mod);
1163511646
1163611647 return RangeSetUnhandledIterator{
1163711648 .sema = sema,
......@@ -11931,18 +11942,19 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
1193111942}
1193211943
1193311944fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void {
11945 const mod = sema.mod;
1193411946 const index = Zir.refToIndex(cond) orelse return;
1193511947 if (sema.code.instructions.items(.tag)[index] != .is_non_err) return;
1193611948
1193711949 const err_inst_data = sema.code.instructions.items(.data)[index].un_node;
1193811950 const err_operand = try sema.resolveInst(err_inst_data.operand);
1193911951 const operand_ty = sema.typeOf(err_operand);
11940 if (operand_ty.zigTypeTag() == .ErrorSet) {
11952 if (operand_ty.zigTypeTag(mod) == .ErrorSet) {
1194111953 try sema.maybeErrorUnwrapComptime(block, body, err_operand);
1194211954 return;
1194311955 }
1194411956 if (try sema.resolveDefinedValue(block, cond_src, err_operand)) |val| {
11945 if (!operand_ty.isError()) return;
11957 if (!operand_ty.isError(mod)) return;
1194611958 if (val.getError() == null) return;
1194711959 try sema.maybeErrorUnwrapComptime(block, body, err_operand);
1194811960 }
......@@ -11972,6 +11984,7 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I
1197211984}
1197311985
1197411986fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
11987 const mod = sema.mod;
1197511988 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1197611989 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1197711990 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
......@@ -11995,7 +12008,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1199512008 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch break :hf false;
1199612009 break :hf field_index < ty.structFieldCount();
1199712010 }
11998 break :hf switch (ty.zigTypeTag()) {
12011 break :hf switch (ty.zigTypeTag(mod)) {
1199912012 .Struct => ty.structFields().contains(field_name),
1200012013 .Union => ty.unionFields().contains(field_name),
1200112014 .Enum => ty.enumFields().contains(field_name),
......@@ -12126,6 +12139,7 @@ fn zirShl(
1212612139 const tracy = trace(@src());
1212712140 defer tracy.end();
1212812141
12142 const mod = sema.mod;
1212912143 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1213012144 const src = inst_data.src();
1213112145 sema.src = src;
......@@ -12136,11 +12150,10 @@ fn zirShl(
1213612150 const rhs = try sema.resolveInst(extra.rhs);
1213712151 const lhs_ty = sema.typeOf(lhs);
1213812152 const rhs_ty = sema.typeOf(rhs);
12139 const target = sema.mod.getTarget();
1214012153 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1214112154
12142 const scalar_ty = lhs_ty.scalarType();
12143 const scalar_rhs_ty = rhs_ty.scalarType();
12155 const scalar_ty = lhs_ty.scalarType(mod);
12156 const scalar_rhs_ty = rhs_ty.scalarType(mod);
1214412157
1214512158 // TODO coerce rhs if air_tag is not shl_sat
1214612159 const rhs_is_comptime_int = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);
......@@ -12156,18 +12169,18 @@ fn zirShl(
1215612169 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1215712170 return lhs;
1215812171 }
12159 if (scalar_ty.zigTypeTag() != .ComptimeInt and air_tag != .shl_sat) {
12172 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) {
1216012173 var bits_payload = Value.Payload.U64{
1216112174 .base = .{ .tag = .int_u64 },
12162 .data = scalar_ty.intInfo(target).bits,
12175 .data = scalar_ty.intInfo(mod).bits,
1216312176 };
1216412177 const bit_value = Value.initPayload(&bits_payload.base);
12165 if (rhs_ty.zigTypeTag() == .Vector) {
12178 if (rhs_ty.zigTypeTag(mod) == .Vector) {
1216612179 var i: usize = 0;
1216712180 while (i < rhs_ty.vectorLen()) : (i += 1) {
1216812181 var elem_value_buf: Value.ElemValueBuffer = undefined;
1216912182 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);
12170 if (rhs_elem.compareHetero(.gte, bit_value, target)) {
12183 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {
1217112184 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
1217212185 rhs_elem.fmtValue(scalar_ty, sema.mod),
1217312186 i,
......@@ -12175,26 +12188,26 @@ fn zirShl(
1217512188 });
1217612189 }
1217712190 }
12178 } else if (rhs_val.compareHetero(.gte, bit_value, target)) {
12191 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {
1217912192 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
1218012193 rhs_val.fmtValue(scalar_ty, sema.mod),
1218112194 scalar_ty.fmt(sema.mod),
1218212195 });
1218312196 }
1218412197 }
12185 if (rhs_ty.zigTypeTag() == .Vector) {
12198 if (rhs_ty.zigTypeTag(mod) == .Vector) {
1218612199 var i: usize = 0;
1218712200 while (i < rhs_ty.vectorLen()) : (i += 1) {
1218812201 var elem_value_buf: Value.ElemValueBuffer = undefined;
1218912202 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);
12190 if (rhs_elem.compareHetero(.lt, Value.zero, target)) {
12203 if (rhs_elem.compareHetero(.lt, Value.zero, mod)) {
1219112204 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
1219212205 rhs_elem.fmtValue(scalar_ty, sema.mod),
1219312206 i,
1219412207 });
1219512208 }
1219612209 }
12197 } else if (rhs_val.compareHetero(.lt, Value.zero, target)) {
12210 } else if (rhs_val.compareHetero(.lt, Value.zero, mod)) {
1219812211 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
1219912212 rhs_val.fmtValue(scalar_ty, sema.mod),
1220012213 });
......@@ -12204,7 +12217,7 @@ fn zirShl(
1220412217 const runtime_src = if (maybe_lhs_val) |lhs_val| rs: {
1220512218 if (lhs_val.isUndef()) return sema.addConstUndef(lhs_ty);
1220612219 const rhs_val = maybe_rhs_val orelse {
12207 if (scalar_ty.zigTypeTag() == .ComptimeInt) {
12220 if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
1220812221 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});
1220912222 }
1221012223 break :rs rhs_src;
......@@ -12213,7 +12226,7 @@ fn zirShl(
1221312226 const val = switch (air_tag) {
1221412227 .shl_exact => val: {
1221512228 const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, sema.mod);
12216 if (scalar_ty.zigTypeTag() == .ComptimeInt) {
12229 if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
1221712230 break :val shifted.wrapped_result;
1221812231 }
1221912232 if (shifted.overflow_bit.compareAllWithZero(.eq, sema.mod)) {
......@@ -12222,12 +12235,12 @@ fn zirShl(
1222212235 return sema.fail(block, src, "operation caused overflow", .{});
1222312236 },
1222412237
12225 .shl_sat => if (scalar_ty.zigTypeTag() == .ComptimeInt)
12238 .shl_sat => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt)
1222612239 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, sema.mod)
1222712240 else
1222812241 try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, sema.mod),
1222912242
12230 .shl => if (scalar_ty.zigTypeTag() == .ComptimeInt)
12243 .shl => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt)
1223112244 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, sema.mod)
1223212245 else
1223312246 try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, sema.mod),
......@@ -12241,11 +12254,11 @@ fn zirShl(
1224112254 const new_rhs = if (air_tag == .shl_sat) rhs: {
1224212255 // Limit the RHS type for saturating shl to be an integer as small as the LHS.
1224312256 if (rhs_is_comptime_int or
12244 scalar_rhs_ty.intInfo(target).bits > scalar_ty.intInfo(target).bits)
12257 scalar_rhs_ty.intInfo(mod).bits > scalar_ty.intInfo(mod).bits)
1224512258 {
1224612259 const max_int = try sema.addConstant(
1224712260 lhs_ty,
12248 try lhs_ty.maxInt(sema.arena, target),
12261 try lhs_ty.maxInt(sema.arena, mod),
1224912262 );
1225012263 const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src });
1225112264 break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false);
......@@ -12256,11 +12269,11 @@ fn zirShl(
1225612269
1225712270 try sema.requireRuntimeBlock(block, src, runtime_src);
1225812271 if (block.wantSafety()) {
12259 const bit_count = scalar_ty.intInfo(target).bits;
12272 const bit_count = scalar_ty.intInfo(mod).bits;
1226012273 if (!std.math.isPowerOfTwo(bit_count)) {
1226112274 const bit_count_val = try Value.Tag.int_u64.create(sema.arena, bit_count);
1226212275
12263 const ok = if (rhs_ty.zigTypeTag() == .Vector) ok: {
12276 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
1226412277 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));
1226512278 const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
1226612279 break :ok try block.addInst(.{
......@@ -12290,7 +12303,7 @@ fn zirShl(
1229012303 } },
1229112304 });
1229212305 const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty);
12293 const any_ov_bit = if (lhs_ty.zigTypeTag() == .Vector)
12306 const any_ov_bit = if (lhs_ty.zigTypeTag(mod) == .Vector)
1229412307 try block.addInst(.{
1229512308 .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce,
1229612309 .data = .{ .reduce = .{
......@@ -12319,6 +12332,7 @@ fn zirShr(
1231912332 const tracy = trace(@src());
1232012333 defer tracy.end();
1232112334
12335 const mod = sema.mod;
1232212336 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1232312337 const src = inst_data.src();
1232412338 sema.src = src;
......@@ -12330,8 +12344,7 @@ fn zirShr(
1233012344 const lhs_ty = sema.typeOf(lhs);
1233112345 const rhs_ty = sema.typeOf(rhs);
1233212346 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
12333 const target = sema.mod.getTarget();
12334 const scalar_ty = lhs_ty.scalarType();
12347 const scalar_ty = lhs_ty.scalarType(mod);
1233512348
1233612349 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(lhs);
1233712350 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(rhs);
......@@ -12344,18 +12357,18 @@ fn zirShr(
1234412357 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1234512358 return lhs;
1234612359 }
12347 if (scalar_ty.zigTypeTag() != .ComptimeInt) {
12360 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {
1234812361 var bits_payload = Value.Payload.U64{
1234912362 .base = .{ .tag = .int_u64 },
12350 .data = scalar_ty.intInfo(target).bits,
12363 .data = scalar_ty.intInfo(mod).bits,
1235112364 };
1235212365 const bit_value = Value.initPayload(&bits_payload.base);
12353 if (rhs_ty.zigTypeTag() == .Vector) {
12366 if (rhs_ty.zigTypeTag(mod) == .Vector) {
1235412367 var i: usize = 0;
1235512368 while (i < rhs_ty.vectorLen()) : (i += 1) {
1235612369 var elem_value_buf: Value.ElemValueBuffer = undefined;
1235712370 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);
12358 if (rhs_elem.compareHetero(.gte, bit_value, target)) {
12371 if (rhs_elem.compareHetero(.gte, bit_value, mod)) {
1235912372 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
1236012373 rhs_elem.fmtValue(scalar_ty, sema.mod),
1236112374 i,
......@@ -12363,26 +12376,26 @@ fn zirShr(
1236312376 });
1236412377 }
1236512378 }
12366 } else if (rhs_val.compareHetero(.gte, bit_value, target)) {
12379 } else if (rhs_val.compareHetero(.gte, bit_value, mod)) {
1236712380 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
1236812381 rhs_val.fmtValue(scalar_ty, sema.mod),
1236912382 scalar_ty.fmt(sema.mod),
1237012383 });
1237112384 }
1237212385 }
12373 if (rhs_ty.zigTypeTag() == .Vector) {
12386 if (rhs_ty.zigTypeTag(mod) == .Vector) {
1237412387 var i: usize = 0;
1237512388 while (i < rhs_ty.vectorLen()) : (i += 1) {
1237612389 var elem_value_buf: Value.ElemValueBuffer = undefined;
1237712390 const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf);
12378 if (rhs_elem.compareHetero(.lt, Value.zero, target)) {
12391 if (rhs_elem.compareHetero(.lt, Value.zero, mod)) {
1237912392 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
1238012393 rhs_elem.fmtValue(scalar_ty, sema.mod),
1238112394 i,
1238212395 });
1238312396 }
1238412397 }
12385 } else if (rhs_val.compareHetero(.lt, Value.zero, target)) {
12398 } else if (rhs_val.compareHetero(.lt, Value.zero, mod)) {
1238612399 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
1238712400 rhs_val.fmtValue(scalar_ty, sema.mod),
1238812401 });
......@@ -12405,18 +12418,18 @@ fn zirShr(
1240512418 }
1240612419 } else rhs_src;
1240712420
12408 if (maybe_rhs_val == null and scalar_ty.zigTypeTag() == .ComptimeInt) {
12421 if (maybe_rhs_val == null and scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
1240912422 return sema.fail(block, src, "LHS of shift must be a fixed-width integer type, or RHS must be comptime-known", .{});
1241012423 }
1241112424
1241212425 try sema.requireRuntimeBlock(block, src, runtime_src);
1241312426 const result = try block.addBinOp(air_tag, lhs, rhs);
1241412427 if (block.wantSafety()) {
12415 const bit_count = scalar_ty.intInfo(target).bits;
12428 const bit_count = scalar_ty.intInfo(mod).bits;
1241612429 if (!std.math.isPowerOfTwo(bit_count)) {
1241712430 const bit_count_val = try Value.Tag.int_u64.create(sema.arena, bit_count);
1241812431
12419 const ok = if (rhs_ty.zigTypeTag() == .Vector) ok: {
12432 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
1242012433 const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val));
1242112434 const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
1242212435 break :ok try block.addInst(.{
......@@ -12436,7 +12449,7 @@ fn zirShr(
1243612449 if (air_tag == .shr_exact) {
1243712450 const back = try block.addBinOp(.shl, result, rhs);
1243812451
12439 const ok = if (rhs_ty.zigTypeTag() == .Vector) ok: {
12452 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
1244012453 const eql = try block.addCmpVector(lhs, back, .eq);
1244112454 break :ok try block.addInst(.{
1244212455 .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce,
......@@ -12461,6 +12474,7 @@ fn zirBitwise(
1246112474 const tracy = trace(@src());
1246212475 defer tracy.end();
1246312476
12477 const mod = sema.mod;
1246412478 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1246512479 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
1246612480 sema.src = src;
......@@ -12475,8 +12489,8 @@ fn zirBitwise(
1247512489
1247612490 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1247712491 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });
12478 const scalar_type = resolved_type.scalarType();
12479 const scalar_tag = scalar_type.zigTypeTag();
12492 const scalar_type = resolved_type.scalarType(mod);
12493 const scalar_tag = scalar_type.zigTypeTag(mod);
1248012494
1248112495 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1248212496 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
......@@ -12484,7 +12498,7 @@ fn zirBitwise(
1248412498 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1248512499
1248612500 if (!is_int) {
12487 return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });
12501 return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag(mod)), @tagName(rhs_ty.zigTypeTag(mod)) });
1248812502 }
1248912503
1249012504 const runtime_src = runtime: {
......@@ -12515,15 +12529,16 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1251512529 const tracy = trace(@src());
1251612530 defer tracy.end();
1251712531
12532 const mod = sema.mod;
1251812533 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1251912534 const src = inst_data.src();
1252012535 const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
1252112536
1252212537 const operand = try sema.resolveInst(inst_data.operand);
1252312538 const operand_type = sema.typeOf(operand);
12524 const scalar_type = operand_type.scalarType();
12539 const scalar_type = operand_type.scalarType(mod);
1252512540
12526 if (scalar_type.zigTypeTag() != .Int) {
12541 if (scalar_type.zigTypeTag(mod) != .Int) {
1252712542 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{
1252812543 operand_type.fmt(sema.mod),
1252912544 });
......@@ -12532,7 +12547,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1253212547 if (try sema.resolveMaybeUndefVal(operand)) |val| {
1253312548 if (val.isUndef()) {
1253412549 return sema.addConstUndef(operand_type);
12535 } else if (operand_type.zigTypeTag() == .Vector) {
12550 } else if (operand_type.zigTypeTag(mod) == .Vector) {
1253612551 const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen());
1253712552 var elem_val_buf: Value.ElemValueBuffer = undefined;
1253812553 const elems = try sema.arena.alloc(Value, vec_len);
......@@ -12728,18 +12743,19 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1272812743 };
1272912744
1273012745 const result_ty = try Type.array(sema.arena, result_len, res_sent_val, resolved_elem_ty, sema.mod);
12746 const mod = sema.mod;
1273112747 const ptr_addrspace = p: {
12732 if (lhs_ty.zigTypeTag() == .Pointer) break :p lhs_ty.ptrAddressSpace();
12733 if (rhs_ty.zigTypeTag() == .Pointer) break :p rhs_ty.ptrAddressSpace();
12748 if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace();
12749 if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace();
1273412750 break :p null;
1273512751 };
1273612752
12737 const runtime_src = if (switch (lhs_ty.zigTypeTag()) {
12753 const runtime_src = if (switch (lhs_ty.zigTypeTag(mod)) {
1273812754 .Array, .Struct => try sema.resolveMaybeUndefVal(lhs),
1273912755 .Pointer => try sema.resolveDefinedValue(block, lhs_src, lhs),
1274012756 else => unreachable,
1274112757 }) |lhs_val| rs: {
12742 if (switch (rhs_ty.zigTypeTag()) {
12758 if (switch (rhs_ty.zigTypeTag(mod)) {
1274312759 .Array, .Struct => try sema.resolveMaybeUndefVal(rhs),
1274412760 .Pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),
1274512761 else => unreachable,
......@@ -12841,8 +12857,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1284112857}
1284212858
1284312859fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, peer_ty: Type) !?Type.ArrayInfo {
12860 const mod = sema.mod;
1284412861 const operand_ty = sema.typeOf(operand);
12845 switch (operand_ty.zigTypeTag()) {
12862 switch (operand_ty.zigTypeTag(mod)) {
1284612863 .Array => return operand_ty.arrayInfo(),
1284712864 .Pointer => {
1284812865 const ptr_info = operand_ty.ptrInfo().data;
......@@ -12859,7 +12876,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1285912876 };
1286012877 },
1286112878 .One => {
12862 if (ptr_info.pointee_type.zigTypeTag() == .Array) {
12879 if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
1286312880 return ptr_info.pointee_type.arrayInfo();
1286412881 }
1286512882 },
......@@ -12867,10 +12884,10 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1286712884 }
1286812885 },
1286912886 .Struct => {
12870 if (operand_ty.isTuple() and peer_ty.isIndexable()) {
12887 if (operand_ty.isTuple() and peer_ty.isIndexable(mod)) {
1287112888 assert(!peer_ty.isTuple());
1287212889 return .{
12873 .elem_type = peer_ty.elemType2(),
12890 .elem_type = peer_ty.elemType2(mod),
1287412891 .sentinel = null,
1287512892 .len = operand_ty.arrayLen(),
1287612893 };
......@@ -12970,11 +12987,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1297012987 }
1297112988
1297212989 // Analyze the lhs first, to catch the case that someone tried to do exponentiation
12990 const mod = sema.mod;
1297312991 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse {
1297412992 const msg = msg: {
1297512993 const msg = try sema.errMsg(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(sema.mod)});
1297612994 errdefer msg.destroy(sema.gpa);
12977 switch (lhs_ty.zigTypeTag()) {
12995 switch (lhs_ty.zigTypeTag(mod)) {
1297812996 .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {
1297912997 try sema.errNote(block, operator_src, msg, "this operator multiplies arrays; use std.math.pow for exponentiation", .{});
1298012998 },
......@@ -12994,7 +13012,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1299413012
1299513013 const result_ty = try Type.array(sema.arena, result_len, lhs_info.sentinel, lhs_info.elem_type, sema.mod);
1299613014
12997 const ptr_addrspace = if (lhs_ty.zigTypeTag() == .Pointer) lhs_ty.ptrAddressSpace() else null;
13015 const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace() else null;
1299813016 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);
1299913017
1300013018 if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {
......@@ -13082,6 +13100,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1308213100}
1308313101
1308413102fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13103 const mod = sema.mod;
1308513104 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1308613105 const src = inst_data.src();
1308713106 const lhs_src = src;
......@@ -13089,9 +13108,9 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1308913108
1309013109 const rhs = try sema.resolveInst(inst_data.operand);
1309113110 const rhs_ty = sema.typeOf(rhs);
13092 const rhs_scalar_ty = rhs_ty.scalarType();
13111 const rhs_scalar_ty = rhs_ty.scalarType(mod);
1309313112
13094 if (rhs_scalar_ty.isUnsignedInt() or switch (rhs_scalar_ty.zigTypeTag()) {
13113 if (rhs_scalar_ty.isUnsignedInt(mod) or switch (rhs_scalar_ty.zigTypeTag(mod)) {
1309513114 .Int, .ComptimeInt, .Float, .ComptimeFloat => false,
1309613115 else => true,
1309713116 }) {
......@@ -13108,7 +13127,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1310813127 return block.addUnOp(if (block.float_mode == .Optimized) .neg_optimized else .neg, rhs);
1310913128 }
1311013129
13111 const lhs = if (rhs_ty.zigTypeTag() == .Vector)
13130 const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector)
1311213131 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero))
1311313132 else
1311413133 try sema.resolveInst(.zero);
......@@ -13117,6 +13136,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1311713136}
1311813137
1311913138fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13139 const mod = sema.mod;
1312013140 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1312113141 const src = inst_data.src();
1312213142 const lhs_src = src;
......@@ -13124,14 +13144,14 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1312413144
1312513145 const rhs = try sema.resolveInst(inst_data.operand);
1312613146 const rhs_ty = sema.typeOf(rhs);
13127 const rhs_scalar_ty = rhs_ty.scalarType();
13147 const rhs_scalar_ty = rhs_ty.scalarType(mod);
1312813148
13129 switch (rhs_scalar_ty.zigTypeTag()) {
13149 switch (rhs_scalar_ty.zigTypeTag(mod)) {
1313013150 .Int, .ComptimeInt, .Float, .ComptimeFloat => {},
1313113151 else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(sema.mod)}),
1313213152 }
1313313153
13134 const lhs = if (rhs_ty.zigTypeTag() == .Vector)
13154 const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector)
1313513155 try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero))
1313613156 else
1313713157 try sema.resolveInst(.zero);
......@@ -13161,6 +13181,7 @@ fn zirArithmetic(
1316113181}
1316213182
1316313183fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13184 const mod = sema.mod;
1316413185 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1316513186 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
1316613187 sema.src = src;
......@@ -13171,8 +13192,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1317113192 const rhs = try sema.resolveInst(extra.rhs);
1317213193 const lhs_ty = sema.typeOf(lhs);
1317313194 const rhs_ty = sema.typeOf(rhs);
13174 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
13175 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
13195 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
13196 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
1317613197 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1317713198 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1317813199
......@@ -13181,25 +13202,24 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1318113202 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
1318213203 });
1318313204
13184 const is_vector = resolved_type.zigTypeTag() == .Vector;
13205 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1318513206
1318613207 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1318713208 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1318813209
13189 const lhs_scalar_ty = lhs_ty.scalarType();
13190 const rhs_scalar_ty = rhs_ty.scalarType();
13191 const scalar_tag = resolved_type.scalarType().zigTypeTag();
13210 const lhs_scalar_ty = lhs_ty.scalarType(mod);
13211 const rhs_scalar_ty = rhs_ty.scalarType(mod);
13212 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1319213213
1319313214 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1319413215
1319513216 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div);
1319613217
13197 const mod = sema.mod;
1319813218 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
1319913219 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1320013220
13201 if ((lhs_ty.zigTypeTag() == .ComptimeFloat and rhs_ty.zigTypeTag() == .ComptimeInt) or
13202 (lhs_ty.zigTypeTag() == .ComptimeInt and rhs_ty.zigTypeTag() == .ComptimeFloat))
13221 if ((lhs_ty.zigTypeTag(mod) == .ComptimeFloat and rhs_ty.zigTypeTag(mod) == .ComptimeInt) or
13222 (lhs_ty.zigTypeTag(mod) == .ComptimeInt and rhs_ty.zigTypeTag(mod) == .ComptimeFloat))
1320313223 {
1320413224 // If it makes a difference whether we coerce to ints or floats before doing the division, error.
1320513225 // If lhs % rhs is 0, it doesn't matter.
......@@ -13268,7 +13288,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1326813288 const runtime_src = rs: {
1326913289 if (maybe_lhs_val) |lhs_val| {
1327013290 if (lhs_val.isUndef()) {
13271 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
13291 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
1327213292 if (maybe_rhs_val) |rhs_val| {
1327313293 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {
1327413294 return sema.addConstUndef(resolved_type);
......@@ -13309,7 +13329,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1330913329 }
1331013330
1331113331 const air_tag = if (is_int) blk: {
13312 if (lhs_ty.isSignedInt() or rhs_ty.isSignedInt()) {
13332 if (lhs_ty.isSignedInt(mod) or rhs_ty.isSignedInt(mod)) {
1331313333 return sema.fail(block, src, "division with '{s}' and '{s}': signed integers must use @divTrunc, @divFloor, or @divExact", .{ @tagName(lhs_ty.tag()), @tagName(rhs_ty.tag()) });
1331413334 }
1331513335 break :blk Air.Inst.Tag.div_trunc;
......@@ -13321,6 +13341,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1332113341}
1332213342
1332313343fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13344 const mod = sema.mod;
1332413345 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1332513346 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
1332613347 sema.src = src;
......@@ -13331,8 +13352,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1333113352 const rhs = try sema.resolveInst(extra.rhs);
1333213353 const lhs_ty = sema.typeOf(lhs);
1333313354 const rhs_ty = sema.typeOf(rhs);
13334 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
13335 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
13355 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
13356 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
1333613357 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1333713358 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1333813359
......@@ -13341,19 +13362,18 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1334113362 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
1334213363 });
1334313364
13344 const is_vector = resolved_type.zigTypeTag() == .Vector;
13365 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1334513366
1334613367 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1334713368 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1334813369
13349 const lhs_scalar_ty = lhs_ty.scalarType();
13350 const scalar_tag = resolved_type.scalarType().zigTypeTag();
13370 const lhs_scalar_ty = lhs_ty.scalarType(mod);
13371 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1335113372
1335213373 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1335313374
1335413375 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_exact);
1335513376
13356 const mod = sema.mod;
1335713377 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
1335813378 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1335913379
......@@ -13437,7 +13457,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1343713457 const ok = if (!is_int) ok: {
1343813458 const floored = try block.addUnOp(.floor, result);
1343913459
13440 if (resolved_type.zigTypeTag() == .Vector) {
13460 if (resolved_type.zigTypeTag(mod) == .Vector) {
1344113461 const eql = try block.addCmpVector(result, floored, .eq);
1344213462 break :ok try block.addInst(.{
1344313463 .tag = switch (block.float_mode) {
......@@ -13459,7 +13479,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1345913479 } else ok: {
1346013480 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);
1346113481
13462 if (resolved_type.zigTypeTag() == .Vector) {
13482 if (resolved_type.zigTypeTag(mod) == .Vector) {
1346313483 const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero);
1346413484 const zero = try sema.addConstant(resolved_type, zero_val);
1346513485 const eql = try block.addCmpVector(remainder, zero, .eq);
......@@ -13484,6 +13504,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1348413504}
1348513505
1348613506fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13507 const mod = sema.mod;
1348713508 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1348813509 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
1348913510 sema.src = src;
......@@ -13494,8 +13515,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1349413515 const rhs = try sema.resolveInst(extra.rhs);
1349513516 const lhs_ty = sema.typeOf(lhs);
1349613517 const rhs_ty = sema.typeOf(rhs);
13497 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
13498 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
13518 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
13519 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
1349913520 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1350013521 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1350113522
......@@ -13504,20 +13525,19 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1350413525 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
1350513526 });
1350613527
13507 const is_vector = resolved_type.zigTypeTag() == .Vector;
13528 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1350813529
1350913530 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1351013531 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1351113532
13512 const lhs_scalar_ty = lhs_ty.scalarType();
13513 const rhs_scalar_ty = rhs_ty.scalarType();
13514 const scalar_tag = resolved_type.scalarType().zigTypeTag();
13533 const lhs_scalar_ty = lhs_ty.scalarType(mod);
13534 const rhs_scalar_ty = rhs_ty.scalarType(mod);
13535 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1351513536
1351613537 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1351713538
1351813539 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_floor);
1351913540
13520 const mod = sema.mod;
1352113541 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
1352213542 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1352313543
......@@ -13562,7 +13582,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1356213582 }
1356313583 if (maybe_lhs_val) |lhs_val| {
1356413584 if (lhs_val.isUndef()) {
13565 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
13585 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
1356613586 if (maybe_rhs_val) |rhs_val| {
1356713587 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {
1356813588 return sema.addConstUndef(resolved_type);
......@@ -13600,6 +13620,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1360013620}
1360113621
1360213622fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13623 const mod = sema.mod;
1360313624 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1360413625 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
1360513626 sema.src = src;
......@@ -13610,8 +13631,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1361013631 const rhs = try sema.resolveInst(extra.rhs);
1361113632 const lhs_ty = sema.typeOf(lhs);
1361213633 const rhs_ty = sema.typeOf(rhs);
13613 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
13614 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
13634 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
13635 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
1361513636 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1361613637 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1361713638
......@@ -13620,20 +13641,19 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1362013641 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
1362113642 });
1362213643
13623 const is_vector = resolved_type.zigTypeTag() == .Vector;
13644 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1362413645
1362513646 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1362613647 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1362713648
13628 const lhs_scalar_ty = lhs_ty.scalarType();
13629 const rhs_scalar_ty = rhs_ty.scalarType();
13630 const scalar_tag = resolved_type.scalarType().zigTypeTag();
13649 const lhs_scalar_ty = lhs_ty.scalarType(mod);
13650 const rhs_scalar_ty = rhs_ty.scalarType(mod);
13651 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1363113652
1363213653 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1363313654
1363413655 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_trunc);
1363513656
13636 const mod = sema.mod;
1363713657 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
1363813658 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1363913659
......@@ -13677,7 +13697,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1367713697 }
1367813698 if (maybe_lhs_val) |lhs_val| {
1367913699 if (lhs_val.isUndef()) {
13680 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
13700 if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) {
1368113701 if (maybe_rhs_val) |rhs_val| {
1368213702 if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) {
1368313703 return sema.addConstUndef(resolved_type);
......@@ -13727,22 +13747,20 @@ fn addDivIntOverflowSafety(
1372713747 casted_rhs: Air.Inst.Ref,
1372813748 is_int: bool,
1372913749) CompileError!void {
13750 const mod = sema.mod;
1373013751 if (!is_int) return;
1373113752
1373213753 // If the LHS is unsigned, it cannot cause overflow.
13733 if (!lhs_scalar_ty.isSignedInt()) return;
13734
13735 const mod = sema.mod;
13736 const target = mod.getTarget();
13754 if (!lhs_scalar_ty.isSignedInt(mod)) return;
1373713755
1373813756 // If the LHS is widened to a larger integer type, no overflow is possible.
13739 if (lhs_scalar_ty.intInfo(target).bits < resolved_type.intInfo(target).bits) {
13757 if (lhs_scalar_ty.intInfo(mod).bits < resolved_type.intInfo(mod).bits) {
1374013758 return;
1374113759 }
1374213760
13743 const min_int = try resolved_type.minInt(sema.arena, target);
13761 const min_int = try resolved_type.minInt(sema.arena, mod);
1374413762 const neg_one_scalar = try Value.Tag.int_i64.create(sema.arena, -1);
13745 const neg_one = if (resolved_type.zigTypeTag() == .Vector)
13763 const neg_one = if (resolved_type.zigTypeTag(mod) == .Vector)
1374613764 try Value.Tag.repeated.create(sema.arena, neg_one_scalar)
1374713765 else
1374813766 neg_one_scalar;
......@@ -13759,7 +13777,7 @@ fn addDivIntOverflowSafety(
1375913777 }
1376013778
1376113779 var ok: Air.Inst.Ref = .none;
13762 if (resolved_type.zigTypeTag() == .Vector) {
13780 if (resolved_type.zigTypeTag(mod) == .Vector) {
1376313781 if (maybe_lhs_val == null) {
1376413782 const min_int_ref = try sema.addConstant(resolved_type, min_int);
1376513783 ok = try block.addCmpVector(casted_lhs, min_int_ref, .neq);
......@@ -13815,7 +13833,8 @@ fn addDivByZeroSafety(
1381513833 // emitted above.
1381613834 if (maybe_rhs_val != null) return;
1381713835
13818 const ok = if (resolved_type.zigTypeTag() == .Vector) ok: {
13836 const mod = sema.mod;
13837 const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: {
1381913838 const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero);
1382013839 const zero = try sema.addConstant(resolved_type, zero_val);
1382113840 const ok = try block.addCmpVector(casted_rhs, zero, .neq);
......@@ -13842,6 +13861,7 @@ fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst
1384213861}
1384313862
1384413863fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
13864 const mod = sema.mod;
1384513865 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1384613866 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
1384713867 sema.src = src;
......@@ -13852,8 +13872,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1385213872 const rhs = try sema.resolveInst(extra.rhs);
1385313873 const lhs_ty = sema.typeOf(lhs);
1385413874 const rhs_ty = sema.typeOf(rhs);
13855 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
13856 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
13875 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
13876 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
1385713877 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1385813878 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1385913879
......@@ -13862,20 +13882,19 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1386213882 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
1386313883 });
1386413884
13865 const is_vector = resolved_type.zigTypeTag() == .Vector;
13885 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1386613886
1386713887 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1386813888 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1386913889
13870 const lhs_scalar_ty = lhs_ty.scalarType();
13871 const rhs_scalar_ty = rhs_ty.scalarType();
13872 const scalar_tag = resolved_type.scalarType().zigTypeTag();
13890 const lhs_scalar_ty = lhs_ty.scalarType(mod);
13891 const rhs_scalar_ty = rhs_ty.scalarType(mod);
13892 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1387313893
1387413894 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1387513895
1387613896 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .mod_rem);
1387713897
13878 const mod = sema.mod;
1387913898 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
1388013899 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1388113900
......@@ -13904,7 +13923,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1390413923 } else Value.zero;
1390513924 return sema.addConstant(resolved_type, zero_val);
1390613925 }
13907 } else if (lhs_scalar_ty.isSignedInt()) {
13926 } else if (lhs_scalar_ty.isSignedInt(mod)) {
1390813927 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
1390913928 }
1391013929 if (maybe_rhs_val) |rhs_val| {
......@@ -13929,7 +13948,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1392913948 return sema.addConstant(resolved_type, rem_result);
1393013949 }
1393113950 break :rs lhs_src;
13932 } else if (rhs_scalar_ty.isSignedInt()) {
13951 } else if (rhs_scalar_ty.isSignedInt(mod)) {
1393313952 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
1393413953 } else {
1393513954 break :rs rhs_src;
......@@ -13978,7 +13997,8 @@ fn intRem(
1397813997 lhs: Value,
1397913998 rhs: Value,
1398013999) CompileError!Value {
13981 if (ty.zigTypeTag() == .Vector) {
14000 const mod = sema.mod;
14001 if (ty.zigTypeTag(mod) == .Vector) {
1398214002 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
1398314003 for (result_data, 0..) |*scalar, i| {
1398414004 var lhs_buf: Value.ElemValueBuffer = undefined;
......@@ -13997,13 +14017,13 @@ fn intRemScalar(
1399714017 lhs: Value,
1399814018 rhs: Value,
1399914019) CompileError!Value {
14000 const target = sema.mod.getTarget();
14020 const mod = sema.mod;
1400114021 // TODO is this a performance issue? maybe we should try the operation without
1400214022 // resorting to BigInt first.
1400314023 var lhs_space: Value.BigIntSpace = undefined;
1400414024 var rhs_space: Value.BigIntSpace = undefined;
14005 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema);
14006 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema);
14025 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
14026 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
1400714027 const limbs_q = try sema.arena.alloc(
1400814028 math.big.Limb,
1400914029 lhs_bigint.limbs.len,
......@@ -14025,6 +14045,7 @@ fn intRemScalar(
1402514045}
1402614046
1402714047fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14048 const mod = sema.mod;
1402814049 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1402914050 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
1403014051 sema.src = src;
......@@ -14035,8 +14056,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1403514056 const rhs = try sema.resolveInst(extra.rhs);
1403614057 const lhs_ty = sema.typeOf(lhs);
1403714058 const rhs_ty = sema.typeOf(rhs);
14038 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
14039 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
14059 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
14060 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
1404014061 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1404114062 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1404214063
......@@ -14048,13 +14069,12 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1404814069 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1404914070 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1405014071
14051 const scalar_tag = resolved_type.scalarType().zigTypeTag();
14072 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1405214073
1405314074 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1405414075
1405514076 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .mod);
1405614077
14057 const mod = sema.mod;
1405814078 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
1405914079 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1406014080
......@@ -14127,6 +14147,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1412714147}
1412814148
1412914149fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14150 const mod = sema.mod;
1413014151 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1413114152 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
1413214153 sema.src = src;
......@@ -14137,8 +14158,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1413714158 const rhs = try sema.resolveInst(extra.rhs);
1413814159 const lhs_ty = sema.typeOf(lhs);
1413914160 const rhs_ty = sema.typeOf(rhs);
14140 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
14141 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
14161 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
14162 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
1414214163 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1414314164 try sema.checkInvalidPtrArithmetic(block, src, lhs_ty);
1414414165
......@@ -14150,13 +14171,12 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1415014171 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1415114172 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1415214173
14153 const scalar_tag = resolved_type.scalarType().zigTypeTag();
14174 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1415414175
1415514176 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1415614177
1415714178 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .rem);
1415814179
14159 const mod = sema.mod;
1416014180 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
1416114181 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1416214182
......@@ -14268,7 +14288,7 @@ fn zirOverflowArithmetic(
1426814288 const lhs = try sema.coerce(block, dest_ty, uncasted_lhs, lhs_src);
1426914289 const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src);
1427014290
14271 if (dest_ty.scalarType().zigTypeTag() != .Int) {
14291 if (dest_ty.scalarType(mod).zigTypeTag(mod) != .Int) {
1427214292 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(mod)});
1427314293 }
1427414294
......@@ -14434,12 +14454,14 @@ fn zirOverflowArithmetic(
1443414454}
1443514455
1443614456fn maybeRepeated(sema: *Sema, ty: Type, val: Value) !Value {
14437 if (ty.zigTypeTag() != .Vector) return val;
14457 const mod = sema.mod;
14458 if (ty.zigTypeTag(mod) != .Vector) return val;
1443814459 return Value.Tag.repeated.create(sema.arena, val);
1443914460}
1444014461
1444114462fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {
14442 const ov_ty = if (ty.zigTypeTag() == .Vector) try Type.vector(sema.arena, ty.vectorLen(), Type.u1) else Type.u1;
14463 const mod = sema.mod;
14464 const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try Type.vector(sema.arena, ty.vectorLen(), Type.u1) else Type.u1;
1444314465
1444414466 const types = try sema.arena.alloc(Type, 2);
1444514467 const values = try sema.arena.alloc(Value, 2);
......@@ -14468,10 +14490,11 @@ fn analyzeArithmetic(
1446814490 rhs_src: LazySrcLoc,
1446914491 want_safety: bool,
1447014492) CompileError!Air.Inst.Ref {
14493 const mod = sema.mod;
1447114494 const lhs_ty = sema.typeOf(lhs);
1447214495 const rhs_ty = sema.typeOf(rhs);
14473 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
14474 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
14496 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
14497 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
1447514498 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1447614499
1447714500 if (lhs_zig_ty_tag == .Pointer) switch (lhs_ty.ptrSize()) {
......@@ -14491,18 +14514,17 @@ fn analyzeArithmetic(
1449114514 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
1449214515 });
1449314516
14494 const is_vector = resolved_type.zigTypeTag() == .Vector;
14517 const is_vector = resolved_type.zigTypeTag(mod) == .Vector;
1449514518
1449614519 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1449714520 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1449814521
14499 const scalar_tag = resolved_type.scalarType().zigTypeTag();
14522 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
1450014523
1450114524 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1450214525
1450314526 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, zir_tag);
1450414527
14505 const mod = sema.mod;
1450614528 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs);
1450714529 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1450814530 const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {
......@@ -14910,7 +14932,7 @@ fn analyzeArithmetic(
1491014932 } },
1491114933 });
1491214934 const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty);
14913 const any_ov_bit = if (resolved_type.zigTypeTag() == .Vector)
14935 const any_ov_bit = if (resolved_type.zigTypeTag(mod) == .Vector)
1491414936 try block.addInst(.{
1491514937 .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce,
1491614938 .data = .{ .reduce = .{
......@@ -14944,12 +14966,12 @@ fn analyzePtrArithmetic(
1494414966 // TODO if the operand is comptime-known to be negative, or is a negative int,
1494514967 // coerce to isize instead of usize.
1494614968 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);
14947 const target = sema.mod.getTarget();
14969 const mod = sema.mod;
1494814970 const opt_ptr_val = try sema.resolveMaybeUndefVal(ptr);
1494914971 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);
1495014972 const ptr_ty = sema.typeOf(ptr);
1495114973 const ptr_info = ptr_ty.ptrInfo().data;
14952 const elem_ty = if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag() == .Array)
14974 const elem_ty = if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Array)
1495314975 ptr_info.pointee_type.childType()
1495414976 else
1495514977 ptr_info.pointee_type;
......@@ -14963,9 +14985,9 @@ fn analyzePtrArithmetic(
1496314985 }
1496414986 // If the addend is not a comptime-known value we can still count on
1496514987 // it being a multiple of the type size.
14966 const elem_size = elem_ty.abiSize(target);
14988 const elem_size = elem_ty.abiSize(mod);
1496714989 const addend = if (opt_off_val) |off_val| a: {
14968 const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(target));
14990 const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod));
1496914991 break :a elem_size * off_int;
1497014992 } else elem_size;
1497114993
......@@ -14991,10 +15013,10 @@ fn analyzePtrArithmetic(
1499115013 if (opt_off_val) |offset_val| {
1499215014 if (ptr_val.isUndef()) return sema.addConstUndef(new_ptr_ty);
1499315015
14994 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(target));
15016 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));
1499515017 if (offset_int == 0) return ptr;
14996 if (try ptr_val.getUnsignedIntAdvanced(target, sema)) |addr| {
14997 const elem_size = elem_ty.abiSize(target);
15018 if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| {
15019 const elem_size = elem_ty.abiSize(mod);
1499815020 const new_addr = switch (air_tag) {
1499915021 .ptr_add => addr + elem_size * offset_int,
1500015022 .ptr_sub => addr - elem_size * offset_int,
......@@ -15116,6 +15138,7 @@ fn zirAsm(
1511615138
1511715139 const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);
1511815140 const inputs = try sema.arena.alloc(ConstraintName, inputs_len);
15141 const mod = sema.mod;
1511915142
1512015143 for (args, 0..) |*arg, arg_i| {
1512115144 const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);
......@@ -15123,7 +15146,7 @@ fn zirAsm(
1512315146
1512415147 const uncasted_arg = try sema.resolveInst(input.data.operand);
1512515148 const uncasted_arg_ty = sema.typeOf(uncasted_arg);
15126 switch (uncasted_arg_ty.zigTypeTag()) {
15149 switch (uncasted_arg_ty.zigTypeTag(mod)) {
1512715150 .ComptimeInt => arg.* = try sema.coerce(block, Type.initTag(.usize), uncasted_arg, src),
1512815151 .ComptimeFloat => arg.* = try sema.coerce(block, Type.initTag(.f64), uncasted_arg, src),
1512915152 else => {
......@@ -15205,6 +15228,7 @@ fn zirCmpEq(
1520515228 const tracy = trace(@src());
1520615229 defer tracy.end();
1520715230
15231 const mod = sema.mod;
1520815232 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1520915233 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1521015234 const src: LazySrcLoc = inst_data.src();
......@@ -15215,8 +15239,8 @@ fn zirCmpEq(
1521515239
1521615240 const lhs_ty = sema.typeOf(lhs);
1521715241 const rhs_ty = sema.typeOf(rhs);
15218 const lhs_ty_tag = lhs_ty.zigTypeTag();
15219 const rhs_ty_tag = rhs_ty.zigTypeTag();
15242 const lhs_ty_tag = lhs_ty.zigTypeTag(mod);
15243 const rhs_ty_tag = rhs_ty.zigTypeTag(mod);
1522015244 if (lhs_ty_tag == .Null and rhs_ty_tag == .Null) {
1522115245 // null == null, null != null
1522215246 if (op == .eq) {
......@@ -15295,6 +15319,7 @@ fn analyzeCmpUnionTag(
1529515319 tag_src: LazySrcLoc,
1529615320 op: std.math.CompareOperator,
1529715321) CompileError!Air.Inst.Ref {
15322 const mod = sema.mod;
1529815323 const union_ty = try sema.resolveTypeFields(sema.typeOf(un));
1529915324 const union_tag_ty = union_ty.unionTagType() orelse {
1530015325 const msg = msg: {
......@@ -15313,7 +15338,7 @@ fn analyzeCmpUnionTag(
1531315338 if (try sema.resolveMaybeUndefVal(coerced_tag)) |enum_val| {
1531415339 if (enum_val.isUndef()) return sema.addConstUndef(Type.bool);
1531515340 const field_ty = union_ty.unionFieldType(enum_val, sema.mod);
15316 if (field_ty.zigTypeTag() == .NoReturn) {
15341 if (field_ty.zigTypeTag(mod) == .NoReturn) {
1531715342 return Air.Inst.Ref.bool_false;
1531815343 }
1531915344 }
......@@ -15352,32 +15377,33 @@ fn analyzeCmp(
1535215377 rhs_src: LazySrcLoc,
1535315378 is_equality_cmp: bool,
1535415379) CompileError!Air.Inst.Ref {
15380 const mod = sema.mod;
1535515381 const lhs_ty = sema.typeOf(lhs);
1535615382 const rhs_ty = sema.typeOf(rhs);
15357 if (lhs_ty.zigTypeTag() != .Optional and rhs_ty.zigTypeTag() != .Optional) {
15383 if (lhs_ty.zigTypeTag(mod) != .Optional and rhs_ty.zigTypeTag(mod) != .Optional) {
1535815384 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1535915385 }
1536015386
15361 if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) {
15387 if (lhs_ty.zigTypeTag(mod) == .Vector and rhs_ty.zigTypeTag(mod) == .Vector) {
1536215388 return sema.cmpVector(block, src, lhs, rhs, op, lhs_src, rhs_src);
1536315389 }
15364 if (lhs_ty.isNumeric() and rhs_ty.isNumeric()) {
15390 if (lhs_ty.isNumeric(mod) and rhs_ty.isNumeric(mod)) {
1536515391 // This operation allows any combination of integer and float types, regardless of the
1536615392 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for
1536715393 // numeric types.
1536815394 return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src);
1536915395 }
15370 if (is_equality_cmp and lhs_ty.zigTypeTag() == .ErrorUnion and rhs_ty.zigTypeTag() == .ErrorSet) {
15396 if (is_equality_cmp and lhs_ty.zigTypeTag(mod) == .ErrorUnion and rhs_ty.zigTypeTag(mod) == .ErrorSet) {
1537115397 const casted_lhs = try sema.analyzeErrUnionCode(block, lhs_src, lhs);
1537215398 return sema.cmpSelf(block, src, casted_lhs, rhs, op, lhs_src, rhs_src);
1537315399 }
15374 if (is_equality_cmp and lhs_ty.zigTypeTag() == .ErrorSet and rhs_ty.zigTypeTag() == .ErrorUnion) {
15400 if (is_equality_cmp and lhs_ty.zigTypeTag(mod) == .ErrorSet and rhs_ty.zigTypeTag(mod) == .ErrorUnion) {
1537515401 const casted_rhs = try sema.analyzeErrUnionCode(block, rhs_src, rhs);
1537615402 return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);
1537715403 }
1537815404 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1537915405 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });
15380 if (!resolved_type.isSelfComparable(is_equality_cmp)) {
15406 if (!resolved_type.isSelfComparable(mod, is_equality_cmp)) {
1538115407 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{
1538215408 compareOperatorName(op), resolved_type.fmt(sema.mod),
1538315409 });
......@@ -15408,6 +15434,7 @@ fn cmpSelf(
1540815434 lhs_src: LazySrcLoc,
1540915435 rhs_src: LazySrcLoc,
1541015436) CompileError!Air.Inst.Ref {
15437 const mod = sema.mod;
1541115438 const resolved_type = sema.typeOf(casted_lhs);
1541215439 const runtime_src: LazySrcLoc = src: {
1541315440 if (try sema.resolveMaybeUndefVal(casted_lhs)) |lhs_val| {
......@@ -15415,7 +15442,7 @@ fn cmpSelf(
1541515442 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {
1541615443 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
1541715444
15418 if (resolved_type.zigTypeTag() == .Vector) {
15445 if (resolved_type.zigTypeTag(mod) == .Vector) {
1541915446 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.bool);
1542015447 const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type);
1542115448 return sema.addConstant(result_ty, cmp_val);
......@@ -15427,7 +15454,7 @@ fn cmpSelf(
1542715454 return Air.Inst.Ref.bool_false;
1542815455 }
1542915456 } else {
15430 if (resolved_type.zigTypeTag() == .Bool) {
15457 if (resolved_type.zigTypeTag(mod) == .Bool) {
1543115458 // We can lower bool eq/neq more efficiently.
1543215459 return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(), rhs_src);
1543315460 }
......@@ -15436,7 +15463,7 @@ fn cmpSelf(
1543615463 } else {
1543715464 // For bools, we still check the other operand, because we can lower
1543815465 // bool eq/neq more efficiently.
15439 if (resolved_type.zigTypeTag() == .Bool) {
15466 if (resolved_type.zigTypeTag(mod) == .Bool) {
1544015467 if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| {
1544115468 if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool);
1544215469 return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src);
......@@ -15446,7 +15473,7 @@ fn cmpSelf(
1544615473 }
1544715474 };
1544815475 try sema.requireRuntimeBlock(block, src, runtime_src);
15449 if (resolved_type.zigTypeTag() == .Vector) {
15476 if (resolved_type.zigTypeTag(mod) == .Vector) {
1545015477 return block.addCmpVector(casted_lhs, casted_rhs, op);
1545115478 }
1545215479 const tag = Air.Inst.Tag.fromCmpOp(op, block.float_mode == .Optimized);
......@@ -15475,10 +15502,11 @@ fn runtimeBoolCmp(
1547515502}
1547615503
1547715504fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15505 const mod = sema.mod;
1547815506 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1547915507 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1548015508 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
15481 switch (ty.zigTypeTag()) {
15509 switch (ty.zigTypeTag(mod)) {
1548215510 .Fn,
1548315511 .NoReturn,
1548415512 .Undefined,
......@@ -15509,8 +15537,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1550915537 .AnyFrame,
1551015538 => {},
1551115539 }
15512 const target = sema.mod.getTarget();
15513 const val = try ty.lazyAbiSize(target, sema.arena);
15540 const val = try ty.lazyAbiSize(mod, sema.arena);
1551415541 if (val.tag() == .lazy_size) {
1551515542 try sema.queueFullTypeResolution(ty);
1551615543 }
......@@ -15518,10 +15545,11 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1551815545}
1551915546
1552015547fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15548 const mod = sema.mod;
1552115549 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1552215550 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1552315551 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
15524 switch (operand_ty.zigTypeTag()) {
15552 switch (operand_ty.zigTypeTag(mod)) {
1552515553 .Fn,
1552615554 .NoReturn,
1552715555 .Undefined,
......@@ -15552,8 +15580,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1555215580 .AnyFrame,
1555315581 => {},
1555415582 }
15555 const target = sema.mod.getTarget();
15556 const bit_size = try operand_ty.bitSizeAdvanced(target, sema);
15583 const bit_size = try operand_ty.bitSizeAdvanced(mod, sema);
1555715584 return sema.addIntUnsigned(Type.comptime_int, bit_size);
1555815585}
1555915586
......@@ -15765,13 +15792,13 @@ fn zirBuiltinSrc(
1576515792}
1576615793
1576715794fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15795 const mod = sema.mod;
1576815796 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1576915797 const src = inst_data.src();
1577015798 const ty = try sema.resolveType(block, src, inst_data.operand);
1577115799 const type_info_ty = try sema.getBuiltinType("Type");
15772 const target = sema.mod.getTarget();
1577315800
15774 switch (ty.zigTypeTag()) {
15801 switch (ty.zigTypeTag(mod)) {
1577515802 .Type => return sema.addConstant(
1577615803 type_info_ty,
1577715804 try Value.Tag.@"union".create(sema.arena, .{
......@@ -15881,8 +15908,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1588115908 try sema.mod.declareDeclDependency(sema.owner_decl_index, fn_info_decl_index);
1588215909 try sema.ensureDeclAnalyzed(fn_info_decl_index);
1588315910 const fn_info_decl = sema.mod.declPtr(fn_info_decl_index);
15884 var fn_ty_buffer: Value.ToTypeBuffer = undefined;
15885 const fn_ty = fn_info_decl.val.toType(&fn_ty_buffer);
15911 const fn_ty = fn_info_decl.val.toType();
1588615912 const param_info_decl_index = (try sema.namespaceLookup(
1588715913 block,
1588815914 src,
......@@ -15892,8 +15918,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1589215918 try sema.mod.declareDeclDependency(sema.owner_decl_index, param_info_decl_index);
1589315919 try sema.ensureDeclAnalyzed(param_info_decl_index);
1589415920 const param_info_decl = sema.mod.declPtr(param_info_decl_index);
15895 var param_buffer: Value.ToTypeBuffer = undefined;
15896 const param_ty = param_info_decl.val.toType(&param_buffer);
15921 const param_ty = param_info_decl.val.toType();
1589715922 const new_decl = try params_anon_decl.finish(
1589815923 try Type.Tag.array.create(params_anon_decl.arena(), .{
1589915924 .len = param_vals.len,
......@@ -15924,7 +15949,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1592415949 // calling_convention: CallingConvention,
1592515950 try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.cc)),
1592615951 // alignment: comptime_int,
15927 try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(target)),
15952 try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(mod)),
1592815953 // is_generic: bool,
1592915954 Value.makeBool(info.is_generic),
1593015955 // is_var_args: bool,
......@@ -15944,7 +15969,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1594415969 );
1594515970 },
1594615971 .Int => {
15947 const info = ty.intInfo(target);
15972 const info = ty.intInfo(mod);
1594815973 const field_values = try sema.arena.alloc(Value, 2);
1594915974 // signedness: Signedness,
1595015975 field_values[0] = try Value.Tag.enum_field_index.create(
......@@ -15965,7 +15990,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1596515990 .Float => {
1596615991 const field_values = try sema.arena.alloc(Value, 1);
1596715992 // bits: comptime_int,
15968 field_values[0] = try Value.Tag.int_u64.create(sema.arena, ty.bitSize(target));
15993 field_values[0] = try Value.Tag.int_u64.create(sema.arena, ty.bitSize(mod));
1596915994
1597015995 return sema.addConstant(
1597115996 type_info_ty,
......@@ -15980,7 +16005,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1598016005 const alignment = if (info.@"align" != 0)
1598116006 try Value.Tag.int_u64.create(sema.arena, info.@"align")
1598216007 else
15983 try info.pointee_type.lazyAbiAlignment(target, sema.arena);
16008 try info.pointee_type.lazyAbiAlignment(mod, sema.arena);
1598416009
1598516010 const field_values = try sema.arena.create([8]Value);
1598616011 field_values.* = .{
......@@ -16072,8 +16097,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1607216097 try sema.mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);
1607316098 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
1607416099 const set_field_ty_decl = sema.mod.declPtr(set_field_ty_decl_index);
16075 var buffer: Value.ToTypeBuffer = undefined;
16076 break :t try set_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
16100 break :t try set_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
1607716101 };
1607816102
1607916103 try sema.queueFullTypeResolution(try error_field_ty.copy(sema.arena));
......@@ -16164,8 +16188,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1616416188 },
1616516189 .Enum => {
1616616190 // TODO: look into memoizing this result.
16167 var int_tag_type_buffer: Type.Payload.Bits = undefined;
16168 const int_tag_ty = try ty.intTagType(&int_tag_type_buffer).copy(sema.arena);
16191 const int_tag_ty = try ty.intTagType().copy(sema.arena);
1616916192
1617016193 const is_exhaustive = Value.makeBool(!ty.isNonexhaustiveEnum());
1617116194
......@@ -16182,8 +16205,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1618216205 try sema.mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);
1618316206 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
1618416207 const enum_field_ty_decl = sema.mod.declPtr(enum_field_ty_decl_index);
16185 var buffer: Value.ToTypeBuffer = undefined;
16186 break :t try enum_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
16208 break :t try enum_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
1618716209 };
1618816210
1618916211 const enum_fields = ty.enumFields();
......@@ -16275,8 +16297,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1627516297 try sema.mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);
1627616298 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
1627716299 const union_field_ty_decl = sema.mod.declPtr(union_field_ty_decl_index);
16278 var buffer: Value.ToTypeBuffer = undefined;
16279 break :t try union_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
16300 break :t try union_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
1628016301 };
1628116302
1628216303 const union_ty = try sema.resolveTypeFields(ty);
......@@ -16383,8 +16404,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1638316404 try sema.mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);
1638416405 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
1638516406 const struct_field_ty_decl = sema.mod.declPtr(struct_field_ty_decl_index);
16386 var buffer: Value.ToTypeBuffer = undefined;
16387 break :t try struct_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
16407 break :t try struct_field_ty_decl.val.toType().copy(fields_anon_decl.arena());
1638816408 };
1638916409 const struct_ty = try sema.resolveTypeFields(ty);
1639016410 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout
......@@ -16430,7 +16450,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1643016450 // is_comptime: bool,
1643116451 Value.makeBool(is_comptime),
1643216452 // alignment: comptime_int,
16433 try field_ty.lazyAbiAlignment(target, fields_anon_decl.arena()),
16453 try field_ty.lazyAbiAlignment(mod, fields_anon_decl.arena()),
1643416454 };
1643516455 struct_field_val.* = try Value.Tag.aggregate.create(fields_anon_decl.arena(), struct_field_fields);
1643616456 }
......@@ -16463,7 +16483,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1646316483 else
1646416484 field.default_val;
1646516485 const default_val_ptr = try sema.optRefValue(block, field.ty, opt_default_val);
16466 const alignment = field.alignment(target, layout);
16486 const alignment = field.alignment(mod, layout);
1646716487
1646816488 struct_field_fields.* = .{
1646916489 // name: []const u8,
......@@ -16506,7 +16526,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1650616526 if (layout == .Packed) {
1650716527 const struct_obj = struct_ty.castTag(.@"struct").?.data;
1650816528 assert(struct_obj.haveLayout());
16509 assert(struct_obj.backing_int_ty.isInt());
16529 assert(struct_obj.backing_int_ty.isInt(mod));
1651016530 const backing_int_ty_val = try Value.Tag.ty.create(sema.arena, struct_obj.backing_int_ty);
1651116531 break :blk try Value.Tag.opt_payload.create(sema.arena, backing_int_ty_val);
1651216532 } else {
......@@ -16584,8 +16604,7 @@ fn typeInfoDecls(
1658416604 try sema.mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);
1658516605 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
1658616606 const declaration_ty_decl = sema.mod.declPtr(declaration_ty_decl_index);
16587 var buffer: Value.ToTypeBuffer = undefined;
16588 break :t try declaration_ty_decl.val.toType(&buffer).copy(decls_anon_decl.arena());
16607 break :t try declaration_ty_decl.val.toType().copy(decls_anon_decl.arena());
1658916608 };
1659016609 try sema.queueFullTypeResolution(try declaration_ty.copy(sema.arena));
1659116610
......@@ -16632,8 +16651,7 @@ fn typeInfoNamespaceDecls(
1663216651 if (decl.kind == .@"usingnamespace") {
1663316652 if (decl.analysis == .in_progress) continue;
1663416653 try sema.mod.ensureDeclAnalyzed(decl_index);
16635 var buf: Value.ToTypeBuffer = undefined;
16636 const new_ns = decl.val.toType(&buf).getNamespace().?;
16654 const new_ns = decl.val.toType().getNamespace().?;
1663716655 try sema.typeInfoNamespaceDecls(block, decls_anon_decl, new_ns, decl_vals, seen_namespaces);
1663816656 continue;
1663916657 }
......@@ -16709,10 +16727,11 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
1670916727}
1671016728
1671116729fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type {
16712 switch (operand.zigTypeTag()) {
16730 const mod = sema.mod;
16731 switch (operand.zigTypeTag(mod)) {
1671316732 .ComptimeInt => return Type.comptime_int,
1671416733 .Int => {
16715 const bits = operand.bitSize(sema.mod.getTarget());
16734 const bits = operand.bitSize(mod);
1671616735 const count = if (bits == 0)
1671716736 0
1671816737 else blk: {
......@@ -16723,10 +16742,10 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
1672316742 }
1672416743 break :blk count;
1672516744 };
16726 return Module.makeIntType(sema.arena, .unsigned, count);
16745 return mod.intType(.unsigned, count);
1672716746 },
1672816747 .Vector => {
16729 const elem_ty = operand.elemType2();
16748 const elem_ty = operand.elemType2(mod);
1673016749 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);
1673116750 return Type.Tag.vector.create(sema.arena, .{
1673216751 .len = operand.vectorLen(),
......@@ -16920,9 +16939,10 @@ fn finishCondBr(
1692016939}
1692116940
1692216941fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
16923 switch (ty.zigTypeTag()) {
16942 const mod = sema.mod;
16943 switch (ty.zigTypeTag(mod)) {
1692416944 .Optional, .Null, .Undefined => return,
16925 .Pointer => if (ty.isPtrLikeOptional()) return,
16945 .Pointer => if (ty.isPtrLikeOptional(mod)) return,
1692616946 else => {},
1692716947 }
1692816948 return sema.failWithExpectedOptionalType(block, src, ty);
......@@ -16951,10 +16971,11 @@ fn zirIsNonNullPtr(
1695116971 const tracy = trace(@src());
1695216972 defer tracy.end();
1695316973
16974 const mod = sema.mod;
1695416975 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1695516976 const src = inst_data.src();
1695616977 const ptr = try sema.resolveInst(inst_data.operand);
16957 try sema.checkNullableType(block, src, sema.typeOf(ptr).elemType2());
16978 try sema.checkNullableType(block, src, sema.typeOf(ptr).elemType2(mod));
1695816979 if ((try sema.resolveMaybeUndefVal(ptr)) == null) {
1695916980 return block.addUnOp(.is_non_null_ptr, ptr);
1696016981 }
......@@ -16963,7 +16984,8 @@ fn zirIsNonNullPtr(
1696316984}
1696416985
1696516986fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
16966 switch (ty.zigTypeTag()) {
16987 const mod = sema.mod;
16988 switch (ty.zigTypeTag(mod)) {
1696716989 .ErrorSet, .ErrorUnion, .Undefined => return,
1696816990 else => return sema.fail(block, src, "expected error union type, found '{}'", .{
1696916991 ty.fmt(sema.mod),
......@@ -16986,10 +17008,11 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1698617008 const tracy = trace(@src());
1698717009 defer tracy.end();
1698817010
17011 const mod = sema.mod;
1698917012 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1699017013 const src = inst_data.src();
1699117014 const ptr = try sema.resolveInst(inst_data.operand);
16992 try sema.checkErrorType(block, src, sema.typeOf(ptr).elemType2());
17015 try sema.checkErrorType(block, src, sema.typeOf(ptr).elemType2(mod));
1699317016 const loaded = try sema.analyzeLoad(block, src, ptr, src);
1699417017 return sema.analyzeIsNonErr(block, src, loaded);
1699517018}
......@@ -17012,6 +17035,7 @@ fn zirCondbr(
1701217035 const tracy = trace(@src());
1701317036 defer tracy.end();
1701417037
17038 const mod = sema.mod;
1701517039 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1701617040 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
1701717041 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
......@@ -17052,7 +17076,7 @@ fn zirCondbr(
1705217076 const err_inst_data = sema.code.instructions.items(.data)[index].un_node;
1705317077 const err_operand = try sema.resolveInst(err_inst_data.operand);
1705417078 const operand_ty = sema.typeOf(err_operand);
17055 assert(operand_ty.zigTypeTag() == .ErrorUnion);
17079 assert(operand_ty.zigTypeTag(mod) == .ErrorUnion);
1705617080 const result_ty = operand_ty.errorUnionSet();
1705717081 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);
1705817082 };
......@@ -17079,7 +17103,7 @@ fn zirCondbr(
1707917103 return always_noreturn;
1708017104}
1708117105
17082fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Ref {
17106fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1708317107 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1708417108 const src = inst_data.src();
1708517109 const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
......@@ -17087,7 +17111,8 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
1708717111 const body = sema.code.extra[extra.end..][0..extra.data.body_len];
1708817112 const err_union = try sema.resolveInst(extra.data.operand);
1708917113 const err_union_ty = sema.typeOf(err_union);
17090 if (err_union_ty.zigTypeTag() != .ErrorUnion) {
17114 const mod = sema.mod;
17115 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
1709117116 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{
1709217117 err_union_ty.fmt(sema.mod),
1709317118 });
......@@ -17124,7 +17149,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
1712417149 return try_inst;
1712517150}
1712617151
17127fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Ref {
17152fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1712817153 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1712917154 const src = inst_data.src();
1713017155 const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
......@@ -17133,7 +17158,8 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1713317158 const operand = try sema.resolveInst(extra.data.operand);
1713417159 const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src);
1713517160 const err_union_ty = sema.typeOf(err_union);
17136 if (err_union_ty.zigTypeTag() != .ErrorUnion) {
17161 const mod = sema.mod;
17162 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {
1713717163 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{
1713817164 err_union_ty.fmt(sema.mod),
1713917165 });
......@@ -17275,16 +17301,17 @@ fn zirRetImplicit(
1727517301 const tracy = trace(@src());
1727617302 defer tracy.end();
1727717303
17304 const mod = sema.mod;
1727817305 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1727917306 const operand = try sema.resolveInst(inst_data.operand);
1728017307
1728117308 const r_brace_src = inst_data.src();
1728217309 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
17283 const base_tag = sema.fn_ret_ty.baseZigTypeTag();
17310 const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod);
1728417311 if (base_tag == .NoReturn) {
1728517312 const msg = msg: {
1728617313 const msg = try sema.errMsg(block, ret_ty_src, "function declared '{}' implicitly returns", .{
17287 sema.fn_ret_ty.fmt(sema.mod),
17314 sema.fn_ret_ty.fmt(mod),
1728817315 });
1728917316 errdefer msg.destroy(sema.gpa);
1729017317 try sema.errNote(block, r_brace_src, msg, "control flow reaches end of body here", .{});
......@@ -17294,7 +17321,7 @@ fn zirRetImplicit(
1729417321 } else if (base_tag != .Void) {
1729517322 const msg = msg: {
1729617323 const msg = try sema.errMsg(block, ret_ty_src, "function with non-void return type '{}' implicitly returns", .{
17297 sema.fn_ret_ty.fmt(sema.mod),
17324 sema.fn_ret_ty.fmt(mod),
1729817325 });
1729917326 errdefer msg.destroy(sema.gpa);
1730017327 try sema.errNote(block, r_brace_src, msg, "control flow reaches end of body here", .{});
......@@ -17397,17 +17424,19 @@ fn retWithErrTracing(
1739717424}
1739817425
1739917426fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {
17400 if (!sema.mod.backendSupportsFeature(.error_return_trace)) return false;
17427 const mod = sema.mod;
17428 if (!mod.backendSupportsFeature(.error_return_trace)) return false;
1740117429
17402 return fn_ret_ty.isError() and
17403 sema.mod.comp.bin_file.options.error_return_tracing;
17430 return fn_ret_ty.isError(mod) and
17431 mod.comp.bin_file.options.error_return_tracing;
1740417432}
1740517433
1740617434fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
17435 const mod = sema.mod;
1740717436 const inst_data = sema.code.instructions.items(.data)[inst].save_err_ret_index;
1740817437
17409 if (!sema.mod.backendSupportsFeature(.error_return_trace)) return;
17410 if (!sema.mod.comp.bin_file.options.error_return_tracing) return;
17438 if (!mod.backendSupportsFeature(.error_return_trace)) return;
17439 if (!mod.comp.bin_file.options.error_return_tracing) return;
1741117440
1741217441 // This is only relevant at runtime.
1741317442 if (block.is_comptime or block.is_typeof) return;
......@@ -17415,7 +17444,7 @@ fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1741517444 const save_index = inst_data.operand == .none or b: {
1741617445 const operand = try sema.resolveInst(inst_data.operand);
1741717446 const operand_ty = sema.typeOf(operand);
17418 break :b operand_ty.isError();
17447 break :b operand_ty.isError(mod);
1741917448 };
1742017449
1742117450 if (save_index)
......@@ -17467,11 +17496,12 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)
1746717496}
1746817497
1746917498fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
17470 assert(sema.fn_ret_ty.zigTypeTag() == .ErrorUnion);
17499 const mod = sema.mod;
17500 assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion);
1747117501
1747217502 if (sema.fn_ret_ty.errorUnionSet().castTag(.error_set_inferred)) |payload| {
1747317503 const op_ty = sema.typeOf(uncasted_operand);
17474 switch (op_ty.zigTypeTag()) {
17504 switch (op_ty.zigTypeTag(mod)) {
1747517505 .ErrorSet => {
1747617506 try payload.data.addErrorSet(sema.gpa, op_ty);
1747717507 },
......@@ -17492,7 +17522,8 @@ fn analyzeRet(
1749217522 // Special case for returning an error to an inferred error set; we need to
1749317523 // add the error tag to the inferred error set of the in-scope function, so
1749417524 // that the coercion below works correctly.
17495 if (sema.fn_ret_ty.zigTypeTag() == .ErrorUnion) {
17525 const mod = sema.mod;
17526 if (sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) {
1749617527 try sema.addToInferredErrorSet(uncasted_operand);
1749717528 }
1749817529 const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, src, .{ .is_ret = true }) catch |err| switch (err) {
......@@ -17540,6 +17571,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1754017571 const tracy = trace(@src());
1754117572 defer tracy.end();
1754217573
17574 const mod = sema.mod;
1754317575 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
1754417576 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
1754517577 const elem_ty_src: LazySrcLoc = .{ .node_offset_ptr_elem = extra.data.src_node };
......@@ -17582,7 +17614,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1758217614 break :blk 0;
1758317615 }
1758417616 }
17585 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(target, sema)).?);
17617 const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?);
1758617618 try sema.validateAlign(block, align_src, abi_align);
1758717619 break :blk abi_align;
1758817620 } else 0;
......@@ -17591,7 +17623,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1759117623 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
1759217624 extra_i += 1;
1759317625 break :blk try sema.analyzeAddressSpace(block, addrspace_src, ref, .pointer);
17594 } else if (elem_ty.zigTypeTag() == .Fn and target.cpu.arch == .avr) .flash else .generic;
17626 } else if (elem_ty.zigTypeTag(mod) == .Fn and target.cpu.arch == .avr) .flash else .generic;
1759517627
1759617628 const bit_offset = if (inst_data.flags.has_bit_range) blk: {
1759717629 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
......@@ -17611,9 +17643,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1761117643 return sema.fail(block, bitoffset_src, "bit offset starts after end of host integer", .{});
1761217644 }
1761317645
17614 if (elem_ty.zigTypeTag() == .NoReturn) {
17646 if (elem_ty.zigTypeTag(mod) == .NoReturn) {
1761517647 return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{});
17616 } else if (elem_ty.zigTypeTag() == .Fn) {
17648 } else if (elem_ty.zigTypeTag(mod) == .Fn) {
1761717649 if (inst_data.size != .One) {
1761817650 return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{});
1761917651 }
......@@ -17623,7 +17655,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1762317655 {
1762417656 return sema.fail(block, align_src, "function pointer alignment disagrees with function alignment", .{});
1762517657 }
17626 } else if (inst_data.size == .Many and elem_ty.zigTypeTag() == .Opaque) {
17658 } else if (inst_data.size == .Many and elem_ty.zigTypeTag(mod) == .Opaque) {
1762717659 return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{});
1762817660 } else if (inst_data.size == .C) {
1762917661 if (!try sema.validateExternType(elem_ty, .other)) {
......@@ -17639,7 +17671,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1763917671 };
1764017672 return sema.failWithOwnedErrorMsg(msg);
1764117673 }
17642 if (elem_ty.zigTypeTag() == .Opaque) {
17674 if (elem_ty.zigTypeTag(mod) == .Opaque) {
1764317675 return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{});
1764417676 }
1764517677 }
......@@ -17666,8 +17698,9 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1766617698 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1766717699 const src = inst_data.src();
1766817700 const obj_ty = try sema.resolveType(block, src, inst_data.operand);
17701 const mod = sema.mod;
1766917702
17670 switch (obj_ty.zigTypeTag()) {
17703 switch (obj_ty.zigTypeTag(mod)) {
1767117704 .Struct => return sema.structInitEmpty(block, obj_ty, src, src),
1767217705 .Array, .Vector => return sema.arrayInitEmpty(block, src, obj_ty),
1767317706 .Void => return sema.addConstant(obj_ty, Value.void),
......@@ -17696,9 +17729,10 @@ fn structInitEmpty(
1769617729}
1769717730
1769817731fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref {
17732 const mod = sema.mod;
1769917733 const arr_len = obj_ty.arrayLen();
1770017734 if (arr_len != 0) {
17701 if (obj_ty.zigTypeTag() == .Array) {
17735 if (obj_ty.zigTypeTag(mod) == .Array) {
1770217736 return sema.fail(block, src, "expected {d} array elements; found 0", .{arr_len});
1770317737 } else {
1770417738 return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len});
......@@ -17766,13 +17800,14 @@ fn zirStructInit(
1776617800 const extra = sema.code.extraData(Zir.Inst.StructInit, inst_data.payload_index);
1776717801 const src = inst_data.src();
1776817802
17803 const mod = sema.mod;
1776917804 const first_item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end).data;
1777017805 const first_field_type_data = zir_datas[first_item.field_type].pl_node;
1777117806 const first_field_type_extra = sema.code.extraData(Zir.Inst.FieldType, first_field_type_data.payload_index).data;
1777217807 const resolved_ty = try sema.resolveType(block, src, first_field_type_extra.container_type);
1777317808 try sema.resolveTypeLayout(resolved_ty);
1777417809
17775 if (resolved_ty.zigTypeTag() == .Struct) {
17810 if (resolved_ty.zigTypeTag(mod) == .Struct) {
1777617811 // This logic must be synchronized with that in `zirStructInitEmpty`.
1777717812
1777817813 // Maps field index to field_type index of where it was already initialized.
......@@ -17815,7 +17850,7 @@ fn zirStructInit(
1781517850 }
1781617851 found_fields[field_index] = item.data.field_type;
1781717852 field_inits[field_index] = try sema.resolveInst(item.data.init);
17818 if (!is_packed) if (resolved_ty.structFieldValueComptime(field_index)) |default_value| {
17853 if (!is_packed) if (resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| {
1781917854 const init_val = (try sema.resolveMaybeUndefVal(field_inits[field_index])) orelse {
1782017855 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known");
1782117856 };
......@@ -17827,7 +17862,7 @@ fn zirStructInit(
1782717862 }
1782817863
1782917864 return sema.finishStructInit(block, src, src, field_inits, resolved_ty, is_ref);
17830 } else if (resolved_ty.zigTypeTag() == .Union) {
17865 } else if (resolved_ty.zigTypeTag(mod) == .Union) {
1783117866 if (extra.data.fields_len != 1) {
1783217867 return sema.fail(block, src, "union initialization expects exactly one field", .{});
1783317868 }
......@@ -18014,6 +18049,7 @@ fn zirStructInitAnon(
1801418049 inst: Zir.Inst.Index,
1801518050 is_ref: bool,
1801618051) CompileError!Air.Inst.Ref {
18052 const mod = sema.mod;
1801718053 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1801818054 const src = inst_data.src();
1801918055 const extra = sema.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index);
......@@ -18050,7 +18086,7 @@ fn zirStructInitAnon(
1805018086
1805118087 const init = try sema.resolveInst(item.data.init);
1805218088 field_ty.* = sema.typeOf(init);
18053 if (types[i].zigTypeTag() == .Opaque) {
18089 if (types[i].zigTypeTag(mod) == .Opaque) {
1805418090 const msg = msg: {
1805518091 const decl = sema.mod.declPtr(block.src_decl);
1805618092 const field_src = Module.initSrc(src.node_offset.x, sema.gpa, decl, i);
......@@ -18148,15 +18184,16 @@ fn zirArrayInit(
1814818184
1814918185 const array_ty = try sema.resolveType(block, src, args[0]);
1815018186 const sentinel_val = array_ty.sentinel();
18187 const mod = sema.mod;
1815118188
1815218189 const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len - 1 + @boolToInt(sentinel_val != null));
1815318190 defer gpa.free(resolved_args);
1815418191 for (args[1..], 0..) |arg, i| {
1815518192 const resolved_arg = try sema.resolveInst(arg);
18156 const elem_ty = if (array_ty.zigTypeTag() == .Struct)
18193 const elem_ty = if (array_ty.zigTypeTag(mod) == .Struct)
1815718194 array_ty.structFieldType(i)
1815818195 else
18159 array_ty.elemType2();
18196 array_ty.elemType2(mod);
1816018197 resolved_args[i] = sema.coerce(block, elem_ty, resolved_arg, .unneeded) catch |err| switch (err) {
1816118198 error.NeededSourceLocation => {
1816218199 const decl = sema.mod.declPtr(block.src_decl);
......@@ -18169,7 +18206,7 @@ fn zirArrayInit(
1816918206 }
1817018207
1817118208 if (sentinel_val) |some| {
18172 resolved_args[resolved_args.len - 1] = try sema.addConstant(array_ty.elemType2(), some);
18209 resolved_args[resolved_args.len - 1] = try sema.addConstant(array_ty.elemType2(mod), some);
1817318210 }
1817418211
1817518212 const opt_runtime_index: ?u32 = for (resolved_args, 0..) |arg, i| {
......@@ -18227,7 +18264,7 @@ fn zirArrayInit(
1822718264 const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
1822818265 .mutable = true,
1822918266 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
18230 .pointee_type = array_ty.elemType2(),
18267 .pointee_type = array_ty.elemType2(mod),
1823118268 });
1823218269 const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty);
1823318270
......@@ -18252,6 +18289,7 @@ fn zirArrayInitAnon(
1825218289 const src = inst_data.src();
1825318290 const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
1825418291 const operands = sema.code.refSlice(extra.end, extra.data.operands_len);
18292 const mod = sema.mod;
1825518293
1825618294 const types = try sema.arena.alloc(Type, operands.len);
1825718295 const values = try sema.arena.alloc(Value, operands.len);
......@@ -18262,7 +18300,7 @@ fn zirArrayInitAnon(
1826218300 const operand_src = src; // TODO better source location
1826318301 const elem = try sema.resolveInst(operand);
1826418302 types[i] = sema.typeOf(elem);
18265 if (types[i].zigTypeTag() == .Opaque) {
18303 if (types[i].zigTypeTag(mod) == .Opaque) {
1826618304 const msg = msg: {
1826718305 const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
1826818306 errdefer msg.destroy(sema.gpa);
......@@ -18379,11 +18417,12 @@ fn fieldType(
1837918417 field_src: LazySrcLoc,
1838018418 ty_src: LazySrcLoc,
1838118419) CompileError!Air.Inst.Ref {
18420 const mod = sema.mod;
1838218421 var cur_ty = aggregate_ty;
1838318422 while (true) {
1838418423 const resolved_ty = try sema.resolveTypeFields(cur_ty);
1838518424 cur_ty = resolved_ty;
18386 switch (cur_ty.zigTypeTag()) {
18425 switch (cur_ty.zigTypeTag(mod)) {
1838718426 .Struct => {
1838818427 if (cur_ty.isAnonStruct()) {
1838918428 const field_index = try sema.anonStructFieldIndex(block, cur_ty, field_name, field_src);
......@@ -18449,14 +18488,14 @@ fn zirFrame(
1844918488}
1845018489
1845118490fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
18491 const mod = sema.mod;
1845218492 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1845318493 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1845418494 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
1845518495 if (ty.isNoReturn()) {
1845618496 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});
1845718497 }
18458 const target = sema.mod.getTarget();
18459 const val = try ty.lazyAbiAlignment(target, sema.arena);
18498 const val = try ty.lazyAbiAlignment(mod, sema.arena);
1846018499 if (val.tag() == .lazy_align) {
1846118500 try sema.queueFullTypeResolution(ty);
1846218501 }
......@@ -18499,16 +18538,17 @@ fn zirUnaryMath(
1849918538 const tracy = trace(@src());
1850018539 defer tracy.end();
1850118540
18541 const mod = sema.mod;
1850218542 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1850318543 const operand = try sema.resolveInst(inst_data.operand);
1850418544 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1850518545 const operand_ty = sema.typeOf(operand);
1850618546
18507 switch (operand_ty.zigTypeTag()) {
18547 switch (operand_ty.zigTypeTag(mod)) {
1850818548 .ComptimeFloat, .Float => {},
1850918549 .Vector => {
18510 const scalar_ty = operand_ty.scalarType();
18511 switch (scalar_ty.zigTypeTag()) {
18550 const scalar_ty = operand_ty.scalarType(mod);
18551 switch (scalar_ty.zigTypeTag(mod)) {
1851218552 .ComptimeFloat, .Float => {},
1851318553 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty.fmt(sema.mod)}),
1851418554 }
......@@ -18516,9 +18556,9 @@ fn zirUnaryMath(
1851618556 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty.fmt(sema.mod)}),
1851718557 }
1851818558
18519 switch (operand_ty.zigTypeTag()) {
18559 switch (operand_ty.zigTypeTag(mod)) {
1852018560 .Vector => {
18521 const scalar_ty = operand_ty.scalarType();
18561 const scalar_ty = operand_ty.scalarType(mod);
1852218562 const vec_len = operand_ty.vectorLen();
1852318563 const result_ty = try Type.vector(sema.arena, vec_len, scalar_ty);
1852418564 if (try sema.resolveMaybeUndefVal(operand)) |val| {
......@@ -18564,7 +18604,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1856418604 const mod = sema.mod;
1856518605
1856618606 try sema.resolveTypeLayout(operand_ty);
18567 const enum_ty = switch (operand_ty.zigTypeTag()) {
18607 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
1856818608 .EnumLiteral => {
1856918609 const val = try sema.resolveConstValue(block, .unneeded, operand, "");
1857018610 const bytes = val.castTag(.enum_literal).?.data;
......@@ -18654,11 +18694,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1865418694 const bits_val = struct_val[1];
1865518695
1865618696 const signedness = signedness_val.toEnum(std.builtin.Signedness);
18657 const bits = @intCast(u16, bits_val.toUnsignedInt(target));
18658 const ty = switch (signedness) {
18659 .signed => try Type.Tag.int_signed.create(sema.arena, bits),
18660 .unsigned => try Type.Tag.int_unsigned.create(sema.arena, bits),
18661 };
18697 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
18698 const ty = try mod.intType(signedness, bits);
1866218699 return sema.addType(ty);
1866318700 },
1866418701 .Vector => {
......@@ -18667,9 +18704,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1866718704 const len_val = struct_val[0];
1866818705 const child_val = struct_val[1];
1866918706
18670 const len = len_val.toUnsignedInt(target);
18671 var buffer: Value.ToTypeBuffer = undefined;
18672 const child_ty = child_val.toType(&buffer);
18707 const len = len_val.toUnsignedInt(mod);
18708 const child_ty = child_val.toType();
1867318709
1867418710 try sema.checkVectorElemType(block, src, child_ty);
1867518711
......@@ -18682,7 +18718,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1868218718 // bits: comptime_int,
1868318719 const bits_val = struct_val[0];
1868418720
18685 const bits = @intCast(u16, bits_val.toUnsignedInt(target));
18721 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
1868618722 const ty = switch (bits) {
1868718723 16 => Type.f16,
1868818724 32 => Type.f32,
......@@ -18708,10 +18744,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1870818744 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
1870918745 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
1871018746 }
18711 const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(target, sema)).?);
18747 const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?);
1871218748
18713 var buffer: Value.ToTypeBuffer = undefined;
18714 const unresolved_elem_ty = child_val.toType(&buffer);
18749 const unresolved_elem_ty = child_val.toType();
1871518750 const elem_ty = if (abi_align == 0)
1871618751 unresolved_elem_ty
1871718752 else t: {
......@@ -18723,7 +18758,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1872318758 const ptr_size = size_val.toEnum(std.builtin.Type.Pointer.Size);
1872418759
1872518760 var actual_sentinel: ?Value = null;
18726 if (!sentinel_val.isNull()) {
18761 if (!sentinel_val.isNull(mod)) {
1872718762 if (ptr_size == .One or ptr_size == .C) {
1872818763 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
1872918764 }
......@@ -18735,9 +18770,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1873518770 actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
1873618771 }
1873718772
18738 if (elem_ty.zigTypeTag() == .NoReturn) {
18773 if (elem_ty.zigTypeTag(mod) == .NoReturn) {
1873918774 return sema.fail(block, src, "pointer to noreturn not allowed", .{});
18740 } else if (elem_ty.zigTypeTag() == .Fn) {
18775 } else if (elem_ty.zigTypeTag(mod) == .Fn) {
1874118776 if (ptr_size != .One) {
1874218777 return sema.fail(block, src, "function pointers must be single pointers", .{});
1874318778 }
......@@ -18747,7 +18782,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1874718782 {
1874818783 return sema.fail(block, src, "function pointer alignment disagrees with function alignment", .{});
1874918784 }
18750 } else if (ptr_size == .Many and elem_ty.zigTypeTag() == .Opaque) {
18785 } else if (ptr_size == .Many and elem_ty.zigTypeTag(mod) == .Opaque) {
1875118786 return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{});
1875218787 } else if (ptr_size == .C) {
1875318788 if (!try sema.validateExternType(elem_ty, .other)) {
......@@ -18763,7 +18798,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1876318798 };
1876418799 return sema.failWithOwnedErrorMsg(msg);
1876518800 }
18766 if (elem_ty.zigTypeTag() == .Opaque) {
18801 if (elem_ty.zigTypeTag(mod) == .Opaque) {
1876718802 return sema.fail(block, src, "C pointers cannot point to opaque types", .{});
1876818803 }
1876918804 }
......@@ -18790,9 +18825,8 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1879018825 // sentinel: ?*const anyopaque,
1879118826 const sentinel_val = struct_val[2];
1879218827
18793 const len = len_val.toUnsignedInt(target);
18794 var buffer: Value.ToTypeBuffer = undefined;
18795 const child_ty = try child_val.toType(&buffer).copy(sema.arena);
18828 const len = len_val.toUnsignedInt(mod);
18829 const child_ty = try child_val.toType().copy(sema.arena);
1879618830 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {
1879718831 const ptr_ty = try Type.ptr(sema.arena, mod, .{
1879818832 .@"addrspace" = .generic,
......@@ -18810,8 +18844,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1881018844 // child: type,
1881118845 const child_val = struct_val[0];
1881218846
18813 var buffer: Value.ToTypeBuffer = undefined;
18814 const child_ty = try child_val.toType(&buffer).copy(sema.arena);
18847 const child_ty = try child_val.toType().copy(sema.arena);
1881518848
1881618849 const ty = try Type.optional(sema.arena, child_ty);
1881718850 return sema.addType(ty);
......@@ -18824,11 +18857,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1882418857 // payload: type,
1882518858 const payload_val = struct_val[1];
1882618859
18827 var buffer: Value.ToTypeBuffer = undefined;
18828 const error_set_ty = try error_set_val.toType(&buffer).copy(sema.arena);
18829 const payload_ty = try payload_val.toType(&buffer).copy(sema.arena);
18860 const error_set_ty = try error_set_val.toType().copy(sema.arena);
18861 const payload_ty = try payload_val.toType().copy(sema.arena);
1883018862
18831 if (error_set_ty.zigTypeTag() != .ErrorSet) {
18863 if (error_set_ty.zigTypeTag(mod) != .ErrorSet) {
1883218864 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});
1883318865 }
1883418866
......@@ -18839,11 +18871,11 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1883918871 return sema.addType(ty);
1884018872 },
1884118873 .ErrorSet => {
18842 const payload_val = union_val.val.optionalValue() orelse
18874 const payload_val = union_val.val.optionalValue(mod) orelse
1884318875 return sema.addType(Type.initTag(.anyerror));
1884418876 const slice_val = payload_val.castTag(.slice).?.data;
1884518877
18846 const len = try sema.usizeCast(block, src, slice_val.len.toUnsignedInt(mod.getTarget()));
18878 const len = try sema.usizeCast(block, src, slice_val.len.toUnsignedInt(mod));
1884718879 var names: Module.ErrorSet.NameMap = .{};
1884818880 try names.ensureUnusedCapacity(sema.arena, len);
1884918881 var i: usize = 0;
......@@ -18890,7 +18922,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1889018922 return sema.fail(block, src, "reified structs must have no decls", .{});
1889118923 }
1889218924
18893 if (layout != .Packed and !backing_int_val.isNull()) {
18925 if (layout != .Packed and !backing_int_val.isNull(mod)) {
1889418926 return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});
1889518927 }
1889618928
......@@ -18954,10 +18986,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1895418986 };
1895518987
1895618988 // Enum tag type
18957 var buffer: Value.ToTypeBuffer = undefined;
18958 const int_tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);
18989 const int_tag_ty = try tag_type_val.toType().copy(new_decl_arena_allocator);
1895918990
18960 if (int_tag_ty.zigTypeTag() != .Int) {
18991 if (int_tag_ty.zigTypeTag(mod) != .Int) {
1896118992 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
1896218993 }
1896318994 enum_obj.tag_ty = int_tag_ty;
......@@ -19090,7 +19121,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1909019121 const new_decl_arena_allocator = new_decl_arena.allocator();
1909119122
1909219123 const union_obj = try new_decl_arena_allocator.create(Module.Union);
19093 const type_tag = if (!tag_type_val.isNull())
19124 const type_tag = if (!tag_type_val.isNull(mod))
1909419125 Type.Tag.union_tagged
1909519126 else if (layout != .Auto)
1909619127 Type.Tag.@"union"
......@@ -19130,11 +19161,10 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1913019161 var tag_ty_field_names: ?Module.EnumFull.NameMap = null;
1913119162 var enum_field_names: ?*Module.EnumNumbered.NameMap = null;
1913219163 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
19133 if (tag_type_val.optionalValue()) |payload_val| {
19134 var buffer: Value.ToTypeBuffer = undefined;
19135 union_obj.tag_ty = try payload_val.toType(&buffer).copy(new_decl_arena_allocator);
19164 if (tag_type_val.optionalValue(mod)) |payload_val| {
19165 union_obj.tag_ty = try payload_val.toType().copy(new_decl_arena_allocator);
1913619166
19137 if (union_obj.tag_ty.zigTypeTag() != .Enum) {
19167 if (union_obj.tag_ty.zigTypeTag(mod) != .Enum) {
1913819168 return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{});
1913919169 }
1914019170 tag_ty_field_names = try union_obj.tag_ty.enumFields().clone(sema.arena);
......@@ -19187,14 +19217,13 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1918719217 return sema.fail(block, src, "duplicate union field {s}", .{field_name});
1918819218 }
1918919219
19190 var buffer: Value.ToTypeBuffer = undefined;
19191 const field_ty = try type_val.toType(&buffer).copy(new_decl_arena_allocator);
19220 const field_ty = try type_val.toType().copy(new_decl_arena_allocator);
1919219221 gop.value_ptr.* = .{
1919319222 .ty = field_ty,
19194 .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(target, sema)).?),
19223 .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?),
1919519224 };
1919619225
19197 if (field_ty.zigTypeTag() == .Opaque) {
19226 if (field_ty.zigTypeTag(mod) == .Opaque) {
1919819227 const msg = msg: {
1919919228 const msg = try sema.errMsg(block, src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
1920019229 errdefer msg.destroy(sema.gpa);
......@@ -19216,7 +19245,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1921619245 break :msg msg;
1921719246 };
1921819247 return sema.failWithOwnedErrorMsg(msg);
19219 } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty))) {
19248 } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty, mod))) {
1922019249 const msg = msg: {
1922119250 const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
1922219251 errdefer msg.destroy(sema.gpa);
......@@ -19280,20 +19309,18 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1928019309 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
1928119310 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
1928219311 }
19283 const alignment = @intCast(u29, alignment_val.toUnsignedInt(target));
19312 const alignment = @intCast(u29, alignment_val.toUnsignedInt(mod));
1928419313 if (alignment == target_util.defaultFunctionAlignment(target)) {
1928519314 break :alignment 0;
1928619315 } else {
1928719316 break :alignment alignment;
1928819317 }
1928919318 };
19290 const return_type = return_type_val.optionalValue() orelse
19319 const return_type = return_type_val.optionalValue(mod) orelse
1929119320 return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{});
1929219321
19293 var buf: Value.ToTypeBuffer = undefined;
19294
1929519322 const args_slice_val = args_val.castTag(.slice).?.data;
19296 const args_len = try sema.usizeCast(block, src, args_slice_val.len.toUnsignedInt(mod.getTarget()));
19323 const args_len = try sema.usizeCast(block, src, args_slice_val.len.toUnsignedInt(mod));
1929719324
1929819325 const param_types = try sema.arena.alloc(Type, args_len);
1929919326 const comptime_params = try sema.arena.alloc(bool, args_len);
......@@ -19316,12 +19343,12 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1931619343 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});
1931719344 }
1931819345
19319 const param_type_val = param_type_opt_val.optionalValue() orelse
19346 const param_type_val = param_type_opt_val.optionalValue(mod) orelse
1932019347 return sema.fail(block, src, "Type.Fn.Param.arg_type must be non-null for @Type", .{});
19321 const param_type = try param_type_val.toType(&buf).copy(sema.arena);
19348 const param_type = try param_type_val.toType().copy(sema.arena);
1932219349
1932319350 if (arg_is_noalias) {
19324 if (!param_type.isPtrAtRuntime()) {
19351 if (!param_type.isPtrAtRuntime(mod)) {
1932519352 return sema.fail(block, src, "non-pointer parameter declared noalias", .{});
1932619353 }
1932719354 noalias_bits |= @as(u32, 1) << (std.math.cast(u5, i) orelse
......@@ -19336,7 +19363,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1933619363 .param_types = param_types,
1933719364 .comptime_params = comptime_params.ptr,
1933819365 .noalias_bits = noalias_bits,
19339 .return_type = try return_type.toType(&buf).copy(sema.arena),
19366 .return_type = try return_type.toType().copy(sema.arena),
1934019367 .alignment = alignment,
1934119368 .cc = cc,
1934219369 .is_var_args = is_var_args,
......@@ -19396,8 +19423,6 @@ fn reifyStruct(
1939619423 },
1939719424 };
1939819425
19399 const target = mod.getTarget();
19400
1940119426 // Fields
1940219427 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(mod));
1940319428 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
......@@ -19420,7 +19445,7 @@ fn reifyStruct(
1942019445 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
1942119446 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
1942219447 }
19423 const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(target, sema)).?);
19448 const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?);
1942419449
1942519450 if (layout == .Packed) {
1942619451 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
......@@ -19461,7 +19486,7 @@ fn reifyStruct(
1946119486 return sema.fail(block, src, "duplicate struct field {s}", .{field_name});
1946219487 }
1946319488
19464 const default_val = if (default_value_val.optionalValue()) |opt_val| blk: {
19489 const default_val = if (default_value_val.optionalValue(mod)) |opt_val| blk: {
1946519490 const payload_val = if (opt_val.pointerDecl()) |opt_decl|
1946619491 mod.declPtr(opt_decl).val
1946719492 else
......@@ -19472,8 +19497,7 @@ fn reifyStruct(
1947219497 return sema.fail(block, src, "comptime field without default initialization value", .{});
1947319498 }
1947419499
19475 var buffer: Value.ToTypeBuffer = undefined;
19476 const field_ty = try type_val.toType(&buffer).copy(new_decl_arena_allocator);
19500 const field_ty = try type_val.toType().copy(new_decl_arena_allocator);
1947719501 gop.value_ptr.* = .{
1947819502 .ty = field_ty,
1947919503 .abi_align = abi_align,
......@@ -19482,7 +19506,7 @@ fn reifyStruct(
1948219506 .offset = undefined,
1948319507 };
1948419508
19485 if (field_ty.zigTypeTag() == .Opaque) {
19509 if (field_ty.zigTypeTag(mod) == .Opaque) {
1948619510 const msg = msg: {
1948719511 const msg = try sema.errMsg(block, src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
1948819512 errdefer msg.destroy(sema.gpa);
......@@ -19492,7 +19516,7 @@ fn reifyStruct(
1949219516 };
1949319517 return sema.failWithOwnedErrorMsg(msg);
1949419518 }
19495 if (field_ty.zigTypeTag() == .NoReturn) {
19519 if (field_ty.zigTypeTag(mod) == .NoReturn) {
1949619520 const msg = msg: {
1949719521 const msg = try sema.errMsg(block, src, "struct fields cannot be 'noreturn'", .{});
1949819522 errdefer msg.destroy(sema.gpa);
......@@ -19514,7 +19538,7 @@ fn reifyStruct(
1951419538 break :msg msg;
1951519539 };
1951619540 return sema.failWithOwnedErrorMsg(msg);
19517 } else if (struct_obj.layout == .Packed and !(validatePackedType(field_ty))) {
19541 } else if (struct_obj.layout == .Packed and !(validatePackedType(field_ty, mod))) {
1951819542 const msg = msg: {
1951919543 const msg = try sema.errMsg(block, src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
1952019544 errdefer msg.destroy(sema.gpa);
......@@ -19545,20 +19569,15 @@ fn reifyStruct(
1954519569
1954619570 var fields_bit_sum: u64 = 0;
1954719571 for (struct_obj.fields.values()) |field| {
19548 fields_bit_sum += field.ty.bitSize(target);
19572 fields_bit_sum += field.ty.bitSize(mod);
1954919573 }
1955019574
19551 if (backing_int_val.optionalValue()) |payload| {
19552 var buf: Value.ToTypeBuffer = undefined;
19553 const backing_int_ty = payload.toType(&buf);
19575 if (backing_int_val.optionalValue(mod)) |payload| {
19576 const backing_int_ty = payload.toType();
1955419577 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);
1955519578 struct_obj.backing_int_ty = try backing_int_ty.copy(new_decl_arena_allocator);
1955619579 } else {
19557 var buf: Type.Payload.Bits = .{
19558 .base = .{ .tag = .int_unsigned },
19559 .data = @intCast(u16, fields_bit_sum),
19560 };
19561 struct_obj.backing_int_ty = try Type.initPayload(&buf.base).copy(new_decl_arena_allocator);
19580 struct_obj.backing_int_ty = try mod.intType(.unsigned, @intCast(u16, fields_bit_sum));
1956219581 }
1956319582
1956419583 struct_obj.status = .have_layout;
......@@ -19569,6 +19588,7 @@ fn reifyStruct(
1956919588}
1957019589
1957119590fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
19591 const mod = sema.mod;
1957219592 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
1957319593 const src = LazySrcLoc.nodeOffset(extra.node);
1957419594 const addrspace_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
......@@ -19594,7 +19614,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
1959419614
1959519615 ptr_info.@"addrspace" = dest_addrspace;
1959619616 const dest_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);
19597 const dest_ty = if (ptr_ty.zigTypeTag() == .Optional)
19617 const dest_ty = if (ptr_ty.zigTypeTag(mod) == .Optional)
1959819618 try Type.optional(sema.arena, dest_ptr_ty)
1959919619 else
1960019620 dest_ptr_ty;
......@@ -19716,6 +19736,7 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1971619736}
1971719737
1971819738fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19739 const mod = sema.mod;
1971919740 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1972019741 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1972119742 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
......@@ -19730,12 +19751,12 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1973019751 if (try sema.resolveMaybeUndefVal(operand)) |val| {
1973119752 const result_val = try sema.floatToInt(block, operand_src, val, operand_ty, dest_ty);
1973219753 return sema.addConstant(dest_ty, result_val);
19733 } else if (dest_ty.zigTypeTag() == .ComptimeInt) {
19754 } else if (dest_ty.zigTypeTag(mod) == .ComptimeInt) {
1973419755 return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_int' must be comptime-known");
1973519756 }
1973619757
1973719758 try sema.requireRuntimeBlock(block, inst_data.src(), operand_src);
19738 if (dest_ty.intInfo(sema.mod.getTarget()).bits == 0) {
19759 if (dest_ty.intInfo(mod).bits == 0) {
1973919760 if (block.wantSafety()) {
1974019761 const ok = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, operand, try sema.addConstant(operand_ty, Value.zero));
1974119762 try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds);
......@@ -19755,6 +19776,7 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1975519776}
1975619777
1975719778fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19779 const mod = sema.mod;
1975819780 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1975919781 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
1976019782 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
......@@ -19769,7 +19791,7 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1976919791 if (try sema.resolveMaybeUndefVal(operand)) |val| {
1977019792 const result_val = try val.intToFloatAdvanced(sema.arena, operand_ty, dest_ty, sema.mod, sema);
1977119793 return sema.addConstant(dest_ty, result_val);
19772 } else if (dest_ty.zigTypeTag() == .ComptimeFloat) {
19794 } else if (dest_ty.zigTypeTag(mod) == .ComptimeFloat) {
1977319795 return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_float' must be comptime-known");
1977419796 }
1977519797
......@@ -19778,6 +19800,7 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1977819800}
1977919801
1978019802fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19803 const mod = sema.mod;
1978119804 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1978219805 const src = inst_data.src();
1978319806
......@@ -19790,9 +19813,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1979019813 const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1979119814 const ptr_ty = try sema.resolveType(block, src, extra.lhs);
1979219815 try sema.checkPtrType(block, type_src, ptr_ty);
19793 const elem_ty = ptr_ty.elemType2();
19794 const target = sema.mod.getTarget();
19795 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(target, sema);
19816 const elem_ty = ptr_ty.elemType2(mod);
19817 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, sema);
1979619818
1979719819 if (ptr_ty.isSlice()) {
1979819820 const msg = msg: {
......@@ -19805,8 +19827,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1980519827 }
1980619828
1980719829 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
19808 const addr = val.toUnsignedInt(target);
19809 if (!ptr_ty.isAllowzeroPtr() and addr == 0)
19830 const addr = val.toUnsignedInt(mod);
19831 if (!ptr_ty.isAllowzeroPtr(mod) and addr == 0)
1981019832 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(sema.mod)});
1981119833 if (addr != 0 and ptr_align != 0 and addr % ptr_align != 0)
1981219834 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)});
......@@ -19820,8 +19842,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1982019842 }
1982119843
1982219844 try sema.requireRuntimeBlock(block, src, operand_src);
19823 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag() == .Fn)) {
19824 if (!ptr_ty.isAllowzeroPtr()) {
19845 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag(mod) == .Fn)) {
19846 if (!ptr_ty.isAllowzeroPtr(mod)) {
1982519847 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
1982619848 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);
1982719849 }
......@@ -19926,6 +19948,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
1992619948}
1992719949
1992819950fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19951 const mod = sema.mod;
1992919952 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1993019953 const src = inst_data.src();
1993119954 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
......@@ -19934,7 +19957,6 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1993419957 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
1993519958 const operand = try sema.resolveInst(extra.rhs);
1993619959 const operand_ty = sema.typeOf(operand);
19937 const target = sema.mod.getTarget();
1993819960
1993919961 try sema.checkPtrType(block, dest_ty_src, dest_ty);
1994019962 try sema.checkPtrOperand(block, operand_src, operand_ty);
......@@ -19982,18 +20004,18 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1998220004 else
1998320005 operand;
1998420006
19985 const dest_elem_ty = dest_ty.elemType2();
20007 const dest_elem_ty = dest_ty.elemType2(mod);
1998620008 try sema.resolveTypeLayout(dest_elem_ty);
19987 const dest_align = dest_ty.ptrAlignment(target);
20009 const dest_align = dest_ty.ptrAlignment(mod);
1998820010
19989 const operand_elem_ty = operand_ty.elemType2();
20011 const operand_elem_ty = operand_ty.elemType2(mod);
1999020012 try sema.resolveTypeLayout(operand_elem_ty);
19991 const operand_align = operand_ty.ptrAlignment(target);
20013 const operand_align = operand_ty.ptrAlignment(mod);
1999220014
1999320015 // If the destination is less aligned than the source, preserve the source alignment
1999420016 const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: {
1999520017 // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result
19996 if (dest_ty.zigTypeTag() == .Optional) {
20018 if (dest_ty.zigTypeTag(mod) == .Optional) {
1999720019 var buf: Type.Payload.ElemType = undefined;
1999820020 var dest_ptr_info = dest_ty.optionalChild(&buf).ptrInfo().data;
1999920021 dest_ptr_info.@"align" = operand_align;
......@@ -20006,8 +20028,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2000620028 };
2000720029
2000820030 if (dest_is_slice) {
20009 const operand_elem_size = operand_elem_ty.abiSize(target);
20010 const dest_elem_size = dest_elem_ty.abiSize(target);
20031 const operand_elem_size = operand_elem_ty.abiSize(mod);
20032 const dest_elem_size = dest_elem_ty.abiSize(mod);
2001120033 if (operand_elem_size != dest_elem_size) {
2001220034 return sema.fail(block, dest_ty_src, "TODO: implement @ptrCast between slices changing the length", .{});
2001320035 }
......@@ -20032,21 +20054,21 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2003220054 }
2003320055
2003420056 if (try sema.resolveMaybeUndefVal(ptr)) |operand_val| {
20035 if (!dest_ty.ptrAllowsZero() and operand_val.isUndef()) {
20057 if (!dest_ty.ptrAllowsZero(mod) and operand_val.isUndef()) {
2003620058 return sema.failWithUseOfUndef(block, operand_src);
2003720059 }
20038 if (!dest_ty.ptrAllowsZero() and operand_val.isNull()) {
20060 if (!dest_ty.ptrAllowsZero(mod) and operand_val.isNull(mod)) {
2003920061 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});
2004020062 }
20041 if (dest_ty.zigTypeTag() == .Optional and sema.typeOf(ptr).zigTypeTag() != .Optional) {
20063 if (dest_ty.zigTypeTag(mod) == .Optional and sema.typeOf(ptr).zigTypeTag(mod) != .Optional) {
2004220064 return sema.addConstant(dest_ty, try Value.Tag.opt_payload.create(sema.arena, operand_val));
2004320065 }
2004420066 return sema.addConstant(aligned_dest_ty, operand_val);
2004520067 }
2004620068
2004720069 try sema.requireRuntimeBlock(block, src, null);
20048 if (block.wantSafety() and operand_ty.ptrAllowsZero() and !dest_ty.ptrAllowsZero() and
20049 (try sema.typeHasRuntimeBits(dest_ty.elemType2()) or dest_ty.elemType2().zigTypeTag() == .Fn))
20070 if (block.wantSafety() and operand_ty.ptrAllowsZero(mod) and !dest_ty.ptrAllowsZero(mod) and
20071 (try sema.typeHasRuntimeBits(dest_ty.elemType2(mod)) or dest_ty.elemType2(mod).zigTypeTag(mod) == .Fn))
2005020072 {
2005120073 const ptr_int = try block.addUnOp(.ptrtoint, ptr);
2005220074 const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize);
......@@ -20102,6 +20124,7 @@ fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2010220124}
2010320125
2010420126fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20127 const mod = sema.mod;
2010520128 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2010620129 const src = inst_data.src();
2010720130 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
......@@ -20112,7 +20135,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2011220135 const dest_is_comptime_int = try sema.checkIntType(block, dest_ty_src, dest_scalar_ty);
2011320136 const operand_ty = sema.typeOf(operand);
2011420137 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);
20115 const is_vector = operand_ty.zigTypeTag() == .Vector;
20138 const is_vector = operand_ty.zigTypeTag(mod) == .Vector;
2011620139 const dest_ty = if (is_vector)
2011720140 try Type.vector(sema.arena, operand_ty.vectorLen(), dest_scalar_ty)
2011820141 else
......@@ -20122,15 +20145,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2012220145 return sema.coerce(block, dest_ty, operand, operand_src);
2012320146 }
2012420147
20125 const target = sema.mod.getTarget();
20126 const dest_info = dest_scalar_ty.intInfo(target);
20148 const dest_info = dest_scalar_ty.intInfo(mod);
2012720149
2012820150 if (try sema.typeHasOnePossibleValue(dest_ty)) |val| {
2012920151 return sema.addConstant(dest_ty, val);
2013020152 }
2013120153
20132 if (operand_scalar_ty.zigTypeTag() != .ComptimeInt) {
20133 const operand_info = operand_ty.intInfo(target);
20154 if (operand_scalar_ty.zigTypeTag(mod) != .ComptimeInt) {
20155 const operand_info = operand_ty.intInfo(mod);
2013420156 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
2013520157 return sema.addConstant(operand_ty, val);
2013620158 }
......@@ -20186,6 +20208,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2018620208}
2018720209
2018820210fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20211 const mod = sema.mod;
2018920212 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2019020213 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2019120214 const align_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
......@@ -20199,12 +20222,12 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2019920222 var ptr_info = ptr_ty.ptrInfo().data;
2020020223 ptr_info.@"align" = dest_align;
2020120224 var dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);
20202 if (ptr_ty.zigTypeTag() == .Optional) {
20225 if (ptr_ty.zigTypeTag(mod) == .Optional) {
2020320226 dest_ty = try Type.Tag.optional.create(sema.arena, dest_ty);
2020420227 }
2020520228
2020620229 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| {
20207 if (try val.getUnsignedIntAdvanced(sema.mod.getTarget(), null)) |addr| {
20230 if (try val.getUnsignedIntAdvanced(mod, null)) |addr| {
2020820231 if (addr % dest_align != 0) {
2020920232 return sema.fail(block, ptr_src, "pointer address 0x{X} is not aligned to {d} bytes", .{ addr, dest_align });
2021020233 }
......@@ -20247,23 +20270,23 @@ fn zirBitCount(
2024720270 block: *Block,
2024820271 inst: Zir.Inst.Index,
2024920272 air_tag: Air.Inst.Tag,
20250 comptime comptimeOp: fn (val: Value, ty: Type, target: std.Target) u64,
20273 comptime comptimeOp: fn (val: Value, ty: Type, mod: *const Module) u64,
2025120274) CompileError!Air.Inst.Ref {
20275 const mod = sema.mod;
2025220276 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
2025320277 const src = inst_data.src();
2025420278 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
2025520279 const operand = try sema.resolveInst(inst_data.operand);
2025620280 const operand_ty = sema.typeOf(operand);
2025720281 _ = try sema.checkIntOrVector(block, operand, operand_src);
20258 const target = sema.mod.getTarget();
20259 const bits = operand_ty.intInfo(target).bits;
20282 const bits = operand_ty.intInfo(mod).bits;
2026020283
2026120284 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
2026220285 return sema.addConstant(operand_ty, val);
2026320286 }
2026420287
20265 const result_scalar_ty = try Type.smallestUnsignedInt(sema.arena, bits);
20266 switch (operand_ty.zigTypeTag()) {
20288 const result_scalar_ty = try mod.smallestUnsignedInt(bits);
20289 switch (operand_ty.zigTypeTag(mod)) {
2026720290 .Vector => {
2026820291 const vec_len = operand_ty.vectorLen();
2026920292 const result_ty = try Type.vector(sema.arena, vec_len, result_scalar_ty);
......@@ -20272,10 +20295,10 @@ fn zirBitCount(
2027220295
2027320296 var elem_buf: Value.ElemValueBuffer = undefined;
2027420297 const elems = try sema.arena.alloc(Value, vec_len);
20275 const scalar_ty = operand_ty.scalarType();
20298 const scalar_ty = operand_ty.scalarType(mod);
2027620299 for (elems, 0..) |*elem, i| {
2027720300 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);
20278 const count = comptimeOp(elem_val, scalar_ty, target);
20301 const count = comptimeOp(elem_val, scalar_ty, mod);
2027920302 elem.* = try Value.Tag.int_u64.create(sema.arena, count);
2028020303 }
2028120304 return sema.addConstant(
......@@ -20291,7 +20314,7 @@ fn zirBitCount(
2029120314 if (try sema.resolveMaybeUndefVal(operand)) |val| {
2029220315 if (val.isUndef()) return sema.addConstUndef(result_scalar_ty);
2029320316 try sema.resolveLazyValue(val);
20294 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, target));
20317 return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, mod));
2029520318 } else {
2029620319 try sema.requireRuntimeBlock(block, src, operand_src);
2029720320 return block.addTyOp(air_tag, result_scalar_ty, operand);
......@@ -20302,14 +20325,14 @@ fn zirBitCount(
2030220325}
2030320326
2030420327fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20328 const mod = sema.mod;
2030520329 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
2030620330 const src = inst_data.src();
2030720331 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
2030820332 const operand = try sema.resolveInst(inst_data.operand);
2030920333 const operand_ty = sema.typeOf(operand);
2031020334 const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src);
20311 const target = sema.mod.getTarget();
20312 const bits = scalar_ty.intInfo(target).bits;
20335 const bits = scalar_ty.intInfo(mod).bits;
2031320336 if (bits % 8 != 0) {
2031420337 return sema.fail(
2031520338 block,
......@@ -20323,11 +20346,11 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2032320346 return sema.addConstant(operand_ty, val);
2032420347 }
2032520348
20326 switch (operand_ty.zigTypeTag()) {
20349 switch (operand_ty.zigTypeTag(mod)) {
2032720350 .Int => {
2032820351 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
2032920352 if (val.isUndef()) return sema.addConstUndef(operand_ty);
20330 const result_val = try val.byteSwap(operand_ty, target, sema.arena);
20353 const result_val = try val.byteSwap(operand_ty, mod, sema.arena);
2033120354 return sema.addConstant(operand_ty, result_val);
2033220355 } else operand_src;
2033320356
......@@ -20344,7 +20367,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2034420367 const elems = try sema.arena.alloc(Value, vec_len);
2034520368 for (elems, 0..) |*elem, i| {
2034620369 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);
20347 elem.* = try elem_val.byteSwap(operand_ty, target, sema.arena);
20370 elem.* = try elem_val.byteSwap(operand_ty, mod, sema.arena);
2034820371 }
2034920372 return sema.addConstant(
2035020373 operand_ty,
......@@ -20371,12 +20394,12 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2037120394 return sema.addConstant(operand_ty, val);
2037220395 }
2037320396
20374 const target = sema.mod.getTarget();
20375 switch (operand_ty.zigTypeTag()) {
20397 const mod = sema.mod;
20398 switch (operand_ty.zigTypeTag(mod)) {
2037620399 .Int => {
2037720400 const runtime_src = if (try sema.resolveMaybeUndefVal(operand)) |val| {
2037820401 if (val.isUndef()) return sema.addConstUndef(operand_ty);
20379 const result_val = try val.bitReverse(operand_ty, target, sema.arena);
20402 const result_val = try val.bitReverse(operand_ty, mod, sema.arena);
2038020403 return sema.addConstant(operand_ty, result_val);
2038120404 } else operand_src;
2038220405
......@@ -20393,7 +20416,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2039320416 const elems = try sema.arena.alloc(Value, vec_len);
2039420417 for (elems, 0..) |*elem, i| {
2039520418 const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf);
20396 elem.* = try elem_val.bitReverse(scalar_ty, target, sema.arena);
20419 elem.* = try elem_val.bitReverse(scalar_ty, mod, sema.arena);
2039720420 }
2039820421 return sema.addConstant(
2039920422 operand_ty,
......@@ -20429,10 +20452,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2042920452
2043020453 const ty = try sema.resolveType(block, lhs_src, extra.lhs);
2043120454 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs, "name of field must be comptime-known");
20432 const target = sema.mod.getTarget();
2043320455
20456 const mod = sema.mod;
2043420457 try sema.resolveTypeLayout(ty);
20435 switch (ty.zigTypeTag()) {
20458 switch (ty.zigTypeTag(mod)) {
2043620459 .Struct => {},
2043720460 else => {
2043820461 const msg = msg: {
......@@ -20464,15 +20487,16 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2046420487 if (i == field_index) {
2046520488 return bit_sum;
2046620489 }
20467 bit_sum += field.ty.bitSize(target);
20490 bit_sum += field.ty.bitSize(mod);
2046820491 } else unreachable;
2046920492 },
20470 else => return ty.structFieldOffset(field_index, target) * 8,
20493 else => return ty.structFieldOffset(field_index, mod) * 8,
2047120494 }
2047220495}
2047320496
2047420497fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
20475 switch (ty.zigTypeTag()) {
20498 const mod = sema.mod;
20499 switch (ty.zigTypeTag(mod)) {
2047620500 .Struct, .Enum, .Union, .Opaque => return,
2047720501 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(sema.mod)}),
2047820502 }
......@@ -20480,7 +20504,8 @@ fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Com
2048020504
2048120505/// Returns `true` if the type was a comptime_int.
2048220506fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
20483 switch (try ty.zigTypeTagOrPoison()) {
20507 const mod = sema.mod;
20508 switch (try ty.zigTypeTagOrPoison(mod)) {
2048420509 .ComptimeInt => return true,
2048520510 .Int => return false,
2048620511 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(sema.mod)}),
......@@ -20493,7 +20518,8 @@ fn checkInvalidPtrArithmetic(
2049320518 src: LazySrcLoc,
2049420519 ty: Type,
2049520520) CompileError!void {
20496 switch (try ty.zigTypeTagOrPoison()) {
20521 const mod = sema.mod;
20522 switch (try ty.zigTypeTagOrPoison(mod)) {
2049720523 .Pointer => switch (ty.ptrSize()) {
2049820524 .One, .Slice => return,
2049920525 .Many, .C => return sema.fail(
......@@ -20532,7 +20558,8 @@ fn checkPtrOperand(
2053220558 ty_src: LazySrcLoc,
2053320559 ty: Type,
2053420560) CompileError!void {
20535 switch (ty.zigTypeTag()) {
20561 const mod = sema.mod;
20562 switch (ty.zigTypeTag(mod)) {
2053620563 .Pointer => return,
2053720564 .Fn => {
2053820565 const msg = msg: {
......@@ -20550,7 +20577,7 @@ fn checkPtrOperand(
2055020577 };
2055120578 return sema.failWithOwnedErrorMsg(msg);
2055220579 },
20553 .Optional => if (ty.isPtrLikeOptional()) return,
20580 .Optional => if (ty.isPtrLikeOptional(mod)) return,
2055420581 else => {},
2055520582 }
2055620583 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)});
......@@ -20562,7 +20589,8 @@ fn checkPtrType(
2056220589 ty_src: LazySrcLoc,
2056320590 ty: Type,
2056420591) CompileError!void {
20565 switch (ty.zigTypeTag()) {
20592 const mod = sema.mod;
20593 switch (ty.zigTypeTag(mod)) {
2056620594 .Pointer => return,
2056720595 .Fn => {
2056820596 const msg = msg: {
......@@ -20580,7 +20608,7 @@ fn checkPtrType(
2058020608 };
2058120609 return sema.failWithOwnedErrorMsg(msg);
2058220610 },
20583 .Optional => if (ty.isPtrLikeOptional()) return,
20611 .Optional => if (ty.isPtrLikeOptional(mod)) return,
2058420612 else => {},
2058520613 }
2058620614 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(sema.mod)});
......@@ -20592,9 +20620,10 @@ fn checkVectorElemType(
2059220620 ty_src: LazySrcLoc,
2059320621 ty: Type,
2059420622) CompileError!void {
20595 switch (ty.zigTypeTag()) {
20623 const mod = sema.mod;
20624 switch (ty.zigTypeTag(mod)) {
2059620625 .Int, .Float, .Bool => return,
20597 else => if (ty.isPtrAtRuntime()) return,
20626 else => if (ty.isPtrAtRuntime(mod)) return,
2059820627 }
2059920628 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(sema.mod)});
2060020629}
......@@ -20605,7 +20634,8 @@ fn checkFloatType(
2060520634 ty_src: LazySrcLoc,
2060620635 ty: Type,
2060720636) CompileError!void {
20608 switch (ty.zigTypeTag()) {
20637 const mod = sema.mod;
20638 switch (ty.zigTypeTag(mod)) {
2060920639 .ComptimeInt, .ComptimeFloat, .Float => {},
2061020640 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(sema.mod)}),
2061120641 }
......@@ -20617,9 +20647,10 @@ fn checkNumericType(
2061720647 ty_src: LazySrcLoc,
2061820648 ty: Type,
2061920649) CompileError!void {
20620 switch (ty.zigTypeTag()) {
20650 const mod = sema.mod;
20651 switch (ty.zigTypeTag(mod)) {
2062120652 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
20622 .Vector => switch (ty.childType().zigTypeTag()) {
20653 .Vector => switch (ty.childType().zigTypeTag(mod)) {
2062320654 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
2062420655 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),
2062520656 },
......@@ -20637,9 +20668,9 @@ fn checkAtomicPtrOperand(
2063720668 ptr_src: LazySrcLoc,
2063820669 ptr_const: bool,
2063920670) CompileError!Air.Inst.Ref {
20640 const target = sema.mod.getTarget();
20641 var diag: target_util.AtomicPtrAlignmentDiagnostics = .{};
20642 const alignment = target_util.atomicPtrAlignment(target, elem_ty, &diag) catch |err| switch (err) {
20671 const mod = sema.mod;
20672 var diag: Module.AtomicPtrAlignmentDiagnostics = .{};
20673 const alignment = mod.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {
2064320674 error.FloatTooBig => return sema.fail(
2064420675 block,
2064520676 elem_ty_src,
......@@ -20668,7 +20699,7 @@ fn checkAtomicPtrOperand(
2066820699 };
2066920700
2067020701 const ptr_ty = sema.typeOf(ptr);
20671 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison()) {
20702 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {
2067220703 .Pointer => ptr_ty.ptrInfo().data,
2067320704 else => {
2067420705 const wanted_ptr_ty = try Type.ptr(sema.arena, sema.mod, wanted_ptr_data);
......@@ -20735,12 +20766,13 @@ fn checkIntOrVector(
2073520766 operand: Air.Inst.Ref,
2073620767 operand_src: LazySrcLoc,
2073720768) CompileError!Type {
20769 const mod = sema.mod;
2073820770 const operand_ty = sema.typeOf(operand);
20739 switch (try operand_ty.zigTypeTagOrPoison()) {
20771 switch (try operand_ty.zigTypeTagOrPoison(mod)) {
2074020772 .Int => return operand_ty,
2074120773 .Vector => {
2074220774 const elem_ty = operand_ty.childType();
20743 switch (try elem_ty.zigTypeTagOrPoison()) {
20775 switch (try elem_ty.zigTypeTagOrPoison(mod)) {
2074420776 .Int => return elem_ty,
2074520777 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
2074620778 elem_ty.fmt(sema.mod),
......@@ -20759,11 +20791,12 @@ fn checkIntOrVectorAllowComptime(
2075920791 operand_ty: Type,
2076020792 operand_src: LazySrcLoc,
2076120793) CompileError!Type {
20762 switch (try operand_ty.zigTypeTagOrPoison()) {
20794 const mod = sema.mod;
20795 switch (try operand_ty.zigTypeTagOrPoison(mod)) {
2076320796 .Int, .ComptimeInt => return operand_ty,
2076420797 .Vector => {
2076520798 const elem_ty = operand_ty.childType();
20766 switch (try elem_ty.zigTypeTagOrPoison()) {
20799 switch (try elem_ty.zigTypeTagOrPoison(mod)) {
2076720800 .Int, .ComptimeInt => return elem_ty,
2076820801 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
2076920802 elem_ty.fmt(sema.mod),
......@@ -20777,7 +20810,8 @@ fn checkIntOrVectorAllowComptime(
2077720810}
2077820811
2077920812fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
20780 switch (ty.zigTypeTag()) {
20813 const mod = sema.mod;
20814 switch (ty.zigTypeTag(mod)) {
2078120815 .ErrorSet => return,
2078220816 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty.fmt(sema.mod)}),
2078320817 }
......@@ -20805,11 +20839,12 @@ fn checkSimdBinOp(
2080520839 lhs_src: LazySrcLoc,
2080620840 rhs_src: LazySrcLoc,
2080720841) CompileError!SimdBinOp {
20842 const mod = sema.mod;
2080820843 const lhs_ty = sema.typeOf(uncasted_lhs);
2080920844 const rhs_ty = sema.typeOf(uncasted_rhs);
2081020845
2081120846 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
20812 var vec_len: ?usize = if (lhs_ty.zigTypeTag() == .Vector) lhs_ty.vectorLen() else null;
20847 var vec_len: ?usize = if (lhs_ty.zigTypeTag(mod) == .Vector) lhs_ty.vectorLen() else null;
2081320848 const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{
2081420849 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
2081520850 });
......@@ -20823,7 +20858,7 @@ fn checkSimdBinOp(
2082320858 .lhs_val = try sema.resolveMaybeUndefVal(lhs),
2082420859 .rhs_val = try sema.resolveMaybeUndefVal(rhs),
2082520860 .result_ty = result_ty,
20826 .scalar_ty = result_ty.scalarType(),
20861 .scalar_ty = result_ty.scalarType(mod),
2082720862 };
2082820863}
2082920864
......@@ -20836,8 +20871,9 @@ fn checkVectorizableBinaryOperands(
2083620871 lhs_src: LazySrcLoc,
2083720872 rhs_src: LazySrcLoc,
2083820873) CompileError!void {
20839 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
20840 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
20874 const mod = sema.mod;
20875 const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(mod);
20876 const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod);
2084120877 if (lhs_zig_ty_tag != .Vector and rhs_zig_ty_tag != .Vector) return;
2084220878
2084320879 const lhs_is_vector = switch (lhs_zig_ty_tag) {
......@@ -20892,6 +20928,7 @@ fn resolveExportOptions(
2089220928 src: LazySrcLoc,
2089320929 zir_ref: Zir.Inst.Ref,
2089420930) CompileError!std.builtin.ExportOptions {
20931 const mod = sema.mod;
2089520932 const export_options_ty = try sema.getBuiltinType("ExportOptions");
2089620933 const air_ref = try sema.resolveInst(zir_ref);
2089720934 const options = try sema.coerce(block, export_options_ty, air_ref, src);
......@@ -20904,7 +20941,7 @@ fn resolveExportOptions(
2090420941 const name_operand = try sema.fieldVal(block, src, options, "name", name_src);
2090520942 const name_val = try sema.resolveConstValue(block, name_src, name_operand, "name of exported value must be comptime-known");
2090620943 const name_ty = Type.initTag(.const_slice_u8);
20907 const name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod);
20944 const name = try name_val.toAllocatedBytes(name_ty, sema.arena, mod);
2090820945
2090920946 const linkage_operand = try sema.fieldVal(block, src, options, "linkage", linkage_src);
2091020947 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_operand, "linkage of exported value must be comptime-known");
......@@ -20913,8 +20950,8 @@ fn resolveExportOptions(
2091320950 const section_operand = try sema.fieldVal(block, src, options, "section", section_src);
2091420951 const section_opt_val = try sema.resolveConstValue(block, section_src, section_operand, "linksection of exported value must be comptime-known");
2091520952 const section_ty = Type.initTag(.const_slice_u8);
20916 const section = if (section_opt_val.optionalValue()) |section_val|
20917 try section_val.toAllocatedBytes(section_ty, sema.arena, sema.mod)
20953 const section = if (section_opt_val.optionalValue(mod)) |section_val|
20954 try section_val.toAllocatedBytes(section_ty, sema.arena, mod)
2091820955 else
2091920956 null;
2092020957
......@@ -20979,6 +21016,7 @@ fn zirCmpxchg(
2097921016 block: *Block,
2098021017 extended: Zir.Inst.Extended.InstData,
2098121018) CompileError!Air.Inst.Ref {
21019 const mod = sema.mod;
2098221020 const extra = sema.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;
2098321021 const air_tag: Air.Inst.Tag = switch (extended.small) {
2098421022 0 => .cmpxchg_weak,
......@@ -20996,7 +21034,7 @@ fn zirCmpxchg(
2099621034 // zig fmt: on
2099721035 const expected_value = try sema.resolveInst(extra.expected_value);
2099821036 const elem_ty = sema.typeOf(expected_value);
20999 if (elem_ty.zigTypeTag() == .Float) {
21037 if (elem_ty.zigTypeTag(mod) == .Float) {
2100021038 return sema.fail(
2100121039 block,
2100221040 elem_ty_src,
......@@ -21102,26 +21140,26 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2110221140 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp", "@reduce operation must be comptime-known");
2110321141 const operand = try sema.resolveInst(extra.rhs);
2110421142 const operand_ty = sema.typeOf(operand);
21105 const target = sema.mod.getTarget();
21143 const mod = sema.mod;
2110621144
21107 if (operand_ty.zigTypeTag() != .Vector) {
21108 return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(sema.mod)});
21145 if (operand_ty.zigTypeTag(mod) != .Vector) {
21146 return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(mod)});
2110921147 }
2111021148
2111121149 const scalar_ty = operand_ty.childType();
2111221150
2111321151 // Type-check depending on operation.
2111421152 switch (operation) {
21115 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag()) {
21153 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(mod)) {
2111621154 .Int, .Bool => {},
2111721155 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{}'", .{
21118 @tagName(operation), operand_ty.fmt(sema.mod),
21156 @tagName(operation), operand_ty.fmt(mod),
2111921157 }),
2112021158 },
21121 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag()) {
21159 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) {
2112221160 .Int, .Float => {},
2112321161 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{}'", .{
21124 @tagName(operation), operand_ty.fmt(sema.mod),
21162 @tagName(operation), operand_ty.fmt(mod),
2112521163 }),
2112621164 },
2112721165 }
......@@ -21136,19 +21174,19 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2113621174 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
2113721175 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);
2113821176
21139 var accum: Value = try operand_val.elemValue(sema.mod, sema.arena, 0);
21177 var accum: Value = try operand_val.elemValue(mod, sema.arena, 0);
2114021178 var elem_buf: Value.ElemValueBuffer = undefined;
2114121179 var i: u32 = 1;
2114221180 while (i < vec_len) : (i += 1) {
21143 const elem_val = operand_val.elemValueBuffer(sema.mod, i, &elem_buf);
21181 const elem_val = operand_val.elemValueBuffer(mod, i, &elem_buf);
2114421182 switch (operation) {
21145 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, sema.mod),
21146 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, sema.mod),
21147 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, sema.mod),
21148 .Min => accum = accum.numberMin(elem_val, target),
21149 .Max => accum = accum.numberMax(elem_val, target),
21183 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, mod),
21184 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, mod),
21185 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, mod),
21186 .Min => accum = accum.numberMin(elem_val, mod),
21187 .Max => accum = accum.numberMax(elem_val, mod),
2115021188 .Add => accum = try sema.numberAddWrapScalar(accum, elem_val, scalar_ty),
21151 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, sema.mod),
21189 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, mod),
2115221190 }
2115321191 }
2115421192 return sema.addConstant(scalar_ty, accum);
......@@ -21165,6 +21203,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2116521203}
2116621204
2116721205fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
21206 const mod = sema.mod;
2116821207 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2116921208 const extra = sema.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data;
2117021209 const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
......@@ -21177,7 +21216,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2117721216 var mask = try sema.resolveInst(extra.mask);
2117821217 var mask_ty = sema.typeOf(mask);
2117921218
21180 const mask_len = switch (sema.typeOf(mask).zigTypeTag()) {
21219 const mask_len = switch (sema.typeOf(mask).zigTypeTag(mod)) {
2118121220 .Array, .Vector => sema.typeOf(mask).arrayLen(),
2118221221 else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(sema.mod)}),
2118321222 };
......@@ -21200,6 +21239,7 @@ fn analyzeShuffle(
2120021239 mask: Value,
2120121240 mask_len: u32,
2120221241) CompileError!Air.Inst.Ref {
21242 const mod = sema.mod;
2120321243 const a_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = src_node };
2120421244 const b_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = src_node };
2120521245 const mask_src: LazySrcLoc = .{ .node_offset_builtin_call_arg3 = src_node };
......@@ -21211,7 +21251,7 @@ fn analyzeShuffle(
2121121251 .elem_type = elem_ty,
2121221252 });
2121321253
21214 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag()) {
21254 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag(mod)) {
2121521255 .Array, .Vector => sema.typeOf(a).arrayLen(),
2121621256 .Undefined => null,
2121721257 else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{
......@@ -21219,7 +21259,7 @@ fn analyzeShuffle(
2121921259 sema.typeOf(a).fmt(sema.mod),
2122021260 }),
2122121261 };
21222 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag()) {
21262 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag(mod)) {
2122321263 .Array, .Vector => sema.typeOf(b).arrayLen(),
2122421264 .Undefined => null,
2122521265 else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{
......@@ -21255,7 +21295,7 @@ fn analyzeShuffle(
2125521295 var buf: Value.ElemValueBuffer = undefined;
2125621296 const elem = mask.elemValueBuffer(sema.mod, i, &buf);
2125721297 if (elem.isUndef()) continue;
21258 const int = elem.toSignedInt(sema.mod.getTarget());
21298 const int = elem.toSignedInt(mod);
2125921299 var unsigned: u32 = undefined;
2126021300 var chosen: u32 = undefined;
2126121301 if (int >= 0) {
......@@ -21297,7 +21337,7 @@ fn analyzeShuffle(
2129721337 values[i] = Value.undef;
2129821338 continue;
2129921339 }
21300 const int = mask_elem_val.toSignedInt(sema.mod.getTarget());
21340 const int = mask_elem_val.toSignedInt(mod);
2130121341 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int);
2130221342 if (int >= 0) {
2130321343 values[i] = try a_val.elemValue(sema.mod, sema.arena, unsigned);
......@@ -21356,6 +21396,7 @@ fn analyzeShuffle(
2135621396}
2135721397
2135821398fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
21399 const mod = sema.mod;
2135921400 const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;
2136021401
2136121402 const src = LazySrcLoc.nodeOffset(extra.node);
......@@ -21369,7 +21410,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2136921410 const pred_uncoerced = try sema.resolveInst(extra.pred);
2137021411 const pred_ty = sema.typeOf(pred_uncoerced);
2137121412
21372 const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison()) {
21413 const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison(mod)) {
2137321414 .Vector, .Array => pred_ty.arrayLen(),
2137421415 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(sema.mod)}),
2137521416 };
......@@ -21489,6 +21530,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2148921530}
2149021531
2149121532fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
21533 const mod = sema.mod;
2149221534 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2149321535 const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data;
2149421536 const src = inst_data.src();
......@@ -21505,7 +21547,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2150521547 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);
2150621548 const op = try sema.resolveAtomicRmwOp(block, op_src, extra.operation);
2150721549
21508 switch (elem_ty.zigTypeTag()) {
21550 switch (elem_ty.zigTypeTag(mod)) {
2150921551 .Enum => if (op != .Xchg) {
2151021552 return sema.fail(block, op_src, "@atomicRmw with enum only allowed with .Xchg", .{});
2151121553 },
......@@ -21536,7 +21578,6 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2153621578 break :rs operand_src;
2153721579 };
2153821580 if (ptr_val.isComptimeMutablePtr()) {
21539 const target = sema.mod.getTarget();
2154021581 const ptr_ty = sema.typeOf(ptr);
2154121582 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;
2154221583 const new_val = switch (op) {
......@@ -21544,12 +21585,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2154421585 .Xchg => operand_val,
2154521586 .Add => try sema.numberAddWrapScalar(stored_val, operand_val, elem_ty),
2154621587 .Sub => try sema.numberSubWrapScalar(stored_val, operand_val, elem_ty),
21547 .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, sema.mod),
21548 .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, sema.mod),
21549 .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, sema.mod),
21550 .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, sema.mod),
21551 .Max => stored_val.numberMax (operand_val, target),
21552 .Min => stored_val.numberMin (operand_val, target),
21588 .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, mod),
21589 .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, mod),
21590 .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, mod),
21591 .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, mod),
21592 .Max => stored_val.numberMax (operand_val, mod),
21593 .Min => stored_val.numberMin (operand_val, mod),
2155321594 // zig fmt: on
2155421595 };
2155521596 try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty);
......@@ -21623,8 +21664,9 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2162321664 const maybe_mulend1 = try sema.resolveMaybeUndefVal(mulend1);
2162421665 const maybe_mulend2 = try sema.resolveMaybeUndefVal(mulend2);
2162521666 const maybe_addend = try sema.resolveMaybeUndefVal(addend);
21667 const mod = sema.mod;
2162621668
21627 switch (ty.zigTypeTag()) {
21669 switch (ty.zigTypeTag(mod)) {
2162821670 .ComptimeFloat, .Float, .Vector => {},
2162921671 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(sema.mod)}),
2163021672 }
......@@ -21743,7 +21785,6 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2174321785
2174421786 const callee_ty = sema.typeOf(func);
2174521787 const func_ty = try sema.checkCallArgumentCount(block, func, func_src, callee_ty, resolved_args.len, false);
21746
2174721788 const ensure_result_used = extra.flags.ensure_result_used;
2174821789 return sema.analyzeCall(block, func, func_ty, func_src, call_src, modifier, ensure_result_used, resolved_args, null, null);
2174921790}
......@@ -21760,13 +21801,14 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2176021801 const field_name = try sema.resolveConstString(block, name_src, extra.field_name, "field name must be comptime-known");
2176121802 const field_ptr = try sema.resolveInst(extra.field_ptr);
2176221803 const field_ptr_ty = sema.typeOf(field_ptr);
21804 const mod = sema.mod;
2176321805
21764 if (parent_ty.zigTypeTag() != .Struct and parent_ty.zigTypeTag() != .Union) {
21806 if (parent_ty.zigTypeTag(mod) != .Struct and parent_ty.zigTypeTag(mod) != .Union) {
2176521807 return sema.fail(block, ty_src, "expected struct or union type, found '{}'", .{parent_ty.fmt(sema.mod)});
2176621808 }
2176721809 try sema.resolveTypeLayout(parent_ty);
2176821810
21769 const field_index = switch (parent_ty.zigTypeTag()) {
21811 const field_index = switch (parent_ty.zigTypeTag(mod)) {
2177021812 .Struct => blk: {
2177121813 if (parent_ty.isTuple()) {
2177221814 if (mem.eql(u8, field_name, "len")) {
......@@ -21781,7 +21823,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2178121823 else => unreachable,
2178221824 };
2178321825
21784 if (parent_ty.zigTypeTag() == .Struct and parent_ty.structFieldIsComptime(field_index)) {
21826 if (parent_ty.zigTypeTag(mod) == .Struct and parent_ty.structFieldIsComptime(field_index)) {
2178521827 return sema.fail(block, src, "cannot get @fieldParentPtr of a comptime field", .{});
2178621828 }
2178721829
......@@ -21913,15 +21955,14 @@ fn analyzeMinMax(
2191321955) CompileError!Air.Inst.Ref {
2191421956 assert(operands.len == operand_srcs.len);
2191521957 assert(operands.len > 0);
21958 const mod = sema.mod;
2191621959
2191721960 if (operands.len == 1) return operands[0];
2191821961
21919 const mod = sema.mod;
21920 const target = mod.getTarget();
2192121962 const opFunc = switch (air_tag) {
2192221963 .min => Value.numberMin,
2192321964 .max => Value.numberMax,
21924 else => unreachable,
21965 else => @compileError("unreachable"),
2192521966 };
2192621967
2192721968 // First, find all comptime-known arguments, and get their min/max
......@@ -21949,7 +21990,7 @@ fn analyzeMinMax(
2194921990 try sema.resolveLazyValue(operand_val);
2195021991
2195121992 const vec_len = simd_op.len orelse {
21952 const result_val = opFunc(cur_val, operand_val, target);
21993 const result_val = opFunc(cur_val, operand_val, mod);
2195321994 cur_minmax = try sema.addConstant(simd_op.result_ty, result_val);
2195421995 continue;
2195521996 };
......@@ -21959,7 +22000,7 @@ fn analyzeMinMax(
2195922000 for (elems, 0..) |*elem, i| {
2196022001 const lhs_elem_val = cur_val.elemValueBuffer(mod, i, &lhs_buf);
2196122002 const rhs_elem_val = operand_val.elemValueBuffer(mod, i, &rhs_buf);
21962 elem.* = opFunc(lhs_elem_val, rhs_elem_val, target);
22003 elem.* = opFunc(lhs_elem_val, rhs_elem_val, mod);
2196322004 }
2196422005 cur_minmax = try sema.addConstant(
2196522006 simd_op.result_ty,
......@@ -21984,7 +22025,7 @@ fn analyzeMinMax(
2198422025 break :refined orig_ty;
2198522026 }
2198622027
21987 const refined_ty = if (orig_ty.zigTypeTag() == .Vector) blk: {
22028 const refined_ty = if (orig_ty.zigTypeTag(mod) == .Vector) blk: {
2198822029 const elem_ty = orig_ty.childType();
2198922030 const len = orig_ty.vectorLen();
2199022031
......@@ -21996,16 +22037,16 @@ fn analyzeMinMax(
2199622037 for (1..len) |idx| {
2199722038 const elem_val = try val.elemValue(mod, sema.arena, idx);
2199822039 if (elem_val.isUndef()) break :blk orig_ty; // can't refine undef
21999 if (Value.order(elem_val, cur_min, target).compare(.lt)) cur_min = elem_val;
22000 if (Value.order(elem_val, cur_max, target).compare(.gt)) cur_max = elem_val;
22040 if (Value.order(elem_val, cur_min, mod).compare(.lt)) cur_min = elem_val;
22041 if (Value.order(elem_val, cur_max, mod).compare(.gt)) cur_max = elem_val;
2200122042 }
2200222043
22003 const refined_elem_ty = try Type.intFittingRange(target, sema.arena, cur_min, cur_max);
22044 const refined_elem_ty = try mod.intFittingRange(cur_min, cur_max);
2200422045 break :blk try Type.vector(sema.arena, len, refined_elem_ty);
2200522046 } else blk: {
2200622047 if (orig_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats
2200722048 if (val.isUndef()) break :blk orig_ty; // can't refine undef
22008 break :blk try Type.intFittingRange(target, sema.arena, val, val);
22049 break :blk try mod.intFittingRange(val, val);
2200922050 };
2201022051
2201122052 // Apply the refined type to the current value - this isn't strictly necessary in the
......@@ -22061,7 +22102,7 @@ fn analyzeMinMax(
2206122102 // Finally, refine the type based on the comptime-known bound.
2206222103 if (known_undef) break :refine; // can't refine undef
2206322104 const unrefined_ty = sema.typeOf(cur_minmax.?);
22064 const is_vector = unrefined_ty.zigTypeTag() == .Vector;
22105 const is_vector = unrefined_ty.zigTypeTag(mod) == .Vector;
2206522106 const comptime_elem_ty = if (is_vector) comptime_ty.childType() else comptime_ty;
2206622107 const unrefined_elem_ty = if (is_vector) unrefined_ty.childType() else unrefined_ty;
2206722108
......@@ -22069,18 +22110,18 @@ fn analyzeMinMax(
2206922110
2207022111 // Compute the final bounds based on the runtime type and the comptime-known bound type
2207122112 const min_val = switch (air_tag) {
22072 .min => try unrefined_elem_ty.minInt(sema.arena, target),
22073 .max => try comptime_elem_ty.minInt(sema.arena, target), // @max(ct, rt) >= ct
22113 .min => try unrefined_elem_ty.minInt(sema.arena, mod),
22114 .max => try comptime_elem_ty.minInt(sema.arena, mod), // @max(ct, rt) >= ct
2207422115 else => unreachable,
2207522116 };
2207622117 const max_val = switch (air_tag) {
22077 .min => try comptime_elem_ty.maxInt(sema.arena, target), // @min(ct, rt) <= ct
22078 .max => try unrefined_elem_ty.maxInt(sema.arena, target),
22118 .min => try comptime_elem_ty.maxInt(sema.arena, mod), // @min(ct, rt) <= ct
22119 .max => try unrefined_elem_ty.maxInt(sema.arena, mod),
2207922120 else => unreachable,
2208022121 };
2208122122
2208222123 // Find the smallest type which can contain these bounds
22083 const final_elem_ty = try Type.intFittingRange(target, sema.arena, min_val, max_val);
22124 const final_elem_ty = try mod.intFittingRange(min_val, max_val);
2208422125
2208522126 const final_ty = if (is_vector)
2208622127 try Type.vector(sema.arena, unrefined_ty.vectorLen(), final_elem_ty)
......@@ -22132,6 +22173,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2213222173 const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);
2213322174 const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr);
2213422175 const target = sema.mod.getTarget();
22176 const mod = sema.mod;
2213522177
2213622178 if (dest_ty.isConstPtr()) {
2213722179 return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{});
......@@ -22196,7 +22238,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2219622238 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: {
2219722239 if (!dest_ptr_val.isComptimeMutablePtr()) break :rs dest_src;
2219822240 if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| {
22199 const len_u64 = (try len_val.?.getUnsignedIntAdvanced(target, sema)).?;
22241 const len_u64 = (try len_val.?.getUnsignedIntAdvanced(mod, sema)).?;
2220022242 const len = try sema.usizeCast(block, dest_src, len_u64);
2220122243 for (0..len) |i| {
2220222244 const elem_index = try sema.addIntUnsigned(Type.usize, i);
......@@ -22239,12 +22281,12 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2223922281 // lowering. The AIR instruction requires pointers with element types of
2224022282 // equal ABI size.
2224122283
22242 if (dest_ty.zigTypeTag() != .Pointer or src_ty.zigTypeTag() != .Pointer) {
22284 if (dest_ty.zigTypeTag(mod) != .Pointer or src_ty.zigTypeTag(mod) != .Pointer) {
2224322285 return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the source or destination iterable is a tuple", .{});
2224422286 }
2224522287
22246 const dest_elem_ty = dest_ty.elemType2();
22247 const src_elem_ty = src_ty.elemType2();
22288 const dest_elem_ty = dest_ty.elemType2(mod);
22289 const src_elem_ty = src_ty.elemType2(mod);
2224822290 if (.ok != try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, true, target, dest_src, src_src)) {
2224922291 return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the element types have different ABI sizes", .{});
2225022292 }
......@@ -22255,7 +22297,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2225522297 var new_dest_ptr = dest_ptr;
2225622298 var new_src_ptr = src_ptr;
2225722299 if (len_val) |val| {
22258 const len = val.toUnsignedInt(target);
22300 const len = val.toUnsignedInt(mod);
2225922301 if (len == 0) {
2226022302 // This AIR instruction guarantees length > 0 if it is comptime-known.
2226122303 return;
......@@ -22320,6 +22362,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2232022362}
2232122363
2232222364fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
22365 const mod = sema.mod;
2232322366 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2232422367 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2232522368 const src = inst_data.src();
......@@ -22334,14 +22377,13 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2233422377 return sema.fail(block, dest_src, "cannot memset constant pointer", .{});
2233522378 }
2233622379
22337 const dest_elem_ty = dest_ptr_ty.elemType2();
22338 const target = sema.mod.getTarget();
22380 const dest_elem_ty = dest_ptr_ty.elemType2(mod);
2233922381
2234022382 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: {
2234122383 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, "len", dest_src);
2234222384 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse
2234322385 break :rs dest_src;
22344 const len_u64 = (try len_val.getUnsignedIntAdvanced(target, sema)).?;
22386 const len_u64 = (try len_val.getUnsignedIntAdvanced(mod, sema)).?;
2234522387 const len = try sema.usizeCast(block, dest_src, len_u64);
2234622388 if (len == 0) {
2234722389 // This AIR instruction guarantees length > 0 if it is comptime-known.
......@@ -22499,9 +22541,10 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2249922541 const tracy = trace(@src());
2250022542 defer tracy.end();
2250122543
22544 const mod = sema.mod;
2250222545 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2250322546 const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
22504 const target = sema.mod.getTarget();
22547 const target = mod.getTarget();
2250522548
2250622549 const align_src: LazySrcLoc = .{ .node_offset_fn_type_align = inst_data.src_node };
2250722550 const addrspace_src: LazySrcLoc = .{ .node_offset_fn_type_addrspace = inst_data.src_node };
......@@ -22535,7 +22578,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2253522578 if (val.tag() == .generic_poison) {
2253622579 break :blk null;
2253722580 }
22538 const alignment = @intCast(u32, val.toUnsignedInt(target));
22581 const alignment = @intCast(u32, val.toUnsignedInt(mod));
2253922582 try sema.validateAlign(block, align_src, alignment);
2254022583 if (alignment == target_util.defaultFunctionAlignment(target)) {
2254122584 break :blk 0;
......@@ -22551,7 +22594,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2255122594 },
2255222595 else => |e| return e,
2255322596 };
22554 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(target));
22597 const alignment = @intCast(u32, align_tv.val.toUnsignedInt(mod));
2255522598 try sema.validateAlign(block, align_src, alignment);
2255622599 if (alignment == target_util.defaultFunctionAlignment(target)) {
2255722600 break :blk 0;
......@@ -22642,8 +22685,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2264222685 extra_index += body.len;
2264322686
2264422687 const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type, "return type must be comptime-known");
22645 var buffer: Value.ToTypeBuffer = undefined;
22646 const ty = try val.toType(&buffer).copy(sema.arena);
22688 const ty = try val.toType().copy(sema.arena);
2264722689 break :blk ty;
2264822690 } else if (extra.data.bits.has_ret_ty_ref) blk: {
2264922691 const ret_ty_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
......@@ -22654,8 +22696,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2265422696 },
2265522697 else => |e| return e,
2265622698 };
22657 var buffer: Value.ToTypeBuffer = undefined;
22658 const ty = try ret_ty_tv.val.toType(&buffer).copy(sema.arena);
22699 const ty = try ret_ty_tv.val.toType().copy(sema.arena);
2265922700 break :blk ty;
2266022701 } else Type.void;
2266122702
......@@ -22727,13 +22768,14 @@ fn zirCDefine(
2272722768 block: *Block,
2272822769 extended: Zir.Inst.Extended.InstData,
2272922770) CompileError!Air.Inst.Ref {
22771 const mod = sema.mod;
2273022772 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
2273122773 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
2273222774 const val_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
2273322775
2273422776 const name = try sema.resolveConstString(block, name_src, extra.lhs, "name of macro being undefined must be comptime-known");
2273522777 const rhs = try sema.resolveInst(extra.rhs);
22736 if (sema.typeOf(rhs).zigTypeTag() != .Void) {
22778 if (sema.typeOf(rhs).zigTypeTag(mod) != .Void) {
2273722779 const value = try sema.resolveConstString(block, val_src, extra.rhs, "value of macro being undefined must be comptime-known");
2273822780 try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value });
2273922781 } else {
......@@ -22799,9 +22841,9 @@ fn resolvePrefetchOptions(
2279922841 src: LazySrcLoc,
2280022842 zir_ref: Zir.Inst.Ref,
2280122843) CompileError!std.builtin.PrefetchOptions {
22844 const mod = sema.mod;
2280222845 const options_ty = try sema.getBuiltinType("PrefetchOptions");
2280322846 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
22804 const target = sema.mod.getTarget();
2280522847
2280622848 const rw_src = sema.maybeOptionsSrc(block, src, "rw");
2280722849 const locality_src = sema.maybeOptionsSrc(block, src, "locality");
......@@ -22818,7 +22860,7 @@ fn resolvePrefetchOptions(
2281822860
2281922861 return std.builtin.PrefetchOptions{
2282022862 .rw = rw_val.toEnum(std.builtin.PrefetchOptions.Rw),
22821 .locality = @intCast(u2, locality_val.toUnsignedInt(target)),
22863 .locality = @intCast(u2, locality_val.toUnsignedInt(mod)),
2282222864 .cache = cache_val.toEnum(std.builtin.PrefetchOptions.Cache),
2282322865 };
2282422866}
......@@ -22887,7 +22929,7 @@ fn resolveExternOptions(
2288722929 const is_thread_local = try sema.fieldVal(block, src, options, "is_thread_local", thread_local_src);
2288822930 const is_thread_local_val = try sema.resolveConstValue(block, thread_local_src, is_thread_local, "threadlocality of the extern symbol must be comptime-known");
2288922931
22890 const library_name = if (!library_name_val.isNull()) blk: {
22932 const library_name = if (!library_name_val.isNull(mod)) blk: {
2289122933 const payload = library_name_val.castTag(.opt_payload).?.data;
2289222934 const library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, mod);
2289322935 if (library_name.len == 0) {
......@@ -22917,17 +22959,17 @@ fn zirBuiltinExtern(
2291722959 block: *Block,
2291822960 extended: Zir.Inst.Extended.InstData,
2291922961) CompileError!Air.Inst.Ref {
22962 const mod = sema.mod;
2292022963 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
2292122964 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
2292222965 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
2292322966
2292422967 var ty = try sema.resolveType(block, ty_src, extra.lhs);
22925 if (!ty.isPtrAtRuntime()) {
22968 if (!ty.isPtrAtRuntime(mod)) {
2292622969 return sema.fail(block, ty_src, "expected (optional) pointer", .{});
2292722970 }
2292822971 if (!try sema.validateExternType(ty.childType(), .other)) {
2292922972 const msg = msg: {
22930 const mod = sema.mod;
2293122973 const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});
2293222974 errdefer msg.destroy(sema.gpa);
2293322975 const src_decl = sema.mod.declPtr(block.src_decl);
......@@ -22945,7 +22987,7 @@ fn zirBuiltinExtern(
2294522987 else => |e| return e,
2294622988 };
2294722989
22948 if (options.linkage == .Weak and !ty.ptrAllowsZero()) {
22990 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {
2294922991 ty = try Type.optional(sema.arena, ty);
2295022992 }
2295122993
......@@ -23087,7 +23129,7 @@ fn validateVarType(
2308723129
2308823130 const src_decl = mod.declPtr(block.src_decl);
2308923131 try sema.explainWhyTypeIsComptime(msg, src.toSrcLoc(src_decl), var_ty);
23090 if (var_ty.zigTypeTag() == .ComptimeInt or var_ty.zigTypeTag() == .ComptimeFloat) {
23132 if (var_ty.zigTypeTag(mod) == .ComptimeInt or var_ty.zigTypeTag(mod) == .ComptimeFloat) {
2309123133 try sema.errNote(block, src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});
2309223134 }
2309323135
......@@ -23101,8 +23143,9 @@ fn validateRunTimeType(
2310123143 var_ty: Type,
2310223144 is_extern: bool,
2310323145) CompileError!bool {
23146 const mod = sema.mod;
2310423147 var ty = var_ty;
23105 while (true) switch (ty.zigTypeTag()) {
23148 while (true) switch (ty.zigTypeTag(mod)) {
2310623149 .Bool,
2310723150 .Int,
2310823151 .Float,
......@@ -23126,9 +23169,9 @@ fn validateRunTimeType(
2312623169
2312723170 .Pointer => {
2312823171 const elem_ty = ty.childType();
23129 switch (elem_ty.zigTypeTag()) {
23172 switch (elem_ty.zigTypeTag(mod)) {
2313023173 .Opaque => return true,
23131 .Fn => return elem_ty.isFnOrHasRuntimeBits(),
23174 .Fn => return elem_ty.isFnOrHasRuntimeBits(mod),
2313223175 else => ty = elem_ty,
2313323176 }
2313423177 },
......@@ -23174,7 +23217,7 @@ fn explainWhyTypeIsComptimeInner(
2317423217 type_set: *TypeSet,
2317523218) CompileError!void {
2317623219 const mod = sema.mod;
23177 switch (ty.zigTypeTag()) {
23220 switch (ty.zigTypeTag(mod)) {
2317823221 .Bool,
2317923222 .Int,
2318023223 .Float,
......@@ -23211,8 +23254,8 @@ fn explainWhyTypeIsComptimeInner(
2321123254 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.elemType(), type_set);
2321223255 },
2321323256 .Pointer => {
23214 const elem_ty = ty.elemType2();
23215 if (elem_ty.zigTypeTag() == .Fn) {
23257 const elem_ty = ty.elemType2(mod);
23258 if (elem_ty.zigTypeTag(mod) == .Fn) {
2321623259 const fn_info = elem_ty.fnInfo();
2321723260 if (fn_info.is_generic) {
2321823261 try mod.errNoteNonLazy(src_loc, msg, "function is generic", .{});
......@@ -23221,7 +23264,7 @@ fn explainWhyTypeIsComptimeInner(
2322123264 .Inline => try mod.errNoteNonLazy(src_loc, msg, "function has inline calling convention", .{}),
2322223265 else => {},
2322323266 }
23224 if (fn_info.return_type.comptimeOnly()) {
23267 if (fn_info.return_type.comptimeOnly(mod)) {
2322523268 try mod.errNoteNonLazy(src_loc, msg, "function has a comptime-only return type", .{});
2322623269 }
2322723270 return;
......@@ -23295,7 +23338,8 @@ fn validateExternType(
2329523338 ty: Type,
2329623339 position: ExternPosition,
2329723340) !bool {
23298 switch (ty.zigTypeTag()) {
23341 const mod = sema.mod;
23342 switch (ty.zigTypeTag(mod)) {
2329923343 .Type,
2330023344 .ComptimeFloat,
2330123345 .ComptimeInt,
......@@ -23314,7 +23358,7 @@ fn validateExternType(
2331423358 .AnyFrame,
2331523359 => return true,
2331623360 .Pointer => return !(ty.isSlice() or try sema.typeRequiresComptime(ty)),
23317 .Int => switch (ty.intInfo(sema.mod.getTarget()).bits) {
23361 .Int => switch (ty.intInfo(mod).bits) {
2331823362 8, 16, 32, 64, 128 => return true,
2331923363 else => return false,
2332023364 },
......@@ -23329,14 +23373,12 @@ fn validateExternType(
2332923373 return !Type.fnCallingConventionAllowsZigTypes(target, ty.fnCallingConvention());
2333023374 },
2333123375 .Enum => {
23332 var buf: Type.Payload.Bits = undefined;
23333 return sema.validateExternType(ty.intTagType(&buf), position);
23376 return sema.validateExternType(ty.intTagType(), position);
2333423377 },
2333523378 .Struct, .Union => switch (ty.containerLayout()) {
2333623379 .Extern => return true,
2333723380 .Packed => {
23338 const target = sema.mod.getTarget();
23339 const bit_size = try ty.bitSizeAdvanced(target, sema);
23381 const bit_size = try ty.bitSizeAdvanced(mod, sema);
2334023382 switch (bit_size) {
2334123383 8, 16, 32, 64, 128 => return true,
2334223384 else => return false,
......@@ -23346,10 +23388,10 @@ fn validateExternType(
2334623388 },
2334723389 .Array => {
2334823390 if (position == .ret_ty or position == .param_ty) return false;
23349 return sema.validateExternType(ty.elemType2(), .element);
23391 return sema.validateExternType(ty.elemType2(mod), .element);
2335023392 },
23351 .Vector => return sema.validateExternType(ty.elemType2(), .element),
23352 .Optional => return ty.isPtrLikeOptional(),
23393 .Vector => return sema.validateExternType(ty.elemType2(mod), .element),
23394 .Optional => return ty.isPtrLikeOptional(mod),
2335323395 }
2335423396}
2335523397
......@@ -23361,7 +23403,7 @@ fn explainWhyTypeIsNotExtern(
2336123403 position: ExternPosition,
2336223404) CompileError!void {
2336323405 const mod = sema.mod;
23364 switch (ty.zigTypeTag()) {
23406 switch (ty.zigTypeTag(mod)) {
2336523407 .Opaque,
2336623408 .Bool,
2336723409 .Float,
......@@ -23390,7 +23432,7 @@ fn explainWhyTypeIsNotExtern(
2339023432 },
2339123433 .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
2339223434 .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
23393 .Int => if (!std.math.isPowerOfTwo(ty.intInfo(sema.mod.getTarget()).bits)) {
23435 .Int => if (!std.math.isPowerOfTwo(ty.intInfo(mod).bits)) {
2339423436 try mod.errNoteNonLazy(src_loc, msg, "only integers with power of two bits are extern compatible", .{});
2339523437 } else {
2339623438 try mod.errNoteNonLazy(src_loc, msg, "only integers with 8, 16, 32, 64 and 128 bits are extern compatible", .{});
......@@ -23409,8 +23451,7 @@ fn explainWhyTypeIsNotExtern(
2340923451 }
2341023452 },
2341123453 .Enum => {
23412 var buf: Type.Payload.Bits = undefined;
23413 const tag_ty = ty.intTagType(&buf);
23454 const tag_ty = ty.intTagType();
2341423455 try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});
2341523456 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
2341623457 },
......@@ -23422,17 +23463,17 @@ fn explainWhyTypeIsNotExtern(
2342223463 } else if (position == .param_ty) {
2342323464 return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{});
2342423465 }
23425 try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), .element);
23466 try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(mod), .element);
2342623467 },
23427 .Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(), .element),
23468 .Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(mod), .element),
2342823469 .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}),
2342923470 }
2343023471}
2343123472
2343223473/// Returns true if `ty` is allowed in packed types.
2343323474/// Does *NOT* require `ty` to be resolved in any way.
23434fn validatePackedType(ty: Type) bool {
23435 switch (ty.zigTypeTag()) {
23475fn validatePackedType(ty: Type, mod: *const Module) bool {
23476 switch (ty.zigTypeTag(mod)) {
2343623477 .Type,
2343723478 .ComptimeFloat,
2343823479 .ComptimeInt,
......@@ -23448,7 +23489,7 @@ fn validatePackedType(ty: Type) bool {
2344823489 .Fn,
2344923490 .Array,
2345023491 => return false,
23451 .Optional => return ty.isPtrLikeOptional(),
23492 .Optional => return ty.isPtrLikeOptional(mod),
2345223493 .Void,
2345323494 .Bool,
2345423495 .Float,
......@@ -23468,7 +23509,7 @@ fn explainWhyTypeIsNotPacked(
2346823509 ty: Type,
2346923510) CompileError!void {
2347023511 const mod = sema.mod;
23471 switch (ty.zigTypeTag()) {
23512 switch (ty.zigTypeTag(mod)) {
2347223513 .Void,
2347323514 .Bool,
2347423515 .Float,
......@@ -23731,6 +23772,7 @@ fn panicSentinelMismatch(
2373123772 sentinel_index: Air.Inst.Ref,
2373223773) !void {
2373323774 assert(!parent_block.is_comptime);
23775 const mod = sema.mod;
2373423776 const expected_sentinel_val = maybe_sentinel orelse return;
2373523777 const expected_sentinel = try sema.addConstant(sentinel_ty, expected_sentinel_val);
2373623778
......@@ -23743,7 +23785,7 @@ fn panicSentinelMismatch(
2374323785 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);
2374423786 };
2374523787
23746 const ok = if (sentinel_ty.zigTypeTag() == .Vector) ok: {
23788 const ok = if (sentinel_ty.zigTypeTag(mod) == .Vector) ok: {
2374723789 const eql =
2374823790 try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq);
2374923791 break :ok try parent_block.addInst(.{
......@@ -23753,7 +23795,7 @@ fn panicSentinelMismatch(
2375323795 .operation = .And,
2375423796 } },
2375523797 });
23756 } else if (sentinel_ty.isSelfComparable(true))
23798 } else if (sentinel_ty.isSelfComparable(mod, true))
2375723799 try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)
2375823800 else {
2375923801 const panic_fn = try sema.getBuiltin("checkNonScalarSentinel");
......@@ -23848,6 +23890,7 @@ fn fieldVal(
2384823890 // When editing this function, note that there is corresponding logic to be edited
2384923891 // in `fieldPtr`. This function takes a value and returns a value.
2385023892
23893 const mod = sema.mod;
2385123894 const arena = sema.arena;
2385223895 const object_src = src; // TODO better source location
2385323896 const object_ty = sema.typeOf(object);
......@@ -23862,7 +23905,7 @@ fn fieldVal(
2386223905 else
2386323906 object_ty;
2386423907
23865 switch (inner_ty.zigTypeTag()) {
23908 switch (inner_ty.zigTypeTag(mod)) {
2386623909 .Array => {
2386723910 if (mem.eql(u8, field_name, "len")) {
2386823911 return sema.addConstant(
......@@ -23926,10 +23969,9 @@ fn fieldVal(
2392623969 object;
2392723970
2392823971 const val = (try sema.resolveDefinedValue(block, object_src, dereffed_type)).?;
23929 var to_type_buffer: Value.ToTypeBuffer = undefined;
23930 const child_type = val.toType(&to_type_buffer);
23972 const child_type = val.toType();
2393123973
23932 switch (try child_type.zigTypeTagOrPoison()) {
23974 switch (try child_type.zigTypeTagOrPoison(mod)) {
2393323975 .ErrorSet => {
2393423976 const name: []const u8 = if (child_type.castTag(.error_set)) |payload| blk: {
2393523977 if (payload.data.names.getEntry(field_name)) |entry| {
......@@ -23997,7 +24039,7 @@ fn fieldVal(
2399724039 const msg = try sema.errMsg(block, src, "type '{}' has no members", .{child_type.fmt(sema.mod)});
2399824040 errdefer msg.destroy(sema.gpa);
2399924041 if (child_type.isSlice()) try sema.errNote(block, src, msg, "slice values have 'len' and 'ptr' members", .{});
24000 if (child_type.zigTypeTag() == .Array) try sema.errNote(block, src, msg, "array values have 'len' member", .{});
24042 if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(block, src, msg, "array values have 'len' member", .{});
2400124043 break :msg msg;
2400224044 };
2400324045 return sema.failWithOwnedErrorMsg(msg);
......@@ -24035,9 +24077,10 @@ fn fieldPtr(
2403524077 // When editing this function, note that there is corresponding logic to be edited
2403624078 // in `fieldVal`. This function takes a pointer and returns a pointer.
2403724079
24080 const mod = sema.mod;
2403824081 const object_ptr_src = src; // TODO better source location
2403924082 const object_ptr_ty = sema.typeOf(object_ptr);
24040 const object_ty = switch (object_ptr_ty.zigTypeTag()) {
24083 const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) {
2404124084 .Pointer => object_ptr_ty.elemType(),
2404224085 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(sema.mod)}),
2404324086 };
......@@ -24052,7 +24095,7 @@ fn fieldPtr(
2405224095 else
2405324096 object_ty;
2405424097
24055 switch (inner_ty.zigTypeTag()) {
24098 switch (inner_ty.zigTypeTag(mod)) {
2405624099 .Array => {
2405724100 if (mem.eql(u8, field_name, "len")) {
2405824101 var anon_decl = try block.startAnonDecl();
......@@ -24142,10 +24185,9 @@ fn fieldPtr(
2414224185 result;
2414324186
2414424187 const val = (sema.resolveDefinedValue(block, src, inner) catch unreachable).?;
24145 var to_type_buffer: Value.ToTypeBuffer = undefined;
24146 const child_type = val.toType(&to_type_buffer);
24188 const child_type = val.toType();
2414724189
24148 switch (child_type.zigTypeTag()) {
24190 switch (child_type.zigTypeTag(mod)) {
2414924191 .ErrorSet => {
2415024192 // TODO resolve inferred error sets
2415124193 const name: []const u8 = if (child_type.castTag(.error_set)) |payload| blk: {
......@@ -24258,15 +24300,16 @@ fn fieldCallBind(
2425824300 // When editing this function, note that there is corresponding logic to be edited
2425924301 // in `fieldVal`. This function takes a pointer and returns a pointer.
2426024302
24303 const mod = sema.mod;
2426124304 const raw_ptr_src = src; // TODO better source location
2426224305 const raw_ptr_ty = sema.typeOf(raw_ptr);
24263 const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and (raw_ptr_ty.ptrSize() == .One or raw_ptr_ty.ptrSize() == .C))
24306 const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize() == .One or raw_ptr_ty.ptrSize() == .C))
2426424307 raw_ptr_ty.childType()
2426524308 else
2426624309 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(sema.mod)});
2426724310
2426824311 // Optionally dereference a second pointer to get the concrete type.
24269 const is_double_ptr = inner_ty.zigTypeTag() == .Pointer and inner_ty.ptrSize() == .One;
24312 const is_double_ptr = inner_ty.zigTypeTag(mod) == .Pointer and inner_ty.ptrSize() == .One;
2427024313 const concrete_ty = if (is_double_ptr) inner_ty.childType() else inner_ty;
2427124314 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;
2427224315 const object_ptr = if (is_double_ptr)
......@@ -24275,7 +24318,7 @@ fn fieldCallBind(
2427524318 raw_ptr;
2427624319
2427724320 find_field: {
24278 switch (concrete_ty.zigTypeTag()) {
24321 switch (concrete_ty.zigTypeTag(mod)) {
2427924322 .Struct => {
2428024323 const struct_ty = try sema.resolveTypeFields(concrete_ty);
2428124324 if (struct_ty.castTag(.@"struct")) |struct_obj| {
......@@ -24321,21 +24364,21 @@ fn fieldCallBind(
2432124364 }
2432224365
2432324366 // If we get here, we need to look for a decl in the struct type instead.
24324 const found_decl = switch (concrete_ty.zigTypeTag()) {
24367 const found_decl = switch (concrete_ty.zigTypeTag(mod)) {
2432524368 .Struct, .Opaque, .Union, .Enum => found_decl: {
2432624369 if (concrete_ty.getNamespace()) |namespace| {
2432724370 if (try sema.namespaceLookup(block, src, namespace, field_name)) |decl_idx| {
2432824371 try sema.addReferencedBy(block, src, decl_idx);
2432924372 const decl_val = try sema.analyzeDeclVal(block, src, decl_idx);
2433024373 const decl_type = sema.typeOf(decl_val);
24331 if (decl_type.zigTypeTag() == .Fn and
24374 if (decl_type.zigTypeTag(mod) == .Fn and
2433224375 decl_type.fnParamLen() >= 1)
2433324376 {
2433424377 const first_param_type = decl_type.fnParamType(0);
2433524378 const first_param_tag = first_param_type.tag();
2433624379 // zig fmt: off
2433724380 if (first_param_tag == .generic_poison or (
24338 first_param_type.zigTypeTag() == .Pointer and
24381 first_param_type.zigTypeTag(mod) == .Pointer and
2433924382 (first_param_type.ptrSize() == .One or
2434024383 first_param_type.ptrSize() == .C) and
2434124384 first_param_type.childType().eql(concrete_ty, sema.mod)))
......@@ -24356,7 +24399,7 @@ fn fieldCallBind(
2435624399 .func_inst = decl_val,
2435724400 .arg0_inst = deref,
2435824401 } };
24359 } else if (first_param_type.zigTypeTag() == .Optional) {
24402 } else if (first_param_type.zigTypeTag(mod) == .Optional) {
2436024403 var opt_buf: Type.Payload.ElemType = undefined;
2436124404 const child = first_param_type.optionalChild(&opt_buf);
2436224405 if (child.eql(concrete_ty, sema.mod)) {
......@@ -24365,7 +24408,7 @@ fn fieldCallBind(
2436524408 .func_inst = decl_val,
2436624409 .arg0_inst = deref,
2436724410 } };
24368 } else if (child.zigTypeTag() == .Pointer and
24411 } else if (child.zigTypeTag(mod) == .Pointer and
2436924412 child.ptrSize() == .One and
2437024413 child.childType().eql(concrete_ty, sema.mod))
2437124414 {
......@@ -24374,7 +24417,7 @@ fn fieldCallBind(
2437424417 .arg0_inst = object_ptr,
2437524418 } };
2437624419 }
24377 } else if (first_param_type.zigTypeTag() == .ErrorUnion and
24420 } else if (first_param_type.zigTypeTag(mod) == .ErrorUnion and
2437824421 first_param_type.errorUnionPayload().eql(concrete_ty, sema.mod))
2437924422 {
2438024423 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
......@@ -24421,9 +24464,10 @@ fn finishFieldCallBind(
2442124464 .@"addrspace" = ptr_ty.ptrAddressSpace(),
2442224465 });
2442324466
24467 const mod = sema.mod;
2442424468 const container_ty = ptr_ty.childType();
24425 if (container_ty.zigTypeTag() == .Struct) {
24426 if (container_ty.structFieldValueComptime(field_index)) |default_val| {
24469 if (container_ty.zigTypeTag(mod) == .Struct) {
24470 if (container_ty.structFieldValueComptime(mod, field_index)) |default_val| {
2442724471 return .{ .direct = try sema.addConstant(field_ty, default_val) };
2442824472 }
2442924473 }
......@@ -24504,7 +24548,8 @@ fn structFieldPtr(
2450424548 unresolved_struct_ty: Type,
2450524549 initializing: bool,
2450624550) CompileError!Air.Inst.Ref {
24507 assert(unresolved_struct_ty.zigTypeTag() == .Struct);
24551 const mod = sema.mod;
24552 assert(unresolved_struct_ty.zigTypeTag(mod) == .Struct);
2450824553
2450924554 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);
2451024555 try sema.resolveStructLayout(struct_ty);
......@@ -24544,6 +24589,7 @@ fn structFieldPtrByIndex(
2454424589 return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing);
2454524590 }
2454624591
24592 const mod = sema.mod;
2454724593 const struct_obj = struct_ty.castTag(.@"struct").?.data;
2454824594 const field = struct_obj.fields.values()[field_index];
2454924595 const struct_ptr_ty = sema.typeOf(struct_ptr);
......@@ -24568,7 +24614,7 @@ fn structFieldPtrByIndex(
2456824614 if (i == field_index) {
2456924615 ptr_ty_data.bit_offset = running_bits;
2457024616 }
24571 running_bits += @intCast(u16, f.ty.bitSize(target));
24617 running_bits += @intCast(u16, f.ty.bitSize(mod));
2457224618 }
2457324619 ptr_ty_data.host_size = (running_bits + 7) / 8;
2457424620
......@@ -24582,7 +24628,7 @@ fn structFieldPtrByIndex(
2458224628 const parent_align = if (struct_ptr_ty_info.@"align" != 0)
2458324629 struct_ptr_ty_info.@"align"
2458424630 else
24585 struct_ptr_ty_info.pointee_type.abiAlignment(target);
24631 struct_ptr_ty_info.pointee_type.abiAlignment(mod);
2458624632 ptr_ty_data.@"align" = parent_align;
2458724633
2458824634 // If the field happens to be byte-aligned, simplify the pointer type.
......@@ -24596,8 +24642,8 @@ fn structFieldPtrByIndex(
2459624642 if (parent_align != 0 and ptr_ty_data.bit_offset % 8 == 0 and
2459724643 target.cpu.arch.endian() == .Little)
2459824644 {
24599 const elem_size_bytes = ptr_ty_data.pointee_type.abiSize(target);
24600 const elem_size_bits = ptr_ty_data.pointee_type.bitSize(target);
24645 const elem_size_bytes = ptr_ty_data.pointee_type.abiSize(mod);
24646 const elem_size_bits = ptr_ty_data.pointee_type.bitSize(mod);
2460124647 if (elem_size_bytes * 8 == elem_size_bits) {
2460224648 const byte_offset = ptr_ty_data.bit_offset / 8;
2460324649 const new_align = @as(u32, 1) << @intCast(u5, @ctz(byte_offset | parent_align));
......@@ -24644,7 +24690,8 @@ fn structFieldVal(
2464424690 field_name_src: LazySrcLoc,
2464524691 unresolved_struct_ty: Type,
2464624692) CompileError!Air.Inst.Ref {
24647 assert(unresolved_struct_ty.zigTypeTag() == .Struct);
24693 const mod = sema.mod;
24694 assert(unresolved_struct_ty.zigTypeTag(mod) == .Struct);
2464824695
2464924696 const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty);
2465024697 switch (struct_ty.tag()) {
......@@ -24728,9 +24775,10 @@ fn tupleFieldValByIndex(
2472824775 field_index: u32,
2472924776 tuple_ty: Type,
2473024777) CompileError!Air.Inst.Ref {
24778 const mod = sema.mod;
2473124779 const field_ty = tuple_ty.structFieldType(field_index);
2473224780
24733 if (tuple_ty.structFieldValueComptime(field_index)) |default_value| {
24781 if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {
2473424782 return sema.addConstant(field_ty, default_value);
2473524783 }
2473624784
......@@ -24743,7 +24791,7 @@ fn tupleFieldValByIndex(
2474324791 return sema.addConstant(field_ty, field_values[field_index]);
2474424792 }
2474524793
24746 if (tuple_ty.structFieldValueComptime(field_index)) |default_val| {
24794 if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
2474724795 return sema.addConstant(field_ty, default_val);
2474824796 }
2474924797
......@@ -24762,7 +24810,9 @@ fn unionFieldPtr(
2476224810 initializing: bool,
2476324811) CompileError!Air.Inst.Ref {
2476424812 const arena = sema.arena;
24765 assert(unresolved_union_ty.zigTypeTag() == .Union);
24813 const mod = sema.mod;
24814
24815 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);
2476624816
2476724817 const union_ptr_ty = sema.typeOf(union_ptr);
2476824818 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);
......@@ -24777,7 +24827,7 @@ fn unionFieldPtr(
2477724827 });
2477824828 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name).?);
2477924829
24780 if (initializing and field.ty.zigTypeTag() == .NoReturn) {
24830 if (initializing and field.ty.zigTypeTag(mod) == .NoReturn) {
2478124831 const msg = msg: {
2478224832 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});
2478324833 errdefer msg.destroy(sema.gpa);
......@@ -24839,7 +24889,7 @@ fn unionFieldPtr(
2483924889 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_val);
2484024890 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);
2484124891 }
24842 if (field.ty.zigTypeTag() == .NoReturn) {
24892 if (field.ty.zigTypeTag(mod) == .NoReturn) {
2484324893 _ = try block.addNoOp(.unreach);
2484424894 return Air.Inst.Ref.unreachable_value;
2484524895 }
......@@ -24855,7 +24905,8 @@ fn unionFieldVal(
2485524905 field_name_src: LazySrcLoc,
2485624906 unresolved_union_ty: Type,
2485724907) CompileError!Air.Inst.Ref {
24858 assert(unresolved_union_ty.zigTypeTag() == .Union);
24908 const mod = sema.mod;
24909 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);
2485924910
2486024911 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);
2486124912 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
......@@ -24911,7 +24962,7 @@ fn unionFieldVal(
2491124962 const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval);
2491224963 try sema.panicInactiveUnionField(block, active_tag, wanted_tag);
2491324964 }
24914 if (field.ty.zigTypeTag() == .NoReturn) {
24965 if (field.ty.zigTypeTag(mod) == .NoReturn) {
2491524966 _ = try block.addNoOp(.unreach);
2491624967 return Air.Inst.Ref.unreachable_value;
2491724968 }
......@@ -24928,22 +24979,22 @@ fn elemPtr(
2492824979 init: bool,
2492924980 oob_safety: bool,
2493024981) CompileError!Air.Inst.Ref {
24982 const mod = sema.mod;
2493124983 const indexable_ptr_src = src; // TODO better source location
2493224984 const indexable_ptr_ty = sema.typeOf(indexable_ptr);
24933 const target = sema.mod.getTarget();
2493424985
24935 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag()) {
24986 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(mod)) {
2493624987 .Pointer => indexable_ptr_ty.elemType(),
2493724988 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(sema.mod)}),
2493824989 };
2493924990 try checkIndexable(sema, block, src, indexable_ty);
2494024991
24941 switch (indexable_ty.zigTypeTag()) {
24992 switch (indexable_ty.zigTypeTag(mod)) {
2494224993 .Array, .Vector => return sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety),
2494324994 .Struct => {
2494424995 // Tuple field access.
2494524996 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime-known");
24946 const index = @intCast(u32, index_val.toUnsignedInt(target));
24997 const index = @intCast(u32, index_val.toUnsignedInt(mod));
2494724998 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);
2494824999 },
2494925000 else => {
......@@ -24966,7 +25017,7 @@ fn elemPtrOneLayerOnly(
2496625017) CompileError!Air.Inst.Ref {
2496725018 const indexable_src = src; // TODO better source location
2496825019 const indexable_ty = sema.typeOf(indexable);
24969 const target = sema.mod.getTarget();
25020 const mod = sema.mod;
2497025021
2497125022 try checkIndexable(sema, block, src, indexable_ty);
2497225023
......@@ -24978,7 +25029,7 @@ fn elemPtrOneLayerOnly(
2497825029 const runtime_src = rs: {
2497925030 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;
2498025031 const index_val = maybe_index_val orelse break :rs elem_index_src;
24981 const index = @intCast(usize, index_val.toUnsignedInt(target));
25032 const index = @intCast(usize, index_val.toUnsignedInt(mod));
2498225033 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index, sema.mod);
2498325034 const result_ty = try sema.elemPtrType(indexable_ty, index);
2498425035 return sema.addConstant(result_ty, elem_ptr);
......@@ -24989,7 +25040,7 @@ fn elemPtrOneLayerOnly(
2498925040 return block.addPtrElemPtr(indexable, elem_index, result_ty);
2499025041 },
2499125042 .One => {
24992 assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by checkIndexable
25043 assert(indexable_ty.childType().zigTypeTag(mod) == .Array); // Guaranteed by checkIndexable
2499325044 return sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety);
2499425045 },
2499525046 }
......@@ -25006,7 +25057,7 @@ fn elemVal(
2500625057) CompileError!Air.Inst.Ref {
2500725058 const indexable_src = src; // TODO better source location
2500825059 const indexable_ty = sema.typeOf(indexable);
25009 const target = sema.mod.getTarget();
25060 const mod = sema.mod;
2501025061
2501125062 try checkIndexable(sema, block, src, indexable_ty);
2501225063
......@@ -25014,7 +25065,7 @@ fn elemVal(
2501425065 // index is a scalar or vector instead of unconditionally casting to usize.
2501525066 const elem_index = try sema.coerce(block, Type.usize, elem_index_uncasted, elem_index_src);
2501625067
25017 switch (indexable_ty.zigTypeTag()) {
25068 switch (indexable_ty.zigTypeTag(mod)) {
2501825069 .Pointer => switch (indexable_ty.ptrSize()) {
2501925070 .Slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
2502025071 .Many, .C => {
......@@ -25024,10 +25075,10 @@ fn elemVal(
2502425075 const runtime_src = rs: {
2502525076 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
2502625077 const index_val = maybe_index_val orelse break :rs elem_index_src;
25027 const index = @intCast(usize, index_val.toUnsignedInt(target));
25078 const index = @intCast(usize, index_val.toUnsignedInt(mod));
2502825079 const elem_ptr_val = try indexable_val.elemPtr(indexable_ty, sema.arena, index, sema.mod);
2502925080 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, indexable_ty)) |elem_val| {
25030 return sema.addConstant(indexable_ty.elemType2(), elem_val);
25081 return sema.addConstant(indexable_ty.elemType2(mod), elem_val);
2503125082 }
2503225083 break :rs indexable_src;
2503325084 };
......@@ -25036,7 +25087,7 @@ fn elemVal(
2503625087 return block.addBinOp(.ptr_elem_val, indexable, elem_index);
2503725088 },
2503825089 .One => {
25039 assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by checkIndexable
25090 assert(indexable_ty.childType().zigTypeTag(mod) == .Array); // Guaranteed by checkIndexable
2504025091 const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety);
2504125092 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);
2504225093 },
......@@ -25049,7 +25100,7 @@ fn elemVal(
2504925100 .Struct => {
2505025101 // Tuple field access.
2505125102 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime-known");
25052 const index = @intCast(u32, index_val.toUnsignedInt(target));
25103 const index = @intCast(u32, index_val.toUnsignedInt(mod));
2505325104 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);
2505425105 },
2505525106 else => unreachable,
......@@ -25093,6 +25144,7 @@ fn tupleFieldPtr(
2509325144 field_index: u32,
2509425145 init: bool,
2509525146) CompileError!Air.Inst.Ref {
25147 const mod = sema.mod;
2509625148 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
2509725149 const tuple_ty = tuple_ptr_ty.childType();
2509825150 _ = try sema.resolveTypeFields(tuple_ty);
......@@ -25116,7 +25168,7 @@ fn tupleFieldPtr(
2511625168 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(),
2511725169 });
2511825170
25119 if (tuple_ty.structFieldValueComptime(field_index)) |default_val| {
25171 if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
2512025172 const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{
2512125173 .field_ty = field_ty,
2512225174 .field_val = default_val,
......@@ -25151,6 +25203,7 @@ fn tupleField(
2515125203 field_index_src: LazySrcLoc,
2515225204 field_index: u32,
2515325205) CompileError!Air.Inst.Ref {
25206 const mod = sema.mod;
2515425207 const tuple_ty = try sema.resolveTypeFields(sema.typeOf(tuple));
2515525208 const field_count = tuple_ty.structFieldCount();
2515625209
......@@ -25166,13 +25219,13 @@ fn tupleField(
2516625219
2516725220 const field_ty = tuple_ty.structFieldType(field_index);
2516825221
25169 if (tuple_ty.structFieldValueComptime(field_index)) |default_value| {
25222 if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {
2517025223 return sema.addConstant(field_ty, default_value); // comptime field
2517125224 }
2517225225
2517325226 if (try sema.resolveMaybeUndefVal(tuple)) |tuple_val| {
2517425227 if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);
25175 return sema.addConstant(field_ty, tuple_val.fieldValue(tuple_ty, field_index));
25228 return sema.addConstant(field_ty, tuple_val.fieldValue(tuple_ty, mod, field_index));
2517625229 }
2517725230
2517825231 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
......@@ -25191,6 +25244,7 @@ fn elemValArray(
2519125244 elem_index: Air.Inst.Ref,
2519225245 oob_safety: bool,
2519325246) CompileError!Air.Inst.Ref {
25247 const mod = sema.mod;
2519425248 const array_ty = sema.typeOf(array);
2519525249 const array_sent = array_ty.sentinel();
2519625250 const array_len = array_ty.arrayLen();
......@@ -25204,10 +25258,9 @@ fn elemValArray(
2520425258 const maybe_undef_array_val = try sema.resolveMaybeUndefVal(array);
2520525259 // index must be defined since it can access out of bounds
2520625260 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
25207 const target = sema.mod.getTarget();
2520825261
2520925262 if (maybe_index_val) |index_val| {
25210 const index = @intCast(usize, index_val.toUnsignedInt(target));
25263 const index = @intCast(usize, index_val.toUnsignedInt(mod));
2521125264 if (array_sent) |s| {
2521225265 if (index == array_len) {
2521325266 return sema.addConstant(elem_ty, s);
......@@ -25223,7 +25276,7 @@ fn elemValArray(
2522325276 return sema.addConstUndef(elem_ty);
2522425277 }
2522525278 if (maybe_index_val) |index_val| {
25226 const index = @intCast(usize, index_val.toUnsignedInt(target));
25279 const index = @intCast(usize, index_val.toUnsignedInt(mod));
2522725280 const elem_val = try array_val.elemValue(sema.mod, sema.arena, index);
2522825281 return sema.addConstant(elem_ty, elem_val);
2522925282 }
......@@ -25255,7 +25308,7 @@ fn elemPtrArray(
2525525308 init: bool,
2525625309 oob_safety: bool,
2525725310) CompileError!Air.Inst.Ref {
25258 const target = sema.mod.getTarget();
25311 const mod = sema.mod;
2525925312 const array_ptr_ty = sema.typeOf(array_ptr);
2526025313 const array_ty = array_ptr_ty.childType();
2526125314 const array_sent = array_ty.sentinel() != null;
......@@ -25269,7 +25322,7 @@ fn elemPtrArray(
2526925322 const maybe_undef_array_ptr_val = try sema.resolveMaybeUndefVal(array_ptr);
2527025323 // The index must not be undefined since it can be out of bounds.
2527125324 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
25272 const index = try sema.usizeCast(block, elem_index_src, index_val.toUnsignedInt(target));
25325 const index = try sema.usizeCast(block, elem_index_src, index_val.toUnsignedInt(mod));
2527325326 if (index >= array_len_s) {
2527425327 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
2527525328 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
......@@ -25290,7 +25343,7 @@ fn elemPtrArray(
2529025343 }
2529125344
2529225345 if (!init) {
25293 try sema.validateRuntimeElemAccess(block, elem_index_src, array_ty.elemType2(), array_ty, array_ptr_src);
25346 try sema.validateRuntimeElemAccess(block, elem_index_src, array_ty.elemType2(mod), array_ty, array_ptr_src);
2529425347 }
2529525348
2529625349 const runtime_src = if (maybe_undef_array_ptr_val != null) elem_index_src else array_ptr_src;
......@@ -25316,16 +25369,16 @@ fn elemValSlice(
2531625369 elem_index: Air.Inst.Ref,
2531725370 oob_safety: bool,
2531825371) CompileError!Air.Inst.Ref {
25372 const mod = sema.mod;
2531925373 const slice_ty = sema.typeOf(slice);
2532025374 const slice_sent = slice_ty.sentinel() != null;
25321 const elem_ty = slice_ty.elemType2();
25375 const elem_ty = slice_ty.elemType2(mod);
2532225376 var runtime_src = slice_src;
2532325377
2532425378 // slice must be defined since it can dereferenced as null
2532525379 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);
2532625380 // index must be defined since it can index out of bounds
2532725381 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
25328 const target = sema.mod.getTarget();
2532925382
2533025383 if (maybe_slice_val) |slice_val| {
2533125384 runtime_src = elem_index_src;
......@@ -25335,7 +25388,7 @@ fn elemValSlice(
2533525388 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
2533625389 }
2533725390 if (maybe_index_val) |index_val| {
25338 const index = @intCast(usize, index_val.toUnsignedInt(target));
25391 const index = @intCast(usize, index_val.toUnsignedInt(mod));
2533925392 if (index >= slice_len_s) {
2534025393 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
2534125394 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
......@@ -25373,14 +25426,14 @@ fn elemPtrSlice(
2537325426 elem_index: Air.Inst.Ref,
2537425427 oob_safety: bool,
2537525428) CompileError!Air.Inst.Ref {
25376 const target = sema.mod.getTarget();
25429 const mod = sema.mod;
2537725430 const slice_ty = sema.typeOf(slice);
2537825431 const slice_sent = slice_ty.sentinel() != null;
2537925432
2538025433 const maybe_undef_slice_val = try sema.resolveMaybeUndefVal(slice);
2538125434 // The index must not be undefined since it can be out of bounds.
2538225435 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
25383 const index = try sema.usizeCast(block, elem_index_src, index_val.toUnsignedInt(target));
25436 const index = try sema.usizeCast(block, elem_index_src, index_val.toUnsignedInt(mod));
2538425437 break :o index;
2538525438 } else null;
2538625439
......@@ -25484,6 +25537,7 @@ fn coerceExtra(
2548425537 const dest_ty_src = inst_src; // TODO better source location
2548525538 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
2548625539 const inst_ty = try sema.resolveTypeFields(sema.typeOf(inst));
25540 const mod = sema.mod;
2548725541 const target = sema.mod.getTarget();
2548825542 // If the types are the same, we can return the operand.
2548925543 if (dest_ty.eql(inst_ty, sema.mod))
......@@ -25502,9 +25556,9 @@ fn coerceExtra(
2550225556 return block.addBitCast(dest_ty, inst);
2550325557 }
2550425558
25505 const is_undef = inst_ty.zigTypeTag() == .Undefined;
25559 const is_undef = inst_ty.zigTypeTag(mod) == .Undefined;
2550625560
25507 switch (dest_ty.zigTypeTag()) {
25561 switch (dest_ty.zigTypeTag(mod)) {
2550825562 .Optional => optional: {
2550925563 // undefined sets the optional bit also to undefined.
2551025564 if (is_undef) {
......@@ -25512,18 +25566,18 @@ fn coerceExtra(
2551225566 }
2551325567
2551425568 // null to ?T
25515 if (inst_ty.zigTypeTag() == .Null) {
25569 if (inst_ty.zigTypeTag(mod) == .Null) {
2551625570 return sema.addConstant(dest_ty, Value.null);
2551725571 }
2551825572
2551925573 // cast from ?*T and ?[*]T to ?*anyopaque
2552025574 // but don't do it if the source type is a double pointer
25521 if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and
25522 inst_ty.isPtrAtRuntime())
25575 if (dest_ty.isPtrLikeOptional(mod) and dest_ty.elemType2(mod).tag() == .anyopaque and
25576 inst_ty.isPtrAtRuntime(mod))
2552325577 anyopaque_check: {
2552425578 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional;
25525 const elem_ty = inst_ty.elemType2();
25526 if (elem_ty.zigTypeTag() == .Pointer or elem_ty.isPtrLikeOptional()) {
25579 const elem_ty = inst_ty.elemType2(mod);
25580 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {
2552725581 in_memory_result = .{ .double_ptr_to_anyopaque = .{
2552825582 .actual = inst_ty,
2552925583 .wanted = dest_ty,
......@@ -25532,7 +25586,7 @@ fn coerceExtra(
2553225586 }
2553325587 // Let the logic below handle wrapping the optional now that
2553425588 // it has been checked to correctly coerce.
25535 if (!inst_ty.isPtrLikeOptional()) break :anyopaque_check;
25589 if (!inst_ty.isPtrLikeOptional(mod)) break :anyopaque_check;
2553625590 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
2553725591 }
2553825592
......@@ -25554,7 +25608,7 @@ fn coerceExtra(
2555425608 const dest_info = dest_ty.ptrInfo().data;
2555525609
2555625610 // Function body to function pointer.
25557 if (inst_ty.zigTypeTag() == .Fn) {
25611 if (inst_ty.zigTypeTag(mod) == .Fn) {
2555825612 const fn_val = try sema.resolveConstValue(block, .unneeded, inst, "");
2555925613 const fn_decl = fn_val.pointerDecl().?;
2556025614 const inst_as_ptr = try sema.analyzeDeclRef(fn_decl);
......@@ -25568,7 +25622,7 @@ fn coerceExtra(
2556825622 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
2556925623 const ptr_elem_ty = inst_ty.childType();
2557025624 const array_ty = dest_info.pointee_type;
25571 if (array_ty.zigTypeTag() != .Array) break :single_item;
25625 if (array_ty.zigTypeTag(mod) != .Array) break :single_item;
2557225626 const array_elem_ty = array_ty.childType();
2557325627 if (array_ty.arrayLen() != 1) break :single_item;
2557425628 const dest_is_mut = dest_info.mutable;
......@@ -25584,7 +25638,7 @@ fn coerceExtra(
2558425638 if (!inst_ty.isSinglePointer()) break :src_array_ptr;
2558525639 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
2558625640 const array_ty = inst_ty.childType();
25587 if (array_ty.zigTypeTag() != .Array) break :src_array_ptr;
25641 if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr;
2558825642 const array_elem_type = array_ty.childType();
2558925643 const dest_is_mut = dest_info.mutable;
2559025644
......@@ -25656,10 +25710,10 @@ fn coerceExtra(
2565625710
2565725711 // cast from *T and [*]T to *anyopaque
2565825712 // but don't do it if the source type is a double pointer
25659 if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer) to_anyopaque: {
25713 if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: {
2566025714 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
25661 const elem_ty = inst_ty.elemType2();
25662 if (elem_ty.zigTypeTag() == .Pointer or elem_ty.isPtrLikeOptional()) {
25715 const elem_ty = inst_ty.elemType2(mod);
25716 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {
2566325717 in_memory_result = .{ .double_ptr_to_anyopaque = .{
2566425718 .actual = inst_ty,
2566525719 .wanted = dest_ty,
......@@ -25679,7 +25733,7 @@ fn coerceExtra(
2567925733
2568025734 switch (dest_info.size) {
2568125735 // coercion to C pointer
25682 .C => switch (inst_ty.zigTypeTag()) {
25736 .C => switch (inst_ty.zigTypeTag(mod)) {
2568325737 .Null => {
2568425738 return sema.addConstant(dest_ty, Value.null);
2568525739 },
......@@ -25691,7 +25745,7 @@ fn coerceExtra(
2569125745 return try sema.coerceCompatiblePtrs(block, dest_ty, addr, inst_src);
2569225746 },
2569325747 .Int => {
25694 const ptr_size_ty = switch (inst_ty.intInfo(target).signedness) {
25748 const ptr_size_ty = switch (inst_ty.intInfo(mod).signedness) {
2569525749 .signed => Type.isize,
2569625750 .unsigned => Type.usize,
2569725751 };
......@@ -25733,7 +25787,7 @@ fn coerceExtra(
2573325787 },
2573425788 else => {},
2573525789 },
25736 .One => switch (dest_info.pointee_type.zigTypeTag()) {
25790 .One => switch (dest_info.pointee_type.zigTypeTag(mod)) {
2573725791 .Union => {
2573825792 // pointer to anonymous struct to pointer to union
2573925793 if (inst_ty.isSinglePointer() and
......@@ -25767,7 +25821,7 @@ fn coerceExtra(
2576725821 else => {},
2576825822 },
2576925823 .Slice => to_slice: {
25770 if (inst_ty.zigTypeTag() == .Array) {
25824 if (inst_ty.zigTypeTag(mod) == .Array) {
2577125825 return sema.fail(
2577225826 block,
2577325827 inst_src,
......@@ -25789,7 +25843,7 @@ fn coerceExtra(
2578925843 .ptr = if (dest_info.@"align" != 0)
2579025844 try Value.Tag.int_u64.create(sema.arena, dest_info.@"align")
2579125845 else
25792 try dest_info.pointee_type.lazyAbiAlignment(target, sema.arena),
25846 try dest_info.pointee_type.lazyAbiAlignment(mod, sema.arena),
2579325847 .len = Value.zero,
2579425848 });
2579525849 return sema.addConstant(dest_ty, slice_val);
......@@ -25834,13 +25888,13 @@ fn coerceExtra(
2583425888 },
2583525889 }
2583625890 },
25837 .Int, .ComptimeInt => switch (inst_ty.zigTypeTag()) {
25891 .Int, .ComptimeInt => switch (inst_ty.zigTypeTag(mod)) {
2583825892 .Float, .ComptimeFloat => float: {
2583925893 if (is_undef) {
2584025894 return sema.addConstUndef(dest_ty);
2584125895 }
2584225896 const val = (try sema.resolveMaybeUndefVal(inst)) orelse {
25843 if (dest_ty.zigTypeTag() == .ComptimeInt) {
25897 if (dest_ty.zigTypeTag(mod) == .ComptimeInt) {
2584425898 if (!opts.report_err) return error.NotCoercible;
2584525899 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime-known");
2584625900 }
......@@ -25870,15 +25924,15 @@ fn coerceExtra(
2587025924 }
2587125925 return try sema.addConstant(dest_ty, val);
2587225926 }
25873 if (dest_ty.zigTypeTag() == .ComptimeInt) {
25927 if (dest_ty.zigTypeTag(mod) == .ComptimeInt) {
2587425928 if (!opts.report_err) return error.NotCoercible;
2587525929 if (opts.no_cast_to_comptime_int) return inst;
2587625930 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime-known");
2587725931 }
2587825932
2587925933 // integer widening
25880 const dst_info = dest_ty.intInfo(target);
25881 const src_info = inst_ty.intInfo(target);
25934 const dst_info = dest_ty.intInfo(mod);
25935 const src_info = inst_ty.intInfo(mod);
2588225936 if ((src_info.signedness == dst_info.signedness and dst_info.bits >= src_info.bits) or
2588325937 // small enough unsigned ints can get casted to large enough signed ints
2588425938 (dst_info.signedness == .signed and dst_info.bits > src_info.bits))
......@@ -25892,7 +25946,7 @@ fn coerceExtra(
2589225946 },
2589325947 else => {},
2589425948 },
25895 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) {
25949 .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(mod)) {
2589625950 .ComptimeFloat => {
2589725951 const val = try sema.resolveConstValue(block, .unneeded, inst, "");
2589825952 const result_val = try val.floatCast(sema.arena, dest_ty, target);
......@@ -25913,7 +25967,7 @@ fn coerceExtra(
2591325967 );
2591425968 }
2591525969 return try sema.addConstant(dest_ty, result_val);
25916 } else if (dest_ty.zigTypeTag() == .ComptimeFloat) {
25970 } else if (dest_ty.zigTypeTag(mod) == .ComptimeFloat) {
2591725971 if (!opts.report_err) return error.NotCoercible;
2591825972 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime-known");
2591925973 }
......@@ -25931,7 +25985,7 @@ fn coerceExtra(
2593125985 return sema.addConstUndef(dest_ty);
2593225986 }
2593325987 const val = (try sema.resolveMaybeUndefVal(inst)) orelse {
25934 if (dest_ty.zigTypeTag() == .ComptimeFloat) {
25988 if (dest_ty.zigTypeTag(mod) == .ComptimeFloat) {
2593525989 if (!opts.report_err) return error.NotCoercible;
2593625990 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime-known");
2593725991 }
......@@ -25955,7 +26009,7 @@ fn coerceExtra(
2595526009 },
2595626010 else => {},
2595726011 },
25958 .Enum => switch (inst_ty.zigTypeTag()) {
26012 .Enum => switch (inst_ty.zigTypeTag(mod)) {
2595926013 .EnumLiteral => {
2596026014 // enum literal to enum
2596126015 const val = try sema.resolveConstValue(block, .unneeded, inst, "");
......@@ -25991,7 +26045,7 @@ fn coerceExtra(
2599126045 },
2599226046 else => {},
2599326047 },
25994 .ErrorUnion => switch (inst_ty.zigTypeTag()) {
26048 .ErrorUnion => switch (inst_ty.zigTypeTag(mod)) {
2599526049 .ErrorUnion => eu: {
2599626050 if (maybe_inst_val) |inst_val| {
2599726051 switch (inst_val.tag()) {
......@@ -26031,7 +26085,7 @@ fn coerceExtra(
2603126085 };
2603226086 },
2603326087 },
26034 .Union => switch (inst_ty.zigTypeTag()) {
26088 .Union => switch (inst_ty.zigTypeTag(mod)) {
2603526089 .Enum, .EnumLiteral => return sema.coerceEnumToUnion(block, dest_ty, dest_ty_src, inst, inst_src),
2603626090 .Struct => {
2603726091 if (inst_ty.isAnonStruct()) {
......@@ -26043,7 +26097,7 @@ fn coerceExtra(
2604326097 },
2604426098 else => {},
2604526099 },
26046 .Array => switch (inst_ty.zigTypeTag()) {
26100 .Array => switch (inst_ty.zigTypeTag(mod)) {
2604726101 .Vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src),
2604826102 .Struct => {
2604926103 if (inst == .empty_struct) {
......@@ -26058,7 +26112,7 @@ fn coerceExtra(
2605826112 },
2605926113 else => {},
2606026114 },
26061 .Vector => switch (inst_ty.zigTypeTag()) {
26115 .Vector => switch (inst_ty.zigTypeTag(mod)) {
2606226116 .Array, .Vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src),
2606326117 .Struct => {
2606426118 if (inst_ty.isTuple()) {
......@@ -26093,7 +26147,7 @@ fn coerceExtra(
2609326147
2609426148 if (!opts.report_err) return error.NotCoercible;
2609526149
26096 if (opts.is_ret and dest_ty.zigTypeTag() == .NoReturn) {
26150 if (opts.is_ret and dest_ty.zigTypeTag(mod) == .NoReturn) {
2609726151 const msg = msg: {
2609826152 const msg = try sema.errMsg(block, inst_src, "function declared 'noreturn' returns", .{});
2609926153 errdefer msg.destroy(sema.gpa);
......@@ -26111,7 +26165,7 @@ fn coerceExtra(
2611126165 errdefer msg.destroy(sema.gpa);
2611226166
2611326167 // E!T to T
26114 if (inst_ty.zigTypeTag() == .ErrorUnion and
26168 if (inst_ty.zigTypeTag(mod) == .ErrorUnion and
2611526169 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
2611626170 {
2611726171 try sema.errNote(block, inst_src, msg, "cannot convert error union to payload type", .{});
......@@ -26120,7 +26174,7 @@ fn coerceExtra(
2612026174
2612126175 // ?T to T
2612226176 var buf: Type.Payload.ElemType = undefined;
26123 if (inst_ty.zigTypeTag() == .Optional and
26177 if (inst_ty.zigTypeTag(mod) == .Optional and
2612426178 (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(&buf), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
2612526179 {
2612626180 try sema.errNote(block, inst_src, msg, "cannot convert optional to payload type", .{});
......@@ -26133,7 +26187,7 @@ fn coerceExtra(
2613326187 if (opts.is_ret and sema.mod.test_functions.get(sema.func.?.owner_decl) == null) {
2613426188 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
2613526189 const src_decl = sema.mod.declPtr(sema.func.?.owner_decl);
26136 if (inst_ty.isError() and !dest_ty.isError()) {
26190 if (inst_ty.isError(mod) and !dest_ty.isError(mod)) {
2613726191 try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl), msg, "function cannot return an error", .{});
2613826192 } else {
2613926193 try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl), msg, "function return type declared here", .{});
......@@ -26264,6 +26318,7 @@ const InMemoryCoercionResult = union(enum) {
2626426318 }
2626526319
2626626320 fn report(res: *const InMemoryCoercionResult, sema: *Sema, block: *Block, src: LazySrcLoc, msg: *Module.ErrorMsg) !void {
26321 const mod = sema.mod;
2626726322 var cur = res;
2626826323 while (true) switch (cur.*) {
2626926324 .ok => unreachable,
......@@ -26445,8 +26500,8 @@ const InMemoryCoercionResult = union(enum) {
2644526500 break;
2644626501 },
2644726502 .ptr_allowzero => |pair| {
26448 const wanted_allow_zero = pair.wanted.ptrAllowsZero();
26449 const actual_allow_zero = pair.actual.ptrAllowsZero();
26503 const wanted_allow_zero = pair.wanted.ptrAllowsZero(mod);
26504 const actual_allow_zero = pair.actual.ptrAllowsZero(mod);
2645026505 if (actual_allow_zero and !wanted_allow_zero) {
2645126506 try sema.errNote(block, src, msg, "'{}' could have null values which are illegal in type '{}'", .{
2645226507 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
......@@ -26522,13 +26577,15 @@ fn coerceInMemoryAllowed(
2652226577 dest_src: LazySrcLoc,
2652326578 src_src: LazySrcLoc,
2652426579) CompileError!InMemoryCoercionResult {
26525 if (dest_ty.eql(src_ty, sema.mod))
26580 const mod = sema.mod;
26581
26582 if (dest_ty.eql(src_ty, mod))
2652626583 return .ok;
2652726584
2652826585 // Differently-named integers with the same number of bits.
26529 if (dest_ty.zigTypeTag() == .Int and src_ty.zigTypeTag() == .Int) {
26530 const dest_info = dest_ty.intInfo(target);
26531 const src_info = src_ty.intInfo(target);
26586 if (dest_ty.zigTypeTag(mod) == .Int and src_ty.zigTypeTag(mod) == .Int) {
26587 const dest_info = dest_ty.intInfo(mod);
26588 const src_info = src_ty.intInfo(mod);
2653226589
2653326590 if (dest_info.signedness == src_info.signedness and
2653426591 dest_info.bits == src_info.bits)
......@@ -26551,7 +26608,7 @@ fn coerceInMemoryAllowed(
2655126608 }
2655226609
2655326610 // Differently-named floats with the same number of bits.
26554 if (dest_ty.zigTypeTag() == .Float and src_ty.zigTypeTag() == .Float) {
26611 if (dest_ty.zigTypeTag(mod) == .Float and src_ty.zigTypeTag(mod) == .Float) {
2655526612 const dest_bits = dest_ty.floatBits(target);
2655626613 const src_bits = src_ty.floatBits(target);
2655726614 if (dest_bits == src_bits) {
......@@ -26575,8 +26632,8 @@ fn coerceInMemoryAllowed(
2657526632 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src);
2657626633 }
2657726634
26578 const dest_tag = dest_ty.zigTypeTag();
26579 const src_tag = src_ty.zigTypeTag();
26635 const dest_tag = dest_ty.zigTypeTag(mod);
26636 const src_tag = src_ty.zigTypeTag(mod);
2658026637
2658126638 // Functions
2658226639 if (dest_tag == .Fn and src_tag == .Fn) {
......@@ -26624,7 +26681,7 @@ fn coerceInMemoryAllowed(
2662426681 }
2662526682 const ok_sent = dest_info.sentinel == null or
2662626683 (src_info.sentinel != null and
26627 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type, sema.mod));
26684 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type, mod));
2662826685 if (!ok_sent) {
2662926686 return InMemoryCoercionResult{ .array_sentinel = .{
2663026687 .actual = src_info.sentinel orelse Value.initTag(.unreachable_value),
......@@ -26646,8 +26703,8 @@ fn coerceInMemoryAllowed(
2664626703 } };
2664726704 }
2664826705
26649 const dest_elem_ty = dest_ty.scalarType();
26650 const src_elem_ty = src_ty.scalarType();
26706 const dest_elem_ty = dest_ty.scalarType(mod);
26707 const src_elem_ty = src_ty.scalarType(mod);
2665126708 const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src);
2665226709 if (child != .ok) {
2665326710 return InMemoryCoercionResult{ .vector_elem = .{
......@@ -26923,6 +26980,7 @@ fn coerceInMemoryAllowedPtrs(
2692326980 dest_src: LazySrcLoc,
2692426981 src_src: LazySrcLoc,
2692526982) !InMemoryCoercionResult {
26983 const mod = sema.mod;
2692626984 const dest_info = dest_ptr_ty.ptrInfo().data;
2692726985 const src_info = src_ptr_ty.ptrInfo().data;
2692826986
......@@ -26964,8 +27022,8 @@ fn coerceInMemoryAllowedPtrs(
2696427022 } };
2696527023 }
2696627024
26967 const dest_allow_zero = dest_ty.ptrAllowsZero();
26968 const src_allow_zero = src_ty.ptrAllowsZero();
27025 const dest_allow_zero = dest_ty.ptrAllowsZero(mod);
27026 const src_allow_zero = src_ty.ptrAllowsZero(mod);
2696927027
2697027028 const ok_allows_zero = (dest_allow_zero and
2697127029 (src_allow_zero or !dest_is_mut)) or
......@@ -27013,12 +27071,12 @@ fn coerceInMemoryAllowedPtrs(
2701327071 const src_align = if (src_info.@"align" != 0)
2701427072 src_info.@"align"
2701527073 else
27016 src_info.pointee_type.abiAlignment(target);
27074 src_info.pointee_type.abiAlignment(mod);
2701727075
2701827076 const dest_align = if (dest_info.@"align" != 0)
2701927077 dest_info.@"align"
2702027078 else
27021 dest_info.pointee_type.abiAlignment(target);
27079 dest_info.pointee_type.abiAlignment(mod);
2702227080
2702327081 if (dest_align > src_align) {
2702427082 return InMemoryCoercionResult{ .ptr_alignment = .{
......@@ -27041,8 +27099,9 @@ fn coerceVarArgParam(
2704127099) !Air.Inst.Ref {
2704227100 if (block.is_typeof) return inst;
2704327101
27102 const mod = sema.mod;
2704427103 const uncasted_ty = sema.typeOf(inst);
27045 const coerced = switch (uncasted_ty.zigTypeTag()) {
27104 const coerced = switch (uncasted_ty.zigTypeTag(mod)) {
2704627105 // TODO consider casting to c_int/f64 if they fit
2704727106 .ComptimeInt, .ComptimeFloat => return sema.fail(
2704827107 block,
......@@ -27124,7 +27183,8 @@ fn storePtr2(
2712427183 // this code does not handle tuple-to-struct coercion which requires dealing with missing
2712527184 // fields.
2712627185 const operand_ty = sema.typeOf(uncasted_operand);
27127 if (operand_ty.isTuple() and elem_ty.zigTypeTag() == .Array) {
27186 const mod = sema.mod;
27187 if (operand_ty.isTuple() and elem_ty.zigTypeTag(mod) == .Array) {
2712827188 const field_count = operand_ty.structFieldCount();
2712927189 var i: u32 = 0;
2713027190 while (i < field_count) : (i += 1) {
......@@ -27225,7 +27285,8 @@ fn storePtr2(
2722527285/// lengths match.
2722627286fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
2722727287 const array_ty = sema.typeOf(ptr).childType();
27228 if (array_ty.zigTypeTag() != .Array) return null;
27288 const mod = sema.mod;
27289 if (array_ty.zigTypeTag(mod) != .Array) return null;
2722927290 var ptr_inst = Air.refToIndex(ptr) orelse return null;
2723027291 const air_datas = sema.air_instructions.items(.data);
2723127292 const air_tags = sema.air_instructions.items(.tag);
......@@ -27237,7 +27298,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
2723727298 .pointer => prev_ptr_ty.castTag(.pointer).?.data.pointee_type,
2723827299 else => return null,
2723927300 };
27240 if (prev_ptr_child_ty.zigTypeTag() == .Vector) break prev_ptr;
27301 if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr;
2724127302 ptr_inst = Air.refToIndex(prev_ptr) orelse return null;
2724227303 } else return null;
2724327304
......@@ -27263,6 +27324,7 @@ fn storePtrVal(
2726327324 operand_val: Value,
2726427325 operand_ty: Type,
2726527326) !void {
27327 const mod = sema.mod;
2726627328 var mut_kit = try sema.beginComptimePtrMutation(block, src, ptr_val, operand_ty);
2726727329 try sema.checkComptimeVarStore(block, src, mut_kit.decl_ref_mut);
2726827330
......@@ -27281,8 +27343,7 @@ fn storePtrVal(
2728127343 val_ptr.* = try operand_val.copy(arena);
2728227344 },
2728327345 .reinterpret => |reinterpret| {
27284 const target = sema.mod.getTarget();
27285 const abi_size = try sema.usizeCast(block, src, mut_kit.ty.abiSize(target));
27346 const abi_size = try sema.usizeCast(block, src, mut_kit.ty.abiSize(mod));
2728627347 const buffer = try sema.gpa.alloc(u8, abi_size);
2728727348 defer sema.gpa.free(buffer);
2728827349 reinterpret.val_ptr.*.writeToMemory(mut_kit.ty, sema.mod, buffer) catch |err| switch (err) {
......@@ -27354,7 +27415,7 @@ fn beginComptimePtrMutation(
2735427415 ptr_val: Value,
2735527416 ptr_elem_ty: Type,
2735627417) CompileError!ComptimePtrMutationKit {
27357 const target = sema.mod.getTarget();
27418 const mod = sema.mod;
2735827419 switch (ptr_val.tag()) {
2735927420 .decl_ref_mut => {
2736027421 const decl_ref_mut = ptr_val.castTag(.decl_ref_mut).?.data;
......@@ -27375,7 +27436,7 @@ fn beginComptimePtrMutation(
2737527436 var parent = try sema.beginComptimePtrMutation(block, src, elem_ptr.array_ptr, elem_ptr.elem_ty);
2737627437
2737727438 switch (parent.pointee) {
27378 .direct => |val_ptr| switch (parent.ty.zigTypeTag()) {
27439 .direct => |val_ptr| switch (parent.ty.zigTypeTag(mod)) {
2737927440 .Array, .Vector => {
2738027441 const check_len = parent.ty.arrayLenIncludingSentinel();
2738127442 if (elem_ptr.index >= check_len) {
......@@ -27570,7 +27631,7 @@ fn beginComptimePtrMutation(
2757027631 },
2757127632 },
2757227633 .reinterpret => |reinterpret| {
27573 if (!elem_ptr.elem_ty.hasWellDefinedLayout()) {
27634 if (!elem_ptr.elem_ty.hasWellDefinedLayout(mod)) {
2757427635 // Even though the parent value type has well-defined memory layout, our
2757527636 // pointer type does not.
2757627637 return ComptimePtrMutationKit{
......@@ -27608,7 +27669,7 @@ fn beginComptimePtrMutation(
2760827669 const arena = parent.beginArena(sema.mod);
2760927670 defer parent.finishArena(sema.mod);
2761027671
27611 switch (parent.ty.zigTypeTag()) {
27672 switch (parent.ty.zigTypeTag(mod)) {
2761227673 .Struct => {
2761327674 const fields = try arena.alloc(Value, parent.ty.structFieldCount());
2761427675 @memset(fields, Value.undef);
......@@ -27746,7 +27807,7 @@ fn beginComptimePtrMutation(
2774627807 else => unreachable,
2774727808 },
2774827809 .reinterpret => |reinterpret| {
27749 const field_offset_u64 = field_ptr.container_ty.structFieldOffset(field_index, target);
27810 const field_offset_u64 = field_ptr.container_ty.structFieldOffset(field_index, mod);
2775027811 const field_offset = try sema.usizeCast(block, src, field_offset_u64);
2775127812 return ComptimePtrMutationKit{
2775227813 .decl_ref_mut = parent.decl_ref_mut,
......@@ -27872,7 +27933,8 @@ fn beginComptimePtrMutationInner(
2787227933 ptr_elem_ty: Type,
2787327934 decl_ref_mut: Value.Payload.DeclRefMut.Data,
2787427935) CompileError!ComptimePtrMutationKit {
27875 const target = sema.mod.getTarget();
27936 const mod = sema.mod;
27937 const target = mod.getTarget();
2787627938 const coerce_ok = (try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_ty, true, target, src, src)) == .ok;
2787727939 if (coerce_ok) {
2787827940 return ComptimePtrMutationKit{
......@@ -27883,7 +27945,7 @@ fn beginComptimePtrMutationInner(
2788327945 }
2788427946
2788527947 // Handle the case that the decl is an array and we're actually trying to point to an element.
27886 if (decl_ty.isArrayOrVector()) {
27948 if (decl_ty.isArrayOrVector(mod)) {
2788727949 const decl_elem_ty = decl_ty.childType();
2788827950 if ((try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_elem_ty, true, target, src, src)) == .ok) {
2788927951 return ComptimePtrMutationKit{
......@@ -27894,14 +27956,14 @@ fn beginComptimePtrMutationInner(
2789427956 }
2789527957 }
2789627958
27897 if (!decl_ty.hasWellDefinedLayout()) {
27959 if (!decl_ty.hasWellDefinedLayout(mod)) {
2789827960 return ComptimePtrMutationKit{
2789927961 .decl_ref_mut = decl_ref_mut,
2790027962 .pointee = .{ .bad_decl_ty = {} },
2790127963 .ty = decl_ty,
2790227964 };
2790327965 }
27904 if (!ptr_elem_ty.hasWellDefinedLayout()) {
27966 if (!ptr_elem_ty.hasWellDefinedLayout(mod)) {
2790527967 return ComptimePtrMutationKit{
2790627968 .decl_ref_mut = decl_ref_mut,
2790727969 .pointee = .{ .bad_ptr_ty = {} },
......@@ -27951,6 +28013,7 @@ fn beginComptimePtrLoad(
2795128013 ptr_val: Value,
2795228014 maybe_array_ty: ?Type,
2795328015) ComptimePtrLoadError!ComptimePtrLoadKit {
28016 const mod = sema.mod;
2795428017 const target = sema.mod.getTarget();
2795528018 var deref: ComptimePtrLoadKit = switch (ptr_val.tag()) {
2795628019 .decl_ref,
......@@ -27966,7 +28029,7 @@ fn beginComptimePtrLoad(
2796628029 const decl_tv = try decl.typedValue();
2796728030 if (decl_tv.val.tag() == .variable) return error.RuntimeLoad;
2796828031
27969 const layout_defined = decl.ty.hasWellDefinedLayout();
28032 const layout_defined = decl.ty.hasWellDefinedLayout(mod);
2797028033 break :blk ComptimePtrLoadKit{
2797128034 .parent = if (layout_defined) .{ .tv = decl_tv, .byte_offset = 0 } else null,
2797228035 .pointee = decl_tv,
......@@ -27988,7 +28051,7 @@ fn beginComptimePtrLoad(
2798828051 }
2798928052
2799028053 if (elem_ptr.index != 0) {
27991 if (elem_ty.hasWellDefinedLayout()) {
28054 if (elem_ty.hasWellDefinedLayout(mod)) {
2799228055 if (deref.parent) |*parent| {
2799328056 // Update the byte offset (in-place)
2799428057 const elem_size = try sema.typeAbiSize(elem_ty);
......@@ -28003,7 +28066,7 @@ fn beginComptimePtrLoad(
2800328066
2800428067 // If we're loading an elem_ptr that was derived from a different type
2800528068 // than the true type of the underlying decl, we cannot deref directly
28006 const ty_matches = if (deref.pointee != null and deref.pointee.?.ty.isArrayOrVector()) x: {
28069 const ty_matches = if (deref.pointee != null and deref.pointee.?.ty.isArrayOrVector(mod)) x: {
2800728070 const deref_elem_ty = deref.pointee.?.ty.childType();
2800828071 break :x (try sema.coerceInMemoryAllowed(block, deref_elem_ty, elem_ty, false, target, src, src)) == .ok or
2800928072 (try sema.coerceInMemoryAllowed(block, elem_ty, deref_elem_ty, false, target, src, src)) == .ok;
......@@ -28018,7 +28081,7 @@ fn beginComptimePtrLoad(
2801828081 if (maybe_array_ty) |load_ty| {
2801928082 // It's possible that we're loading a [N]T, in which case we'd like to slice
2802028083 // the pointee array directly from our parent array.
28021 if (load_ty.isArrayOrVector() and load_ty.childType().eql(elem_ty, sema.mod)) {
28084 if (load_ty.isArrayOrVector(mod) and load_ty.childType().eql(elem_ty, sema.mod)) {
2802228085 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());
2802328086 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{
2802428087 .ty = try Type.array(sema.arena, N, null, elem_ty, sema.mod),
......@@ -28058,7 +28121,7 @@ fn beginComptimePtrLoad(
2805828121 const field_index = @intCast(u32, field_ptr.field_index);
2805928122 var deref = try sema.beginComptimePtrLoad(block, src, field_ptr.container_ptr, field_ptr.container_ty);
2806028123
28061 if (field_ptr.container_ty.hasWellDefinedLayout()) {
28124 if (field_ptr.container_ty.hasWellDefinedLayout(mod)) {
2806228125 const struct_ty = field_ptr.container_ty.castTag(.@"struct");
2806328126 if (struct_ty != null and struct_ty.?.data.layout == .Packed) {
2806428127 // packed structs are not byte addressable
......@@ -28066,7 +28129,7 @@ fn beginComptimePtrLoad(
2806628129 } else if (deref.parent) |*parent| {
2806728130 // Update the byte offset (in-place)
2806828131 try sema.resolveTypeLayout(field_ptr.container_ty);
28069 const field_offset = field_ptr.container_ty.structFieldOffset(field_index, target);
28132 const field_offset = field_ptr.container_ty.structFieldOffset(field_index, mod);
2807028133 parent.byte_offset = try sema.usizeCast(block, src, parent.byte_offset + field_offset);
2807128134 }
2807228135 } else {
......@@ -28103,7 +28166,7 @@ fn beginComptimePtrLoad(
2810328166 const field_ty = field_ptr.container_ty.structFieldType(field_index);
2810428167 deref.pointee = TypedValue{
2810528168 .ty = field_ty,
28106 .val = tv.val.fieldValue(tv.ty, field_index),
28169 .val = tv.val.fieldValue(tv.ty, mod, field_index),
2810728170 };
2810828171 }
2810928172 break :blk deref;
......@@ -28146,7 +28209,7 @@ fn beginComptimePtrLoad(
2814628209 return sema.fail(block, src, "attempt to unwrap error: {s}", .{tv.val.castTag(.@"error").?.data.name});
2814728210 },
2814828211 .opt_payload_ptr => if (tv.val.castTag(.opt_payload)) |some| some.data else opt: {
28149 if (tv.val.isNull()) return sema.fail(block, src, "attempt to use null value", .{});
28212 if (tv.val.isNull(mod)) return sema.fail(block, src, "attempt to use null value", .{});
2815028213 break :opt tv.val;
2815128214 },
2815228215 else => unreachable,
......@@ -28181,7 +28244,7 @@ fn beginComptimePtrLoad(
2818128244 };
2818228245
2818328246 if (deref.pointee) |tv| {
28184 if (deref.parent == null and tv.ty.hasWellDefinedLayout()) {
28247 if (deref.parent == null and tv.ty.hasWellDefinedLayout(mod)) {
2818528248 deref.parent = .{ .tv = tv, .byte_offset = 0 };
2818628249 }
2818728250 }
......@@ -28196,15 +28259,15 @@ fn bitCast(
2819628259 inst_src: LazySrcLoc,
2819728260 operand_src: ?LazySrcLoc,
2819828261) CompileError!Air.Inst.Ref {
28262 const mod = sema.mod;
2819928263 const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
2820028264 try sema.resolveTypeLayout(dest_ty);
2820128265
2820228266 const old_ty = try sema.resolveTypeFields(sema.typeOf(inst));
2820328267 try sema.resolveTypeLayout(old_ty);
2820428268
28205 const target = sema.mod.getTarget();
28206 const dest_bits = dest_ty.bitSize(target);
28207 const old_bits = old_ty.bitSize(target);
28269 const dest_bits = dest_ty.bitSize(mod);
28270 const old_bits = old_ty.bitSize(mod);
2820828271
2820928272 if (old_bits != dest_bits) {
2821028273 return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{
......@@ -28233,20 +28296,20 @@ fn bitCastVal(
2823328296 new_ty: Type,
2823428297 buffer_offset: usize,
2823528298) !?Value {
28236 const target = sema.mod.getTarget();
28237 if (old_ty.eql(new_ty, sema.mod)) return val;
28299 const mod = sema.mod;
28300 if (old_ty.eql(new_ty, mod)) return val;
2823828301
2823928302 // For types with well-defined memory layouts, we serialize them a byte buffer,
2824028303 // then deserialize to the new type.
28241 const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));
28304 const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(mod));
2824228305 const buffer = try sema.gpa.alloc(u8, abi_size);
2824328306 defer sema.gpa.free(buffer);
28244 val.writeToMemory(old_ty, sema.mod, buffer) catch |err| switch (err) {
28307 val.writeToMemory(old_ty, mod, buffer) catch |err| switch (err) {
2824528308 error.ReinterpretDeclRef => return null,
2824628309 error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already
28247 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{old_ty.fmt(sema.mod)}),
28310 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{old_ty.fmt(mod)}),
2824828311 };
28249 return try Value.readFromMemory(new_ty, sema.mod, buffer[buffer_offset..], sema.arena);
28312 return try Value.readFromMemory(new_ty, mod, buffer[buffer_offset..], sema.arena);
2825028313}
2825128314
2825228315fn coerceArrayPtrToSlice(
......@@ -28272,7 +28335,8 @@ fn coerceArrayPtrToSlice(
2827228335fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool {
2827328336 const dest_info = dest_ty.ptrInfo().data;
2827428337 const inst_info = inst_ty.ptrInfo().data;
28275 const len0 = (inst_info.pointee_type.zigTypeTag() == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel() == 0 or
28338 const mod = sema.mod;
28339 const len0 = (inst_info.pointee_type.zigTypeTag(mod) == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel() == 0 or
2827628340 (inst_info.pointee_type.arrayLen() == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or
2827728341 (inst_info.pointee_type.isTuple() and inst_info.pointee_type.structFieldCount() == 0);
2827828342
......@@ -28298,17 +28362,16 @@ fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_resul
2829828362 }
2829928363 if (inst_info.@"align" == 0 and dest_info.@"align" == 0) return true;
2830028364 if (len0) return true;
28301 const target = sema.mod.getTarget();
2830228365
2830328366 const inst_align = if (inst_info.@"align" != 0)
2830428367 inst_info.@"align"
2830528368 else
28306 inst_info.pointee_type.abiAlignment(target);
28369 inst_info.pointee_type.abiAlignment(mod);
2830728370
2830828371 const dest_align = if (dest_info.@"align" != 0)
2830928372 dest_info.@"align"
2831028373 else
28311 dest_info.pointee_type.abiAlignment(target);
28374 dest_info.pointee_type.abiAlignment(mod);
2831228375
2831328376 if (dest_align > inst_align) {
2831428377 in_memory_result.* = .{ .ptr_alignment = .{
......@@ -28327,18 +28390,19 @@ fn coerceCompatiblePtrs(
2832728390 inst: Air.Inst.Ref,
2832828391 inst_src: LazySrcLoc,
2832928392) !Air.Inst.Ref {
28393 const mod = sema.mod;
2833028394 const inst_ty = sema.typeOf(inst);
2833128395 if (try sema.resolveMaybeUndefVal(inst)) |val| {
28332 if (!val.isUndef() and val.isNull() and !dest_ty.isAllowzeroPtr()) {
28396 if (!val.isUndef() and val.isNull(mod) and !dest_ty.isAllowzeroPtr(mod)) {
2833328397 return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(sema.mod)});
2833428398 }
2833528399 // The comptime Value representation is compatible with both types.
2833628400 return sema.addConstant(dest_ty, val);
2833728401 }
2833828402 try sema.requireRuntimeBlock(block, inst_src, null);
28339 const inst_allows_zero = inst_ty.zigTypeTag() != .Pointer or inst_ty.ptrAllowsZero();
28340 if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero() and
28341 (try sema.typeHasRuntimeBits(dest_ty.elemType2()) or dest_ty.elemType2().zigTypeTag() == .Fn))
28403 const inst_allows_zero = inst_ty.zigTypeTag(mod) != .Pointer or inst_ty.ptrAllowsZero(mod);
28404 if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(mod) and
28405 (try sema.typeHasRuntimeBits(dest_ty.elemType2(mod)) or dest_ty.elemType2(mod).zigTypeTag(mod) == .Fn))
2834228406 {
2834328407 const actual_ptr = if (inst_ty.isSlice())
2834428408 try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)
......@@ -28364,6 +28428,7 @@ fn coerceEnumToUnion(
2836428428 inst: Air.Inst.Ref,
2836528429 inst_src: LazySrcLoc,
2836628430) !Air.Inst.Ref {
28431 const mod = sema.mod;
2836728432 const inst_ty = sema.typeOf(inst);
2836828433
2836928434 const tag_ty = union_ty.unionTagType() orelse {
......@@ -28396,7 +28461,7 @@ fn coerceEnumToUnion(
2839628461 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
2839728462 const field = union_obj.fields.values()[field_index];
2839828463 const field_ty = try sema.resolveTypeFields(field.ty);
28399 if (field_ty.zigTypeTag() == .NoReturn) {
28464 if (field_ty.zigTypeTag(mod) == .NoReturn) {
2840028465 const msg = msg: {
2840128466 const msg = try sema.errMsg(block, inst_src, "cannot initialize 'noreturn' field of union", .{});
2840228467 errdefer msg.destroy(sema.gpa);
......@@ -28449,7 +28514,7 @@ fn coerceEnumToUnion(
2844928514 errdefer if (msg) |some| some.destroy(sema.gpa);
2845028515
2845128516 for (union_obj.fields.values(), 0..) |field, i| {
28452 if (field.ty.zigTypeTag() == .NoReturn) {
28517 if (field.ty.zigTypeTag(mod) == .NoReturn) {
2845328518 const err_msg = msg orelse try sema.errMsg(
2845428519 block,
2845528520 inst_src,
......@@ -28469,7 +28534,7 @@ fn coerceEnumToUnion(
2846928534 }
2847028535
2847128536 // If the union has all fields 0 bits, the union value is just the enum value.
28472 if (union_ty.unionHasAllZeroBitFieldTypes()) {
28537 if (union_ty.unionHasAllZeroBitFieldTypes(mod)) {
2847328538 return block.addBitCast(union_ty, enum_tag);
2847428539 }
2847528540
......@@ -28487,7 +28552,7 @@ fn coerceEnumToUnion(
2848728552 while (it.next()) |field| : (field_index += 1) {
2848828553 const field_name = field.key_ptr.*;
2848928554 const field_ty = field.value_ptr.ty;
28490 if (!field_ty.hasRuntimeBits()) continue;
28555 if (!(try sema.typeHasRuntimeBits(field_ty))) continue;
2849128556 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) });
2849228557 }
2849328558 try sema.addDeclaredHereNote(msg, union_ty);
......@@ -29066,12 +29131,13 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo
2906629131}
2906729132
2906829133fn maybeQueueFuncBodyAnalysis(sema: *Sema, decl_index: Decl.Index) !void {
29069 const decl = sema.mod.declPtr(decl_index);
29134 const mod = sema.mod;
29135 const decl = mod.declPtr(decl_index);
2907029136 const tv = try decl.typedValue();
29071 if (tv.ty.zigTypeTag() != .Fn) return;
29137 if (tv.ty.zigTypeTag(mod) != .Fn) return;
2907229138 if (!try sema.fnHasRuntimeBits(tv.ty)) return;
2907329139 const func = tv.val.castTag(.function) orelse return; // undef or extern_fn
29074 try sema.mod.ensureFuncBodyAnalysisQueued(func.data);
29140 try mod.ensureFuncBodyAnalysisQueued(func.data);
2907529141}
2907629142
2907729143fn analyzeRef(
......@@ -29124,8 +29190,9 @@ fn analyzeLoad(
2912429190 ptr: Air.Inst.Ref,
2912529191 ptr_src: LazySrcLoc,
2912629192) CompileError!Air.Inst.Ref {
29193 const mod = sema.mod;
2912729194 const ptr_ty = sema.typeOf(ptr);
29128 const elem_ty = switch (ptr_ty.zigTypeTag()) {
29195 const elem_ty = switch (ptr_ty.zigTypeTag(mod)) {
2912929196 .Pointer => ptr_ty.childType(),
2913029197 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)}),
2913129198 };
......@@ -29196,12 +29263,13 @@ fn analyzeIsNull(
2919629263 operand: Air.Inst.Ref,
2919729264 invert_logic: bool,
2919829265) CompileError!Air.Inst.Ref {
29266 const mod = sema.mod;
2919929267 const result_ty = Type.bool;
2920029268 if (try sema.resolveMaybeUndefVal(operand)) |opt_val| {
2920129269 if (opt_val.isUndef()) {
2920229270 return sema.addConstUndef(result_ty);
2920329271 }
29204 const is_null = opt_val.isNull();
29272 const is_null = opt_val.isNull(mod);
2920529273 const bool_value = if (invert_logic) !is_null else is_null;
2920629274 if (bool_value) {
2920729275 return Air.Inst.Ref.bool_true;
......@@ -29213,10 +29281,10 @@ fn analyzeIsNull(
2921329281 const inverted_non_null_res = if (invert_logic) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
2921429282 const operand_ty = sema.typeOf(operand);
2921529283 var buf: Type.Payload.ElemType = undefined;
29216 if (operand_ty.zigTypeTag() == .Optional and operand_ty.optionalChild(&buf).zigTypeTag() == .NoReturn) {
29284 if (operand_ty.zigTypeTag(mod) == .Optional and operand_ty.optionalChild(&buf).zigTypeTag(mod) == .NoReturn) {
2921729285 return inverted_non_null_res;
2921829286 }
29219 if (operand_ty.zigTypeTag() != .Optional and !operand_ty.isPtrLikeOptional()) {
29287 if (operand_ty.zigTypeTag(mod) != .Optional and !operand_ty.isPtrLikeOptional(mod)) {
2922029288 return inverted_non_null_res;
2922129289 }
2922229290 try sema.requireRuntimeBlock(block, src, null);
......@@ -29230,11 +29298,12 @@ fn analyzePtrIsNonErrComptimeOnly(
2923029298 src: LazySrcLoc,
2923129299 operand: Air.Inst.Ref,
2923229300) CompileError!Air.Inst.Ref {
29301 const mod = sema.mod;
2923329302 const ptr_ty = sema.typeOf(operand);
29234 assert(ptr_ty.zigTypeTag() == .Pointer);
29303 assert(ptr_ty.zigTypeTag(mod) == .Pointer);
2923529304 const child_ty = ptr_ty.childType();
2923629305
29237 const child_tag = child_ty.zigTypeTag();
29306 const child_tag = child_ty.zigTypeTag(mod);
2923829307 if (child_tag != .ErrorSet and child_tag != .ErrorUnion) return Air.Inst.Ref.bool_true;
2923929308 if (child_tag == .ErrorSet) return Air.Inst.Ref.bool_false;
2924029309 assert(child_tag == .ErrorUnion);
......@@ -29251,14 +29320,15 @@ fn analyzeIsNonErrComptimeOnly(
2925129320 src: LazySrcLoc,
2925229321 operand: Air.Inst.Ref,
2925329322) CompileError!Air.Inst.Ref {
29323 const mod = sema.mod;
2925429324 const operand_ty = sema.typeOf(operand);
29255 const ot = operand_ty.zigTypeTag();
29325 const ot = operand_ty.zigTypeTag(mod);
2925629326 if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true;
2925729327 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;
2925829328 assert(ot == .ErrorUnion);
2925929329
2926029330 const payload_ty = operand_ty.errorUnionPayload();
29261 if (payload_ty.zigTypeTag() == .NoReturn) {
29331 if (payload_ty.zigTypeTag(mod) == .NoReturn) {
2926229332 return Air.Inst.Ref.bool_false;
2926329333 }
2926429334
......@@ -29375,22 +29445,21 @@ fn analyzeSlice(
2937529445 end_src: LazySrcLoc,
2937629446 by_length: bool,
2937729447) CompileError!Air.Inst.Ref {
29448 const mod = sema.mod;
2937829449 // Slice expressions can operate on a variable whose type is an array. This requires
2937929450 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.
2938029451 const ptr_ptr_ty = sema.typeOf(ptr_ptr);
29381 const target = sema.mod.getTarget();
29382 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag()) {
29452 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(mod)) {
2938329453 .Pointer => ptr_ptr_ty.elemType(),
2938429454 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(sema.mod)}),
2938529455 };
29386 const mod = sema.mod;
2938729456
2938829457 var array_ty = ptr_ptr_child_ty;
2938929458 var slice_ty = ptr_ptr_ty;
2939029459 var ptr_or_slice = ptr_ptr;
2939129460 var elem_ty: Type = undefined;
2939229461 var ptr_sentinel: ?Value = null;
29393 switch (ptr_ptr_child_ty.zigTypeTag()) {
29462 switch (ptr_ptr_child_ty.zigTypeTag(mod)) {
2939429463 .Array => {
2939529464 ptr_sentinel = ptr_ptr_child_ty.sentinel();
2939629465 elem_ty = ptr_ptr_child_ty.childType();
......@@ -29398,7 +29467,7 @@ fn analyzeSlice(
2939829467 .Pointer => switch (ptr_ptr_child_ty.ptrSize()) {
2939929468 .One => {
2940029469 const double_child_ty = ptr_ptr_child_ty.childType();
29401 if (double_child_ty.zigTypeTag() == .Array) {
29470 if (double_child_ty.zigTypeTag(mod) == .Array) {
2940229471 ptr_sentinel = double_child_ty.sentinel();
2940329472 ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src);
2940429473 slice_ty = ptr_ptr_child_ty;
......@@ -29417,7 +29486,7 @@ fn analyzeSlice(
2941729486
2941829487 if (ptr_ptr_child_ty.ptrSize() == .C) {
2941929488 if (try sema.resolveDefinedValue(block, ptr_src, ptr_or_slice)) |ptr_val| {
29420 if (ptr_val.isNull()) {
29489 if (ptr_val.isNull(mod)) {
2942129490 return sema.fail(block, src, "slice of null pointer", .{});
2942229491 }
2942329492 }
......@@ -29448,7 +29517,7 @@ fn analyzeSlice(
2944829517 // we might learn of the length because it is a comptime-known slice value.
2944929518 var end_is_len = uncasted_end_opt == .none;
2945029519 const end = e: {
29451 if (array_ty.zigTypeTag() == .Array) {
29520 if (array_ty.zigTypeTag(mod) == .Array) {
2945229521 const len_val = try Value.Tag.int_u64.create(sema.arena, array_ty.arrayLen());
2945329522
2945429523 if (!end_is_len) {
......@@ -29587,8 +29656,8 @@ fn analyzeSlice(
2958729656 }
2958829657 if (try sema.resolveMaybeUndefVal(new_ptr)) |ptr_val| sentinel_check: {
2958929658 const expected_sentinel = sentinel orelse break :sentinel_check;
29590 const start_int = start_val.getUnsignedInt(sema.mod.getTarget()).?;
29591 const end_int = end_val.getUnsignedInt(sema.mod.getTarget()).?;
29659 const start_int = start_val.getUnsignedInt(mod).?;
29660 const end_int = end_val.getUnsignedInt(mod).?;
2959229661 const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int);
2959329662
2959429663 const elem_ptr = try ptr_val.elemPtr(sema.typeOf(new_ptr), sema.arena, sentinel_index, sema.mod);
......@@ -29641,7 +29710,7 @@ fn analyzeSlice(
2964129710 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C;
2964229711
2964329712 if (opt_new_len_val) |new_len_val| {
29644 const new_len_int = new_len_val.toUnsignedInt(target);
29713 const new_len_int = new_len_val.toUnsignedInt(mod);
2964529714
2964629715 const return_ty = try Type.ptr(sema.arena, mod, .{
2964729716 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, mod),
......@@ -29724,7 +29793,7 @@ fn analyzeSlice(
2972429793 }
2972529794
2972629795 // requirement: end <= len
29727 const opt_len_inst = if (array_ty.zigTypeTag() == .Array)
29796 const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array)
2972829797 try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel())
2972929798 else if (slice_ty.isSlice()) blk: {
2973029799 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
......@@ -29778,14 +29847,15 @@ fn cmpNumeric(
2977829847 lhs_src: LazySrcLoc,
2977929848 rhs_src: LazySrcLoc,
2978029849) CompileError!Air.Inst.Ref {
29850 const mod = sema.mod;
2978129851 const lhs_ty = sema.typeOf(uncasted_lhs);
2978229852 const rhs_ty = sema.typeOf(uncasted_rhs);
2978329853
29784 assert(lhs_ty.isNumeric());
29785 assert(rhs_ty.isNumeric());
29854 assert(lhs_ty.isNumeric(mod));
29855 assert(rhs_ty.isNumeric(mod));
2978629856
29787 const lhs_ty_tag = lhs_ty.zigTypeTag();
29788 const rhs_ty_tag = rhs_ty.zigTypeTag();
29857 const lhs_ty_tag = lhs_ty.zigTypeTag(mod);
29858 const rhs_ty_tag = rhs_ty.zigTypeTag(mod);
2978929859 const target = sema.mod.getTarget();
2979029860
2979129861 // One exception to heterogeneous comparison: comptime_float needs to
......@@ -29805,14 +29875,14 @@ fn cmpNumeric(
2980529875 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {
2980629876 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
2980729877 // Compare ints: const vs. undefined (or vice versa)
29808 if (!lhs_val.isUndef() and (lhs_ty.isInt() or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt() and rhs_val.isUndef()) {
29878 if (!lhs_val.isUndef() and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod) and rhs_val.isUndef()) {
2980929879 try sema.resolveLazyValue(lhs_val);
29810 if (sema.compareIntsOnlyPossibleResult(target, lhs_val, op, rhs_ty)) |res| {
29880 if (try sema.compareIntsOnlyPossibleResult(lhs_val, op, rhs_ty)) |res| {
2981129881 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
2981229882 }
29813 } else if (!rhs_val.isUndef() and (rhs_ty.isInt() or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt() and lhs_val.isUndef()) {
29883 } else if (!rhs_val.isUndef() and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod) and lhs_val.isUndef()) {
2981429884 try sema.resolveLazyValue(rhs_val);
29815 if (sema.compareIntsOnlyPossibleResult(target, rhs_val, op.reverse(), lhs_ty)) |res| {
29885 if (try sema.compareIntsOnlyPossibleResult(rhs_val, op.reverse(), lhs_ty)) |res| {
2981629886 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
2981729887 }
2981829888 }
......@@ -29827,16 +29897,16 @@ fn cmpNumeric(
2982729897 return Air.Inst.Ref.bool_false;
2982829898 }
2982929899 }
29830 if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, target, sema)) {
29900 if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, mod, sema)) {
2983129901 return Air.Inst.Ref.bool_true;
2983229902 } else {
2983329903 return Air.Inst.Ref.bool_false;
2983429904 }
2983529905 } else {
29836 if (!lhs_val.isUndef() and (lhs_ty.isInt() or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt()) {
29906 if (!lhs_val.isUndef() and (lhs_ty.isInt(mod) or lhs_ty_tag == .ComptimeInt) and rhs_ty.isInt(mod)) {
2983729907 // Compare ints: const vs. var
2983829908 try sema.resolveLazyValue(lhs_val);
29839 if (sema.compareIntsOnlyPossibleResult(target, lhs_val, op, rhs_ty)) |res| {
29909 if (try sema.compareIntsOnlyPossibleResult(lhs_val, op, rhs_ty)) |res| {
2984029910 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
2984129911 }
2984229912 }
......@@ -29844,10 +29914,10 @@ fn cmpNumeric(
2984429914 }
2984529915 } else {
2984629916 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
29847 if (!rhs_val.isUndef() and (rhs_ty.isInt() or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt()) {
29917 if (!rhs_val.isUndef() and (rhs_ty.isInt(mod) or rhs_ty_tag == .ComptimeInt) and lhs_ty.isInt(mod)) {
2984829918 // Compare ints: var vs. const
2984929919 try sema.resolveLazyValue(rhs_val);
29850 if (sema.compareIntsOnlyPossibleResult(target, rhs_val, op.reverse(), lhs_ty)) |res| {
29920 if (try sema.compareIntsOnlyPossibleResult(rhs_val, op.reverse(), lhs_ty)) |res| {
2985129921 return if (res) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false;
2985229922 }
2985329923 }
......@@ -29901,11 +29971,11 @@ fn cmpNumeric(
2990129971 const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val|
2990229972 !(try lhs_val.compareAllWithZeroAdvanced(.gte, sema))
2990329973 else
29904 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt());
29974 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod));
2990529975 const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val|
2990629976 !(try rhs_val.compareAllWithZeroAdvanced(.gte, sema))
2990729977 else
29908 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt());
29978 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod));
2990929979 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;
2991029980
2991129981 var dest_float_type: ?Type = null;
......@@ -29926,7 +29996,7 @@ fn cmpNumeric(
2992629996 .lt, .lte => return if (lhs_val.isNegativeInf()) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false,
2992729997 };
2992829998 if (!rhs_is_signed) {
29929 switch (lhs_val.orderAgainstZero()) {
29999 switch (lhs_val.orderAgainstZero(mod)) {
2993030000 .gt => {},
2993130001 .eq => switch (op) { // LHS = 0, RHS is unsigned
2993230002 .lte => return Air.Inst.Ref.bool_true,
......@@ -29959,13 +30029,13 @@ fn cmpNumeric(
2995930029 }
2996030030 lhs_bits = bigint.toConst().bitCountTwosComp();
2996130031 } else {
29962 lhs_bits = lhs_val.intBitCountTwosComp(target);
30032 lhs_bits = lhs_val.intBitCountTwosComp(mod);
2996330033 }
2996430034 lhs_bits += @boolToInt(!lhs_is_signed and dest_int_is_signed);
2996530035 } else if (lhs_is_float) {
2996630036 dest_float_type = lhs_ty;
2996730037 } else {
29968 const int_info = lhs_ty.intInfo(target);
30038 const int_info = lhs_ty.intInfo(mod);
2996930039 lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
2997030040 }
2997130041
......@@ -29985,7 +30055,7 @@ fn cmpNumeric(
2998530055 .lt, .lte => return if (rhs_val.isNegativeInf()) Air.Inst.Ref.bool_false else Air.Inst.Ref.bool_true,
2998630056 };
2998730057 if (!lhs_is_signed) {
29988 switch (rhs_val.orderAgainstZero()) {
30058 switch (rhs_val.orderAgainstZero(mod)) {
2998930059 .gt => {},
2999030060 .eq => switch (op) { // RHS = 0, LHS is unsigned
2999130061 .gte => return Air.Inst.Ref.bool_true,
......@@ -30018,13 +30088,13 @@ fn cmpNumeric(
3001830088 }
3001930089 rhs_bits = bigint.toConst().bitCountTwosComp();
3002030090 } else {
30021 rhs_bits = rhs_val.intBitCountTwosComp(target);
30091 rhs_bits = rhs_val.intBitCountTwosComp(mod);
3002230092 }
3002330093 rhs_bits += @boolToInt(!rhs_is_signed and dest_int_is_signed);
3002430094 } else if (rhs_is_float) {
3002530095 dest_float_type = rhs_ty;
3002630096 } else {
30027 const int_info = rhs_ty.intInfo(target);
30097 const int_info = rhs_ty.intInfo(mod);
3002830098 rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
3002930099 }
3003030100
......@@ -30032,7 +30102,7 @@ fn cmpNumeric(
3003230102 const max_bits = std.math.max(lhs_bits, rhs_bits);
3003330103 const casted_bits = std.math.cast(u16, max_bits) orelse return sema.fail(block, src, "{d} exceeds maximum integer bit count", .{max_bits});
3003430104 const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;
30035 break :blk try Module.makeIntType(sema.arena, signedness, casted_bits);
30105 break :blk try mod.intType(signedness, casted_bits);
3003630106 };
3003730107 const casted_lhs = try sema.coerce(block, dest_ty, lhs, lhs_src);
3003830108 const casted_rhs = try sema.coerce(block, dest_ty, rhs, rhs_src);
......@@ -30040,13 +30110,20 @@ fn cmpNumeric(
3004030110 return block.addBinOp(Air.Inst.Tag.fromCmpOp(op, block.float_mode == .Optimized), casted_lhs, casted_rhs);
3004130111}
3004230112
30043/// Asserts that LHS value is an int or comptime int and not undefined, and that RHS type is an int.
30044/// Given a const LHS and an unknown RHS, attempt to determine whether `op` has a guaranteed result.
30113/// Asserts that LHS value is an int or comptime int and not undefined, and
30114/// that RHS type is an int. Given a const LHS and an unknown RHS, attempt to
30115/// determine whether `op` has a guaranteed result.
3004530116/// If it cannot be determined, returns null.
3004630117/// Otherwise returns a bool for the guaranteed comparison operation.
30047fn compareIntsOnlyPossibleResult(sema: *Sema, target: std.Target, lhs_val: Value, op: std.math.CompareOperator, rhs_ty: Type) ?bool {
30048 const rhs_info = rhs_ty.intInfo(target);
30049 const vs_zero = lhs_val.orderAgainstZeroAdvanced(sema) catch unreachable;
30118fn compareIntsOnlyPossibleResult(
30119 sema: *Sema,
30120 lhs_val: Value,
30121 op: std.math.CompareOperator,
30122 rhs_ty: Type,
30123) Allocator.Error!?bool {
30124 const mod = sema.mod;
30125 const rhs_info = rhs_ty.intInfo(mod);
30126 const vs_zero = lhs_val.orderAgainstZeroAdvanced(mod, sema) catch unreachable;
3005030127 const is_zero = vs_zero == .eq;
3005130128 const is_negative = vs_zero == .lt;
3005230129 const is_positive = vs_zero == .gt;
......@@ -30078,7 +30155,7 @@ fn compareIntsOnlyPossibleResult(sema: *Sema, target: std.Target, lhs_val: Value
3007830155 };
3007930156
3008030157 const sign_adj = @boolToInt(!is_negative and rhs_info.signedness == .signed);
30081 const req_bits = lhs_val.intBitCountTwosComp(target) + sign_adj;
30158 const req_bits = lhs_val.intBitCountTwosComp(mod) + sign_adj;
3008230159
3008330160 // No sized type can have more than 65535 bits.
3008430161 // The RHS type operand is either a runtime value or sized (but undefined) constant.
......@@ -30111,12 +30188,11 @@ fn compareIntsOnlyPossibleResult(sema: *Sema, target: std.Target, lhs_val: Value
3011130188 .max = false,
3011230189 };
3011330190
30114 var ty_buffer: Type.Payload.Bits = .{
30115 .base = .{ .tag = if (is_negative) .int_signed else .int_unsigned },
30116 .data = @intCast(u16, req_bits),
30117 };
30118 const ty = Type.initPayload(&ty_buffer.base);
30119 const pop_count = lhs_val.popCount(ty, target);
30191 const ty = try mod.intType(
30192 if (is_negative) .signed else .unsigned,
30193 @intCast(u16, req_bits),
30194 );
30195 const pop_count = lhs_val.popCount(ty, mod);
3012030196
3012130197 if (is_negative) {
3012230198 break :edge .{
......@@ -30152,10 +30228,11 @@ fn cmpVector(
3015230228 lhs_src: LazySrcLoc,
3015330229 rhs_src: LazySrcLoc,
3015430230) CompileError!Air.Inst.Ref {
30231 const mod = sema.mod;
3015530232 const lhs_ty = sema.typeOf(lhs);
3015630233 const rhs_ty = sema.typeOf(rhs);
30157 assert(lhs_ty.zigTypeTag() == .Vector);
30158 assert(rhs_ty.zigTypeTag() == .Vector);
30234 assert(lhs_ty.zigTypeTag(mod) == .Vector);
30235 assert(rhs_ty.zigTypeTag(mod) == .Vector);
3015930236 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
3016030237
3016130238 const resolved_ty = try sema.resolvePeerTypes(block, src, &.{ lhs, rhs }, .{ .override = &.{ lhs_src, rhs_src } });
......@@ -30296,16 +30373,17 @@ fn resolvePeerTypes(
3029630373 instructions: []const Air.Inst.Ref,
3029730374 candidate_srcs: Module.PeerTypeCandidateSrc,
3029830375) !Type {
30376 const mod = sema.mod;
3029930377 switch (instructions.len) {
3030030378 0 => return Type.initTag(.noreturn),
3030130379 1 => return sema.typeOf(instructions[0]),
3030230380 else => {},
3030330381 }
3030430382
30305 const target = sema.mod.getTarget();
30383 const target = mod.getTarget();
3030630384
3030730385 var chosen = instructions[0];
30308 // If this is non-null then it does the following thing, depending on the chosen zigTypeTag().
30386 // If this is non-null then it does the following thing, depending on the chosen zigTypeTag(mod).
3030930387 // * ErrorSet: this is an override
3031030388 // * ErrorUnion: this is an override of the error set only
3031130389 // * other: at the end we make an ErrorUnion with the other thing and this
......@@ -30318,8 +30396,8 @@ fn resolvePeerTypes(
3031830396 const candidate_ty = sema.typeOf(candidate);
3031930397 const chosen_ty = sema.typeOf(chosen);
3032030398
30321 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison();
30322 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison();
30399 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison(mod);
30400 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison(mod);
3032330401
3032430402 // If the candidate can coerce into our chosen type, we're done.
3032530403 // If the chosen type can coerce into the candidate, use that.
......@@ -30347,8 +30425,8 @@ fn resolvePeerTypes(
3034730425 continue;
3034830426 },
3034930427 .Int => {
30350 const chosen_info = chosen_ty.intInfo(target);
30351 const candidate_info = candidate_ty.intInfo(target);
30428 const chosen_info = chosen_ty.intInfo(mod);
30429 const candidate_info = candidate_ty.intInfo(mod);
3035230430
3035330431 if (chosen_info.bits < candidate_info.bits) {
3035430432 chosen = candidate;
......@@ -30537,7 +30615,7 @@ fn resolvePeerTypes(
3053730615 // *[N]T to []T
3053830616 if ((cand_info.size == .Many or cand_info.size == .Slice) and
3053930617 chosen_info.size == .One and
30540 chosen_info.pointee_type.zigTypeTag() == .Array)
30618 chosen_info.pointee_type.zigTypeTag(mod) == .Array)
3054130619 {
3054230620 // In case we see i.e.: `*[1]T`, `*[2]T`, `[*]T`
3054330621 convert_to_slice = false;
......@@ -30546,7 +30624,7 @@ fn resolvePeerTypes(
3054630624 continue;
3054730625 }
3054830626 if (cand_info.size == .One and
30549 cand_info.pointee_type.zigTypeTag() == .Array and
30627 cand_info.pointee_type.zigTypeTag(mod) == .Array and
3055030628 (chosen_info.size == .Many or chosen_info.size == .Slice))
3055130629 {
3055230630 // In case we see i.e.: `*[1]T`, `*[2]T`, `[*]T`
......@@ -30559,8 +30637,8 @@ fn resolvePeerTypes(
3055930637 // Keep the one whose element type can be coerced into.
3056030638 if (chosen_info.size == .One and
3056130639 cand_info.size == .One and
30562 chosen_info.pointee_type.zigTypeTag() == .Array and
30563 cand_info.pointee_type.zigTypeTag() == .Array)
30640 chosen_info.pointee_type.zigTypeTag(mod) == .Array and
30641 cand_info.pointee_type.zigTypeTag(mod) == .Array)
3056430642 {
3056530643 const chosen_elem_ty = chosen_info.pointee_type.childType();
3056630644 const cand_elem_ty = cand_info.pointee_type.childType();
......@@ -30631,7 +30709,7 @@ fn resolvePeerTypes(
3063130709 .Optional => {
3063230710 var opt_child_buf: Type.Payload.ElemType = undefined;
3063330711 const chosen_ptr_ty = chosen_ty.optionalChild(&opt_child_buf);
30634 if (chosen_ptr_ty.zigTypeTag() == .Pointer) {
30712 if (chosen_ptr_ty.zigTypeTag(mod) == .Pointer) {
3063530713 const chosen_info = chosen_ptr_ty.ptrInfo().data;
3063630714
3063730715 seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable;
......@@ -30639,7 +30717,7 @@ fn resolvePeerTypes(
3063930717 // *[N]T to ?![*]T
3064030718 // *[N]T to ?![]T
3064130719 if (cand_info.size == .One and
30642 cand_info.pointee_type.zigTypeTag() == .Array and
30720 cand_info.pointee_type.zigTypeTag(mod) == .Array and
3064330721 (chosen_info.size == .Many or chosen_info.size == .Slice))
3064430722 {
3064530723 continue;
......@@ -30648,7 +30726,7 @@ fn resolvePeerTypes(
3064830726 },
3064930727 .ErrorUnion => {
3065030728 const chosen_ptr_ty = chosen_ty.errorUnionPayload();
30651 if (chosen_ptr_ty.zigTypeTag() == .Pointer) {
30729 if (chosen_ptr_ty.zigTypeTag(mod) == .Pointer) {
3065230730 const chosen_info = chosen_ptr_ty.ptrInfo().data;
3065330731
3065430732 seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable;
......@@ -30656,7 +30734,7 @@ fn resolvePeerTypes(
3065630734 // *[N]T to E![*]T
3065730735 // *[N]T to E![]T
3065830736 if (cand_info.size == .One and
30659 cand_info.pointee_type.zigTypeTag() == .Array and
30737 cand_info.pointee_type.zigTypeTag(mod) == .Array and
3066030738 (chosen_info.size == .Many or chosen_info.size == .Slice))
3066130739 {
3066230740 continue;
......@@ -30664,7 +30742,7 @@ fn resolvePeerTypes(
3066430742 }
3066530743 },
3066630744 .Fn => {
30667 if (!cand_info.mutable and cand_info.pointee_type.zigTypeTag() == .Fn and .ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty, cand_info.pointee_type, target, src, src)) {
30745 if (!cand_info.mutable and cand_info.pointee_type.zigTypeTag(mod) == .Fn and .ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty, cand_info.pointee_type, target, src, src)) {
3066830746 chosen = candidate;
3066930747 chosen_i = candidate_i + 1;
3067030748 continue;
......@@ -30697,16 +30775,16 @@ fn resolvePeerTypes(
3069730775
3069830776 const chosen_child_ty = chosen_ty.childType();
3069930777 const candidate_child_ty = candidate_ty.childType();
30700 if (chosen_child_ty.zigTypeTag() == .Int and candidate_child_ty.zigTypeTag() == .Int) {
30701 const chosen_info = chosen_child_ty.intInfo(target);
30702 const candidate_info = candidate_child_ty.intInfo(target);
30778 if (chosen_child_ty.zigTypeTag(mod) == .Int and candidate_child_ty.zigTypeTag(mod) == .Int) {
30779 const chosen_info = chosen_child_ty.intInfo(mod);
30780 const candidate_info = candidate_child_ty.intInfo(mod);
3070330781 if (chosen_info.bits < candidate_info.bits) {
3070430782 chosen = candidate;
3070530783 chosen_i = candidate_i + 1;
3070630784 }
3070730785 continue;
3070830786 }
30709 if (chosen_child_ty.zigTypeTag() == .Float and candidate_child_ty.zigTypeTag() == .Float) {
30787 if (chosen_child_ty.zigTypeTag(mod) == .Float and candidate_child_ty.zigTypeTag(mod) == .Float) {
3071030788 if (chosen_ty.floatBits(target) < candidate_ty.floatBits(target)) {
3071130789 chosen = candidate;
3071230790 chosen_i = candidate_i + 1;
......@@ -30725,7 +30803,7 @@ fn resolvePeerTypes(
3072530803 .Vector => continue,
3072630804 else => {},
3072730805 },
30728 .Fn => if (chosen_ty.isSinglePointer() and chosen_ty.isConstPtr() and chosen_ty.childType().zigTypeTag() == .Fn) {
30806 .Fn => if (chosen_ty.isSinglePointer() and chosen_ty.isConstPtr() and chosen_ty.childType().zigTypeTag(mod) == .Fn) {
3072930807 if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(), candidate_ty, target, src, src)) {
3073030808 continue;
3073130809 }
......@@ -30790,27 +30868,27 @@ fn resolvePeerTypes(
3079030868 // the source locations.
3079130869 const chosen_src = candidate_srcs.resolve(
3079230870 sema.gpa,
30793 sema.mod.declPtr(block.src_decl),
30871 mod.declPtr(block.src_decl),
3079430872 chosen_i,
3079530873 );
3079630874 const candidate_src = candidate_srcs.resolve(
3079730875 sema.gpa,
30798 sema.mod.declPtr(block.src_decl),
30876 mod.declPtr(block.src_decl),
3079930877 candidate_i + 1,
3080030878 );
3080130879
3080230880 const msg = msg: {
3080330881 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{
30804 chosen_ty.fmt(sema.mod),
30805 candidate_ty.fmt(sema.mod),
30882 chosen_ty.fmt(mod),
30883 candidate_ty.fmt(mod),
3080630884 });
3080730885 errdefer msg.destroy(sema.gpa);
3080830886
3080930887 if (chosen_src) |src_loc|
30810 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty.fmt(sema.mod)});
30888 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty.fmt(mod)});
3081130889
3081230890 if (candidate_src) |src_loc|
30813 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty.fmt(sema.mod)});
30891 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty.fmt(mod)});
3081430892
3081530893 break :msg msg;
3081630894 };
......@@ -30826,72 +30904,73 @@ fn resolvePeerTypes(
3082630904 info.data.sentinel = chosen_child_ty.sentinel();
3082730905 info.data.size = .Slice;
3082830906 info.data.mutable = !(seen_const or chosen_child_ty.isConstPtr());
30829 info.data.pointee_type = chosen_child_ty.elemType2();
30907 info.data.pointee_type = chosen_child_ty.elemType2(mod);
3083030908
30831 const new_ptr_ty = try Type.ptr(sema.arena, sema.mod, info.data);
30909 const new_ptr_ty = try Type.ptr(sema.arena, mod, info.data);
3083230910 const opt_ptr_ty = if (any_are_null)
3083330911 try Type.optional(sema.arena, new_ptr_ty)
3083430912 else
3083530913 new_ptr_ty;
3083630914 const set_ty = err_set_ty orelse return opt_ptr_ty;
30837 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, sema.mod);
30915 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, mod);
3083830916 }
3083930917
3084030918 if (seen_const) {
3084130919 // turn []T => []const T
30842 switch (chosen_ty.zigTypeTag()) {
30920 switch (chosen_ty.zigTypeTag(mod)) {
3084330921 .ErrorUnion => {
3084430922 const ptr_ty = chosen_ty.errorUnionPayload();
3084530923 var info = ptr_ty.ptrInfo();
3084630924 info.data.mutable = false;
30847 const new_ptr_ty = try Type.ptr(sema.arena, sema.mod, info.data);
30925 const new_ptr_ty = try Type.ptr(sema.arena, mod, info.data);
3084830926 const opt_ptr_ty = if (any_are_null)
3084930927 try Type.optional(sema.arena, new_ptr_ty)
3085030928 else
3085130929 new_ptr_ty;
3085230930 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();
30853 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, sema.mod);
30931 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, mod);
3085430932 },
3085530933 .Pointer => {
3085630934 var info = chosen_ty.ptrInfo();
3085730935 info.data.mutable = false;
30858 const new_ptr_ty = try Type.ptr(sema.arena, sema.mod, info.data);
30936 const new_ptr_ty = try Type.ptr(sema.arena, mod, info.data);
3085930937 const opt_ptr_ty = if (any_are_null)
3086030938 try Type.optional(sema.arena, new_ptr_ty)
3086130939 else
3086230940 new_ptr_ty;
3086330941 const set_ty = err_set_ty orelse return opt_ptr_ty;
30864 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, sema.mod);
30942 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, mod);
3086530943 },
3086630944 else => return chosen_ty,
3086730945 }
3086830946 }
3086930947
3087030948 if (any_are_null) {
30871 const opt_ty = switch (chosen_ty.zigTypeTag()) {
30949 const opt_ty = switch (chosen_ty.zigTypeTag(mod)) {
3087230950 .Null, .Optional => chosen_ty,
3087330951 else => try Type.optional(sema.arena, chosen_ty),
3087430952 };
3087530953 const set_ty = err_set_ty orelse return opt_ty;
30876 return try Type.errorUnion(sema.arena, set_ty, opt_ty, sema.mod);
30954 return try Type.errorUnion(sema.arena, set_ty, opt_ty, mod);
3087730955 }
3087830956
30879 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) {
30957 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag(mod)) {
3088030958 .ErrorSet => return ty,
3088130959 .ErrorUnion => {
3088230960 const payload_ty = chosen_ty.errorUnionPayload();
30883 return try Type.errorUnion(sema.arena, ty, payload_ty, sema.mod);
30961 return try Type.errorUnion(sema.arena, ty, payload_ty, mod);
3088430962 },
30885 else => return try Type.errorUnion(sema.arena, ty, chosen_ty, sema.mod),
30963 else => return try Type.errorUnion(sema.arena, ty, chosen_ty, mod),
3088630964 };
3088730965
3088830966 return chosen_ty;
3088930967}
3089030968
3089130969pub fn resolveFnTypes(sema: *Sema, fn_info: Type.Payload.Function.Data) CompileError!void {
30970 const mod = sema.mod;
3089230971 try sema.resolveTypeFully(fn_info.return_type);
3089330972
30894 if (sema.mod.comp.bin_file.options.error_return_tracing and fn_info.return_type.isError()) {
30973 if (mod.comp.bin_file.options.error_return_tracing and fn_info.return_type.isError(mod)) {
3089530974 // Ensure the type exists so that backends can assume that.
3089630975 _ = try sema.getBuiltinType("StackTrace");
3089730976 }
......@@ -30943,7 +31022,8 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!void {
3094331022}
3094431023
3094531024pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
30946 switch (ty.zigTypeTag()) {
31025 const mod = sema.mod;
31026 switch (ty.zigTypeTag(mod)) {
3094731027 .Struct => return sema.resolveStructLayout(ty),
3094831028 .Union => return sema.resolveUnionLayout(ty),
3094931029 .Array => {
......@@ -31021,7 +31101,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3102131101 struct_obj.status = .have_layout;
3102231102 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
3102331103
31024 if (struct_obj.assumed_runtime_bits and !resolved_ty.hasRuntimeBits()) {
31104 if (struct_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(resolved_ty))) {
3102531105 const msg = try Module.ErrorMsg.create(
3102631106 sema.gpa,
3102731107 struct_obj.srcLoc(sema.mod),
......@@ -31043,7 +31123,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3104331123 };
3104431124
3104531125 for (struct_obj.fields.values(), 0..) |field, i| {
31046 optimized_order[i] = if (field.ty.hasRuntimeBits())
31126 optimized_order[i] = if (!(try sema.typeHasRuntimeBits(field.ty)))
3104731127 @intCast(u32, i)
3104831128 else
3104931129 Module.Struct.omitted_field;
......@@ -31054,11 +31134,11 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3105431134 sema: *Sema,
3105531135
3105631136 fn lessThan(ctx: @This(), a: u32, b: u32) bool {
31137 const m = ctx.sema.mod;
3105731138 if (a == Module.Struct.omitted_field) return false;
3105831139 if (b == Module.Struct.omitted_field) return true;
31059 const target = ctx.sema.mod.getTarget();
31060 return ctx.struct_obj.fields.values()[a].ty.abiAlignment(target) >
31061 ctx.struct_obj.fields.values()[b].ty.abiAlignment(target);
31140 return ctx.struct_obj.fields.values()[a].ty.abiAlignment(m) >
31141 ctx.struct_obj.fields.values()[b].ty.abiAlignment(m);
3106231142 }
3106331143 };
3106431144 mem.sort(u32, optimized_order, AlignSortContext{
......@@ -31073,11 +31153,10 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3107331153
3107431154fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!void {
3107531155 const gpa = mod.gpa;
31076 const target = mod.getTarget();
3107731156
3107831157 var fields_bit_sum: u64 = 0;
3107931158 for (struct_obj.fields.values()) |field| {
31080 fields_bit_sum += field.ty.bitSize(target);
31159 fields_bit_sum += field.ty.bitSize(mod);
3108131160 }
3108231161
3108331162 const decl_index = struct_obj.owner_decl;
......@@ -31178,32 +31257,29 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
3117831257 };
3117931258 return sema.fail(&block, LazySrcLoc.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
3118031259 }
31181 var buf: Type.Payload.Bits = .{
31182 .base = .{ .tag = .int_unsigned },
31183 .data = @intCast(u16, fields_bit_sum),
31184 };
31185 struct_obj.backing_int_ty = try Type.initPayload(&buf.base).copy(decl_arena_allocator);
31260 struct_obj.backing_int_ty = try mod.intType(.unsigned, @intCast(u16, fields_bit_sum));
3118631261 }
3118731262}
3118831263
3118931264fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void {
31190 const target = sema.mod.getTarget();
31265 const mod = sema.mod;
3119131266
31192 if (!backing_int_ty.isInt()) {
31267 if (!backing_int_ty.isInt(mod)) {
3119331268 return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(sema.mod)});
3119431269 }
31195 if (backing_int_ty.bitSize(target) != fields_bit_sum) {
31270 if (backing_int_ty.bitSize(mod) != fields_bit_sum) {
3119631271 return sema.fail(
3119731272 block,
3119831273 src,
3119931274 "backing integer type '{}' has bit size {} but the struct fields have a total bit size of {}",
31200 .{ backing_int_ty.fmt(sema.mod), backing_int_ty.bitSize(target), fields_bit_sum },
31275 .{ backing_int_ty.fmt(sema.mod), backing_int_ty.bitSize(mod), fields_bit_sum },
3120131276 );
3120231277 }
3120331278}
3120431279
3120531280fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
31206 if (!ty.isIndexable()) {
31281 const mod = sema.mod;
31282 if (!ty.isIndexable(mod)) {
3120731283 const msg = msg: {
3120831284 const msg = try sema.errMsg(block, src, "type '{}' does not support indexing", .{ty.fmt(sema.mod)});
3120931285 errdefer msg.destroy(sema.gpa);
......@@ -31215,12 +31291,13 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
3121531291}
3121631292
3121731293fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
31218 if (ty.zigTypeTag() == .Pointer) {
31294 const mod = sema.mod;
31295 if (ty.zigTypeTag(mod) == .Pointer) {
3121931296 switch (ty.ptrSize()) {
3122031297 .Slice, .Many, .C => return,
3122131298 .One => {
3122231299 const elem_ty = ty.childType();
31223 if (elem_ty.zigTypeTag() == .Array) return;
31300 if (elem_ty.zigTypeTag(mod) == .Array) return;
3122431301 // TODO https://github.com/ziglang/zig/issues/15479
3122531302 // if (elem_ty.isTuple()) return;
3122631303 },
......@@ -31270,7 +31347,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3127031347 union_obj.status = .have_layout;
3127131348 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
3127231349
31273 if (union_obj.assumed_runtime_bits and !resolved_ty.hasRuntimeBits()) {
31350 if (union_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(resolved_ty))) {
3127431351 const msg = try Module.ErrorMsg.create(
3127531352 sema.gpa,
3127631353 union_obj.srcLoc(sema.mod),
......@@ -31285,6 +31362,23 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3128531362// for hasRuntimeBits() of each field, so we need "requires comptime"
3128631363// to be known already before this function returns.
3128731364pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
31365 const mod = sema.mod;
31366
31367 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
31368 .int_type => return false,
31369 .ptr_type => @panic("TODO"),
31370 .array_type => @panic("TODO"),
31371 .vector_type => @panic("TODO"),
31372 .optional_type => @panic("TODO"),
31373 .error_union_type => @panic("TODO"),
31374 .simple_type => @panic("TODO"),
31375 .struct_type => @panic("TODO"),
31376 .simple_value => unreachable,
31377 .extern_func => unreachable,
31378 .int => unreachable,
31379 .enum_tag => unreachable, // it's a value, not a type
31380 };
31381
3128831382 return switch (ty.tag()) {
3128931383 .u1,
3129031384 .u8,
......@@ -31349,8 +31443,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3134931443 .generic_poison,
3135031444 .array_u8,
3135131445 .array_u8_sentinel_0,
31352 .int_signed,
31353 .int_unsigned,
3135431446 .enum_simple,
3135531447 => false,
3135631448
......@@ -31360,11 +31452,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3136031452 .comptime_float,
3136131453 .enum_literal,
3136231454 .type_info,
31363 // These are function bodies, not function pointers.
31364 .fn_noreturn_no_args,
31365 .fn_void_no_args,
31366 .fn_naked_noreturn_no_args,
31367 .fn_ccc_void_no_args,
3136831455 .function,
3136931456 => true,
3137031457
......@@ -31387,7 +31474,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3138731474 .mut_slice,
3138831475 => {
3138931476 const child_ty = ty.childType();
31390 if (child_ty.zigTypeTag() == .Fn) {
31477 if (child_ty.zigTypeTag(mod) == .Fn) {
3139131478 return child_ty.fnInfo().is_generic;
3139231479 } else {
3139331480 return sema.resolveTypeRequiresComptime(child_ty);
......@@ -31474,7 +31561,8 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3147431561/// Returns `error.AnalysisFail` if any of the types (recursively) failed to
3147531562/// be resolved.
3147631563pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
31477 switch (ty.zigTypeTag()) {
31564 const mod = sema.mod;
31565 switch (ty.zigTypeTag(mod)) {
3147831566 .Pointer => {
3147931567 const child_ty = try sema.resolveTypeFields(ty.childType());
3148031568 return sema.resolveTypeFully(child_ty);
......@@ -31840,7 +31928,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3184031928 type_body_len: u32 = 0,
3184131929 align_body_len: u32 = 0,
3184231930 init_body_len: u32 = 0,
31843 type_ref: Air.Inst.Ref = .none,
31931 type_ref: Zir.Inst.Ref = .none,
3184431932 };
3184531933 const fields = try sema.arena.alloc(Field, fields_len);
3184631934 var any_inits = false;
......@@ -31967,7 +32055,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3196732055 const field = &struct_obj.fields.values()[field_i];
3196832056 field.ty = try field_ty.copy(decl_arena_allocator);
3196932057
31970 if (field_ty.zigTypeTag() == .Opaque) {
32058 if (field_ty.zigTypeTag(mod) == .Opaque) {
3197132059 const msg = msg: {
3197232060 const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{
3197332061 .index = field_i,
......@@ -31981,7 +32069,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3198132069 };
3198232070 return sema.failWithOwnedErrorMsg(msg);
3198332071 }
31984 if (field_ty.zigTypeTag() == .NoReturn) {
32072 if (field_ty.zigTypeTag(mod) == .NoReturn) {
3198532073 const msg = msg: {
3198632074 const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{
3198732075 .index = field_i,
......@@ -32010,7 +32098,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3201032098 break :msg msg;
3201132099 };
3201232100 return sema.failWithOwnedErrorMsg(msg);
32013 } else if (struct_obj.layout == .Packed and !(validatePackedType(field.ty))) {
32101 } else if (struct_obj.layout == .Packed and !(validatePackedType(field.ty, mod))) {
3201432102 const msg = msg: {
3201532103 const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{
3201632104 .index = field_i,
......@@ -32191,7 +32279,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3219132279 if (small.auto_enum_tag) {
3219232280 // The provided type is an integer type and we must construct the enum tag type here.
3219332281 int_tag_ty = provided_ty;
32194 if (int_tag_ty.zigTypeTag() != .Int and int_tag_ty.zigTypeTag() != .ComptimeInt) {
32282 if (int_tag_ty.zigTypeTag(mod) != .Int and int_tag_ty.zigTypeTag(mod) != .ComptimeInt) {
3219532283 return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(sema.mod)});
3219632284 }
3219732285
......@@ -32220,7 +32308,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3222032308 } else {
3222132309 // The provided type is the enum tag type.
3222232310 union_obj.tag_ty = try provided_ty.copy(decl_arena_allocator);
32223 if (union_obj.tag_ty.zigTypeTag() != .Enum) {
32311 if (union_obj.tag_ty.zigTypeTag(mod) != .Enum) {
3222432312 return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)});
3222532313 }
3222632314 // The fields of the union must match the enum exactly.
......@@ -32281,7 +32369,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3228132369 break :blk align_ref;
3228232370 } else .none;
3228332371
32284 const tag_ref: Zir.Inst.Ref = if (has_tag) blk: {
32372 const tag_ref: Air.Inst.Ref = if (has_tag) blk: {
3228532373 const tag_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
3228632374 extra_index += 1;
3228732375 break :blk try sema.resolveInst(tag_ref);
......@@ -32391,7 +32479,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3239132479 }
3239232480 }
3239332481
32394 if (field_ty.zigTypeTag() == .Opaque) {
32482 if (field_ty.zigTypeTag(mod) == .Opaque) {
3239532483 const msg = msg: {
3239632484 const ty_src = union_obj.fieldSrcLoc(sema.mod, .{
3239732485 .index = field_i,
......@@ -32420,7 +32508,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3242032508 break :msg msg;
3242132509 };
3242232510 return sema.failWithOwnedErrorMsg(msg);
32423 } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty))) {
32511 } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty, mod))) {
3242432512 const msg = msg: {
3242532513 const ty_src = union_obj.fieldSrcLoc(sema.mod, .{
3242632514 .index = field_i,
......@@ -32673,6 +32761,29 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
3267332761/// that the types are already resolved.
3267432762/// TODO assert the return value matches `ty.onePossibleValue`
3267532763pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
32764 const mod = sema.mod;
32765
32766 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
32767 .int_type => |int_type| {
32768 if (int_type.bits == 0) {
32769 return Value.zero;
32770 } else {
32771 return null;
32772 }
32773 },
32774 .ptr_type => @panic("TODO"),
32775 .array_type => @panic("TODO"),
32776 .vector_type => @panic("TODO"),
32777 .optional_type => @panic("TODO"),
32778 .error_union_type => @panic("TODO"),
32779 .simple_type => @panic("TODO"),
32780 .struct_type => @panic("TODO"),
32781 .simple_value => unreachable,
32782 .extern_func => unreachable,
32783 .int => unreachable,
32784 .enum_tag => unreachable, // it's a value, not a type
32785 };
32786
3267632787 switch (ty.tag()) {
3267732788 .f16,
3267832789 .f32,
......@@ -32712,10 +32823,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3271232823 .error_set,
3271332824 .error_set_merged,
3271432825 .error_union,
32715 .fn_noreturn_no_args,
32716 .fn_void_no_args,
32717 .fn_naked_noreturn_no_args,
32718 .fn_ccc_void_no_args,
3271932826 .function,
3272032827 .single_const_pointer_to_comptime_int,
3272132828 .array_sentinel,
......@@ -32803,7 +32910,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3280332910 const resolved_ty = try sema.resolveTypeFields(ty);
3280432911 const enum_obj = resolved_ty.castTag(.enum_numbered).?.data;
3280532912 // An explicit tag type is always provided for enum_numbered.
32806 if (enum_obj.tag_ty.hasRuntimeBits()) {
32913 if (!(try sema.typeHasRuntimeBits(enum_obj.tag_ty))) {
3280732914 return null;
3280832915 }
3280932916 if (enum_obj.fields.count() == 1) {
......@@ -32819,7 +32926,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3281932926 .enum_full => {
3282032927 const resolved_ty = try sema.resolveTypeFields(ty);
3282132928 const enum_obj = resolved_ty.castTag(.enum_full).?.data;
32822 if (enum_obj.tag_ty.hasRuntimeBits()) {
32929 if (!(try sema.typeHasRuntimeBits(enum_obj.tag_ty))) {
3282332930 return null;
3282432931 }
3282532932 switch (enum_obj.fields.count()) {
......@@ -32843,7 +32950,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3284332950 },
3284432951 .enum_nonexhaustive => {
3284532952 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;
32846 if (tag_ty.zigTypeTag() != .ComptimeInt and !(try sema.typeHasRuntimeBits(tag_ty))) {
32953 if (tag_ty.zigTypeTag(mod) != .ComptimeInt and !(try sema.typeHasRuntimeBits(tag_ty))) {
3284732954 return Value.zero;
3284832955 } else {
3284932956 return null;
......@@ -32883,13 +32990,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3288332990 .null => return Value.null,
3288432991 .undefined => return Value.initTag(.undef),
3288532992
32886 .int_unsigned, .int_signed => {
32887 if (ty.cast(Type.Payload.Bits).?.data == 0) {
32888 return Value.zero;
32889 } else {
32890 return null;
32891 }
32892 },
3289332993 .vector, .array, .array_u8 => {
3289432994 if (ty.arrayLen() == 0)
3289532995 return Value.initTag(.empty_array);
......@@ -32919,6 +33019,89 @@ pub fn getTmpAir(sema: Sema) Air {
3291933019}
3292033020
3292133021pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
33022 switch (ty.ip_index) {
33023 .u1_type => return .u1_type,
33024 .u8_type => return .u8_type,
33025 .i8_type => return .i8_type,
33026 .u16_type => return .u16_type,
33027 .i16_type => return .i16_type,
33028 .u29_type => return .u29_type,
33029 .u32_type => return .u32_type,
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 }
3292233105 switch (ty.tag()) {
3292333106 .u1 => return .u1_type,
3292433107 .u8 => return .u8_type,
......@@ -32934,6 +33117,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
3293433117 .i128 => return .i128_type,
3293533118 .usize => return .usize_type,
3293633119 .isize => return .isize_type,
33120 .c_char => return .c_char_type,
3293733121 .c_short => return .c_short_type,
3293833122 .c_ushort => return .c_ushort_type,
3293933123 .c_int => return .c_int_type,
......@@ -32966,17 +33150,13 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
3296633150 .address_space => return .address_space_type,
3296733151 .float_mode => return .float_mode_type,
3296833152 .reduce_op => return .reduce_op_type,
32969 .modifier => return .modifier_type,
33153 .modifier => return .call_modifier_type,
3297033154 .prefetch_options => return .prefetch_options_type,
3297133155 .export_options => return .export_options_type,
3297233156 .extern_options => return .extern_options_type,
3297333157 .type_info => return .type_info_type,
3297433158 .manyptr_u8 => return .manyptr_u8_type,
3297533159 .manyptr_const_u8 => return .manyptr_const_u8_type,
32976 .fn_noreturn_no_args => return .fn_noreturn_no_args_type,
32977 .fn_void_no_args => return .fn_void_no_args_type,
32978 .fn_naked_noreturn_no_args => return .fn_naked_noreturn_no_args_type,
32979 .fn_ccc_void_no_args => return .fn_ccc_void_no_args_type,
3298033160 .single_const_pointer_to_comptime_int => return .single_const_pointer_to_comptime_int_type,
3298133161 .const_slice_u8 => return .const_slice_u8_type,
3298233162 .anyerror_void_error_union => return .anyerror_void_error_union_type,
......@@ -33186,7 +33366,8 @@ const DerefResult = union(enum) {
3318633366};
3318733367
3318833368fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, load_ty: Type, want_mutable: bool) CompileError!DerefResult {
33189 const target = sema.mod.getTarget();
33369 const mod = sema.mod;
33370 const target = mod.getTarget();
3319033371 const deref = sema.beginComptimePtrLoad(block, src, ptr_val, load_ty) catch |err| switch (err) {
3319133372 error.RuntimeLoad => return DerefResult{ .runtime_load = {} },
3319233373 else => |e| return e,
......@@ -33211,7 +33392,7 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value
3321133392
3321233393 // The type is not in-memory coercible or the direct dereference failed, so it must
3321333394 // be bitcast according to the pointer type we are performing the load through.
33214 if (!load_ty.hasWellDefinedLayout()) {
33395 if (!load_ty.hasWellDefinedLayout(mod)) {
3321533396 return DerefResult{ .needed_well_defined = load_ty };
3321633397 }
3321733398
......@@ -33253,6 +33434,7 @@ fn typePtrOrOptionalPtrTy(
3325333434 ty: Type,
3325433435 buf: *Type.Payload.ElemType,
3325533436) !?Type {
33437 const mod = sema.mod;
3325633438 switch (ty.tag()) {
3325733439 .optional_single_const_pointer,
3325833440 .optional_single_mut_pointer,
......@@ -33281,7 +33463,7 @@ fn typePtrOrOptionalPtrTy(
3328133463
3328233464 .optional => {
3328333465 const child_type = ty.optionalChild(buf);
33284 if (child_type.zigTypeTag() != .Pointer) return null;
33466 if (child_type.zigTypeTag(mod) != .Pointer) return null;
3328533467
3328633468 const info = child_type.ptrInfo().data;
3328733469 switch (info.size) {
......@@ -33310,6 +33492,23 @@ fn typePtrOrOptionalPtrTy(
3331033492/// TODO merge these implementations together with the "advanced"/opt_sema pattern seen
3331133493/// elsewhere in value.zig
3331233494pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33495 const mod = sema.mod;
33496 if (ty.ip_index != .none) {
33497 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
33498 .int_type => return false,
33499 .ptr_type => @panic("TODO"),
33500 .array_type => @panic("TODO"),
33501 .vector_type => @panic("TODO"),
33502 .optional_type => @panic("TODO"),
33503 .error_union_type => @panic("TODO"),
33504 .simple_type => @panic("TODO"),
33505 .struct_type => @panic("TODO"),
33506 .simple_value => unreachable,
33507 .extern_func => unreachable,
33508 .int => unreachable,
33509 .enum_tag => unreachable, // it's a value, not a type
33510 }
33511 }
3331333512 return switch (ty.tag()) {
3331433513 .u1,
3331533514 .u8,
......@@ -33374,8 +33573,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3337433573 .generic_poison,
3337533574 .array_u8,
3337633575 .array_u8_sentinel_0,
33377 .int_signed,
33378 .int_unsigned,
3337933576 .enum_simple,
3338033577 => false,
3338133578
......@@ -33385,11 +33582,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3338533582 .comptime_float,
3338633583 .enum_literal,
3338733584 .type_info,
33388 // These are function bodies, not function pointers.
33389 .fn_noreturn_no_args,
33390 .fn_void_no_args,
33391 .fn_naked_noreturn_no_args,
33392 .fn_ccc_void_no_args,
3339333585 .function,
3339433586 => true,
3339533587
......@@ -33412,7 +33604,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3341233604 .mut_slice,
3341333605 => {
3341433606 const child_ty = ty.childType();
33415 if (child_ty.zigTypeTag() == .Fn) {
33607 if (child_ty.zigTypeTag(mod) == .Fn) {
3341633608 return child_ty.fnInfo().is_generic;
3341733609 } else {
3341833610 return sema.typeRequiresComptime(child_ty);
......@@ -33504,7 +33696,8 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3350433696}
3350533697
3350633698pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
33507 return ty.hasRuntimeBitsAdvanced(false, .{ .sema = sema }) catch |err| switch (err) {
33699 const mod = sema.mod;
33700 return ty.hasRuntimeBitsAdvanced(mod, false, .{ .sema = sema }) catch |err| switch (err) {
3350833701 error.NeedLazy => unreachable,
3350933702 else => |e| return e,
3351033703 };
......@@ -33512,19 +33705,18 @@ pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
3351233705
3351333706fn typeAbiSize(sema: *Sema, ty: Type) !u64 {
3351433707 try sema.resolveTypeLayout(ty);
33515 const target = sema.mod.getTarget();
33516 return ty.abiSize(target);
33708 return ty.abiSize(sema.mod);
3351733709}
3351833710
3351933711fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!u32 {
33520 const target = sema.mod.getTarget();
33521 return (try ty.abiAlignmentAdvanced(target, .{ .sema = sema })).scalar;
33712 return (try ty.abiAlignmentAdvanced(sema.mod, .{ .sema = sema })).scalar;
3352233713}
3352333714
3352433715/// Not valid to call for packed unions.
3352533716/// Keep implementation in sync with `Module.Union.Field.normalAlignment`.
3352633717fn unionFieldAlignment(sema: *Sema, field: Module.Union.Field) !u32 {
33527 if (field.ty.zigTypeTag() == .NoReturn) {
33718 const mod = sema.mod;
33719 if (field.ty.zigTypeTag(mod) == .NoReturn) {
3352833720 return @as(u32, 0);
3352933721 } else if (field.abi_align == 0) {
3353033722 return sema.typeAbiAlignment(field.ty);
......@@ -33605,13 +33797,14 @@ fn queueFullTypeResolution(sema: *Sema, ty: Type) !void {
3360533797}
3360633798
3360733799fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value {
33608 if (ty.zigTypeTag() == .Vector) {
33800 const mod = sema.mod;
33801 if (ty.zigTypeTag(mod) == .Vector) {
3360933802 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
3361033803 for (result_data, 0..) |*scalar, i| {
3361133804 var lhs_buf: Value.ElemValueBuffer = undefined;
3361233805 var rhs_buf: Value.ElemValueBuffer = undefined;
33613 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
33614 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
33806 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
33807 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3361533808 scalar.* = try sema.intAddScalar(lhs_elem, rhs_elem);
3361633809 }
3361733810 return Value.Tag.aggregate.create(sema.arena, result_data);
......@@ -33620,13 +33813,13 @@ fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value {
3362033813}
3362133814
3362233815fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {
33816 const mod = sema.mod;
3362333817 // TODO is this a performance issue? maybe we should try the operation without
3362433818 // resorting to BigInt first.
3362533819 var lhs_space: Value.BigIntSpace = undefined;
3362633820 var rhs_space: Value.BigIntSpace = undefined;
33627 const target = sema.mod.getTarget();
33628 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema);
33629 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema);
33821 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
33822 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
3363033823 const limbs = try sema.arena.alloc(
3363133824 std.math.big.Limb,
3363233825 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
......@@ -33645,7 +33838,8 @@ fn numberAddWrapScalar(
3364533838) !Value {
3364633839 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
3364733840
33648 if (ty.zigTypeTag() == .ComptimeInt) {
33841 const mod = sema.mod;
33842 if (ty.zigTypeTag(mod) == .ComptimeInt) {
3364933843 return sema.intAdd(lhs, rhs, ty);
3365033844 }
3365133845
......@@ -33663,7 +33857,8 @@ fn intSub(
3366333857 rhs: Value,
3366433858 ty: Type,
3366533859) !Value {
33666 if (ty.zigTypeTag() == .Vector) {
33860 const mod = sema.mod;
33861 if (ty.zigTypeTag(mod) == .Vector) {
3366733862 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
3366833863 for (result_data, 0..) |*scalar, i| {
3366933864 var lhs_buf: Value.ElemValueBuffer = undefined;
......@@ -33678,13 +33873,13 @@ fn intSub(
3367833873}
3367933874
3368033875fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value) !Value {
33876 const mod = sema.mod;
3368133877 // TODO is this a performance issue? maybe we should try the operation without
3368233878 // resorting to BigInt first.
3368333879 var lhs_space: Value.BigIntSpace = undefined;
3368433880 var rhs_space: Value.BigIntSpace = undefined;
33685 const target = sema.mod.getTarget();
33686 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema);
33687 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema);
33881 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
33882 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
3368833883 const limbs = try sema.arena.alloc(
3368933884 std.math.big.Limb,
3369033885 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
......@@ -33703,7 +33898,8 @@ fn numberSubWrapScalar(
3370333898) !Value {
3370433899 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
3370533900
33706 if (ty.zigTypeTag() == .ComptimeInt) {
33901 const mod = sema.mod;
33902 if (ty.zigTypeTag(mod) == .ComptimeInt) {
3370733903 return sema.intSub(lhs, rhs, ty);
3370833904 }
3370933905
......@@ -33721,14 +33917,15 @@ fn floatAdd(
3372133917 rhs: Value,
3372233918 float_type: Type,
3372333919) !Value {
33724 if (float_type.zigTypeTag() == .Vector) {
33920 const mod = sema.mod;
33921 if (float_type.zigTypeTag(mod) == .Vector) {
3372533922 const result_data = try sema.arena.alloc(Value, float_type.vectorLen());
3372633923 for (result_data, 0..) |*scalar, i| {
3372733924 var lhs_buf: Value.ElemValueBuffer = undefined;
3372833925 var rhs_buf: Value.ElemValueBuffer = undefined;
3372933926 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
3373033927 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
33731 scalar.* = try sema.floatAddScalar(lhs_elem, rhs_elem, float_type.scalarType());
33928 scalar.* = try sema.floatAddScalar(lhs_elem, rhs_elem, float_type.scalarType(mod));
3373233929 }
3373333930 return Value.Tag.aggregate.create(sema.arena, result_data);
3373433931 }
......@@ -33778,14 +33975,15 @@ fn floatSub(
3377833975 rhs: Value,
3377933976 float_type: Type,
3378033977) !Value {
33781 if (float_type.zigTypeTag() == .Vector) {
33978 const mod = sema.mod;
33979 if (float_type.zigTypeTag(mod) == .Vector) {
3378233980 const result_data = try sema.arena.alloc(Value, float_type.vectorLen());
3378333981 for (result_data, 0..) |*scalar, i| {
3378433982 var lhs_buf: Value.ElemValueBuffer = undefined;
3378533983 var rhs_buf: Value.ElemValueBuffer = undefined;
3378633984 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
3378733985 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
33788 scalar.* = try sema.floatSubScalar(lhs_elem, rhs_elem, float_type.scalarType());
33986 scalar.* = try sema.floatSubScalar(lhs_elem, rhs_elem, float_type.scalarType(mod));
3378933987 }
3379033988 return Value.Tag.aggregate.create(sema.arena, result_data);
3379133989 }
......@@ -33835,7 +34033,8 @@ fn intSubWithOverflow(
3383534033 rhs: Value,
3383634034 ty: Type,
3383734035) !Value.OverflowArithmeticResult {
33838 if (ty.zigTypeTag() == .Vector) {
34036 const mod = sema.mod;
34037 if (ty.zigTypeTag(mod) == .Vector) {
3383934038 const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen());
3384034039 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
3384134040 for (result_data, 0..) |*scalar, i| {
......@@ -33843,7 +34042,7 @@ fn intSubWithOverflow(
3384334042 var rhs_buf: Value.ElemValueBuffer = undefined;
3384434043 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
3384534044 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
33846 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType());
34045 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod));
3384734046 overflowed_data[i] = of_math_result.overflow_bit;
3384834047 scalar.* = of_math_result.wrapped_result;
3384934048 }
......@@ -33861,13 +34060,13 @@ fn intSubWithOverflowScalar(
3386134060 rhs: Value,
3386234061 ty: Type,
3386334062) !Value.OverflowArithmeticResult {
33864 const target = sema.mod.getTarget();
33865 const info = ty.intInfo(target);
34063 const mod = sema.mod;
34064 const info = ty.intInfo(mod);
3386634065
3386734066 var lhs_space: Value.BigIntSpace = undefined;
3386834067 var rhs_space: Value.BigIntSpace = undefined;
33869 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema);
33870 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema);
34068 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
34069 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
3387134070 const limbs = try sema.arena.alloc(
3387234071 std.math.big.Limb,
3387334072 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -33889,13 +34088,14 @@ fn floatToInt(
3388934088 float_ty: Type,
3389034089 int_ty: Type,
3389134090) CompileError!Value {
33892 if (float_ty.zigTypeTag() == .Vector) {
34091 const mod = sema.mod;
34092 if (float_ty.zigTypeTag(mod) == .Vector) {
3389334093 const elem_ty = float_ty.childType();
3389434094 const result_data = try sema.arena.alloc(Value, float_ty.vectorLen());
3389534095 for (result_data, 0..) |*scalar, i| {
3389634096 var buf: Value.ElemValueBuffer = undefined;
3389734097 const elem_val = val.elemValueBuffer(sema.mod, i, &buf);
33898 scalar.* = try sema.floatToIntScalar(block, src, elem_val, elem_ty, int_ty.scalarType());
34098 scalar.* = try sema.floatToIntScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod));
3389934099 }
3390034100 return Value.Tag.aggregate.create(sema.arena, result_data);
3390134101 }
......@@ -33976,7 +34176,8 @@ fn intFitsInType(
3397634176 ty: Type,
3397734177 vector_index: ?*usize,
3397834178) CompileError!bool {
33979 const target = sema.mod.getTarget();
34179 const mod = sema.mod;
34180 const target = mod.getTarget();
3398034181 switch (val.tag()) {
3398134182 .zero,
3398234183 .undef,
......@@ -33985,9 +34186,9 @@ fn intFitsInType(
3398534186
3398634187 .one,
3398734188 .bool_true,
33988 => switch (ty.zigTypeTag()) {
34189 => switch (ty.zigTypeTag(mod)) {
3398934190 .Int => {
33990 const info = ty.intInfo(target);
34191 const info = ty.intInfo(mod);
3399134192 return switch (info.signedness) {
3399234193 .signed => info.bits >= 2,
3399334194 .unsigned => info.bits >= 1,
......@@ -33997,9 +34198,9 @@ fn intFitsInType(
3399734198 else => unreachable,
3399834199 },
3399934200
34000 .lazy_align => switch (ty.zigTypeTag()) {
34201 .lazy_align => switch (ty.zigTypeTag(mod)) {
3400134202 .Int => {
34002 const info = ty.intInfo(target);
34203 const info = ty.intInfo(mod);
3400334204 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
3400434205 // If it is u16 or bigger we know the alignment fits without resolving it.
3400534206 if (info.bits >= max_needed_bits) return true;
......@@ -34011,9 +34212,9 @@ fn intFitsInType(
3401134212 .ComptimeInt => return true,
3401234213 else => unreachable,
3401334214 },
34014 .lazy_size => switch (ty.zigTypeTag()) {
34215 .lazy_size => switch (ty.zigTypeTag(mod)) {
3401534216 .Int => {
34016 const info = ty.intInfo(target);
34217 const info = ty.intInfo(mod);
3401734218 const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);
3401834219 // If it is u64 or bigger we know the size fits without resolving it.
3401934220 if (info.bits >= max_needed_bits) return true;
......@@ -34026,41 +34227,41 @@ fn intFitsInType(
3402634227 else => unreachable,
3402734228 },
3402834229
34029 .int_u64 => switch (ty.zigTypeTag()) {
34230 .int_u64 => switch (ty.zigTypeTag(mod)) {
3403034231 .Int => {
3403134232 const x = val.castTag(.int_u64).?.data;
3403234233 if (x == 0) return true;
34033 const info = ty.intInfo(target);
34234 const info = ty.intInfo(mod);
3403434235 const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
3403534236 return info.bits >= needed_bits;
3403634237 },
3403734238 .ComptimeInt => return true,
3403834239 else => unreachable,
3403934240 },
34040 .int_i64 => switch (ty.zigTypeTag()) {
34241 .int_i64 => switch (ty.zigTypeTag(mod)) {
3404134242 .Int => {
3404234243 const x = val.castTag(.int_i64).?.data;
3404334244 if (x == 0) return true;
34044 const info = ty.intInfo(target);
34245 const info = ty.intInfo(mod);
3404534246 if (info.signedness == .unsigned and x < 0)
3404634247 return false;
3404734248 var buffer: Value.BigIntSpace = undefined;
34048 return (try val.toBigIntAdvanced(&buffer, target, sema)).fitsInTwosComp(info.signedness, info.bits);
34249 return (try val.toBigIntAdvanced(&buffer, mod, sema)).fitsInTwosComp(info.signedness, info.bits);
3404934250 },
3405034251 .ComptimeInt => return true,
3405134252 else => unreachable,
3405234253 },
34053 .int_big_positive => switch (ty.zigTypeTag()) {
34254 .int_big_positive => switch (ty.zigTypeTag(mod)) {
3405434255 .Int => {
34055 const info = ty.intInfo(target);
34256 const info = ty.intInfo(mod);
3405634257 return val.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
3405734258 },
3405834259 .ComptimeInt => return true,
3405934260 else => unreachable,
3406034261 },
34061 .int_big_negative => switch (ty.zigTypeTag()) {
34262 .int_big_negative => switch (ty.zigTypeTag(mod)) {
3406234263 .Int => {
34063 const info = ty.intInfo(target);
34264 const info = ty.intInfo(mod);
3406434265 return val.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
3406534266 },
3406634267 .ComptimeInt => return true,
......@@ -34068,7 +34269,7 @@ fn intFitsInType(
3406834269 },
3406934270
3407034271 .the_only_possible_value => {
34071 assert(ty.intInfo(target).bits == 0);
34272 assert(ty.intInfo(mod).bits == 0);
3407234273 return true;
3407334274 },
3407434275
......@@ -34077,9 +34278,9 @@ fn intFitsInType(
3407734278 .decl_ref,
3407834279 .function,
3407934280 .variable,
34080 => switch (ty.zigTypeTag()) {
34281 => switch (ty.zigTypeTag(mod)) {
3408134282 .Int => {
34082 const info = ty.intInfo(target);
34283 const info = ty.intInfo(mod);
3408334284 const ptr_bits = target.ptrBitWidth();
3408434285 return switch (info.signedness) {
3408534286 .signed => info.bits > ptr_bits,
......@@ -34091,9 +34292,9 @@ fn intFitsInType(
3409134292 },
3409234293
3409334294 .aggregate => {
34094 assert(ty.zigTypeTag() == .Vector);
34295 assert(ty.zigTypeTag(mod) == .Vector);
3409534296 for (val.castTag(.aggregate).?.data, 0..) |elem, i| {
34096 if (!(try sema.intFitsInType(elem, ty.scalarType(), null))) {
34297 if (!(try sema.intFitsInType(elem, ty.scalarType(mod), null))) {
3409734298 if (vector_index) |some| some.* = i;
3409834299 return false;
3409934300 }
......@@ -34122,11 +34323,8 @@ fn intInRange(
3412234323}
3412334324
3412434325/// Asserts the type is an enum.
34125fn enumHasInt(
34126 sema: *Sema,
34127 ty: Type,
34128 int: Value,
34129) CompileError!bool {
34326fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {
34327 const mod = sema.mod;
3413034328 switch (ty.tag()) {
3413134329 .enum_nonexhaustive => unreachable,
3413234330 .enum_full => {
......@@ -34157,11 +34355,7 @@ fn enumHasInt(
3415734355 const enum_simple = ty.castTag(.enum_simple).?.data;
3415834356 const fields_len = enum_simple.fields.count();
3415934357 const bits = std.math.log2_int_ceil(usize, fields_len);
34160 var buffer: Type.Payload.Bits = .{
34161 .base = .{ .tag = .int_unsigned },
34162 .data = bits,
34163 };
34164 const tag_ty = Type.initPayload(&buffer.base);
34358 const tag_ty = try mod.intType(.unsigned, bits);
3416534359 return sema.intInRange(tag_ty, int, fields_len);
3416634360 },
3416734361 .atomic_order,
......@@ -34186,7 +34380,8 @@ fn intAddWithOverflow(
3418634380 rhs: Value,
3418734381 ty: Type,
3418834382) !Value.OverflowArithmeticResult {
34189 if (ty.zigTypeTag() == .Vector) {
34383 const mod = sema.mod;
34384 if (ty.zigTypeTag(mod) == .Vector) {
3419034385 const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen());
3419134386 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
3419234387 for (result_data, 0..) |*scalar, i| {
......@@ -34194,7 +34389,7 @@ fn intAddWithOverflow(
3419434389 var rhs_buf: Value.ElemValueBuffer = undefined;
3419534390 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
3419634391 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
34197 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType());
34392 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod));
3419834393 overflowed_data[i] = of_math_result.overflow_bit;
3419934394 scalar.* = of_math_result.wrapped_result;
3420034395 }
......@@ -34212,13 +34407,13 @@ fn intAddWithOverflowScalar(
3421234407 rhs: Value,
3421334408 ty: Type,
3421434409) !Value.OverflowArithmeticResult {
34215 const target = sema.mod.getTarget();
34216 const info = ty.intInfo(target);
34410 const mod = sema.mod;
34411 const info = ty.intInfo(mod);
3421734412
3421834413 var lhs_space: Value.BigIntSpace = undefined;
3421934414 var rhs_space: Value.BigIntSpace = undefined;
34220 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema);
34221 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema);
34415 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
34416 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
3422234417 const limbs = try sema.arena.alloc(
3422334418 std.math.big.Limb,
3422434419 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -34243,14 +34438,15 @@ fn compareAll(
3424334438 rhs: Value,
3424434439 ty: Type,
3424534440) CompileError!bool {
34246 if (ty.zigTypeTag() == .Vector) {
34441 const mod = sema.mod;
34442 if (ty.zigTypeTag(mod) == .Vector) {
3424734443 var i: usize = 0;
3424834444 while (i < ty.vectorLen()) : (i += 1) {
3424934445 var lhs_buf: Value.ElemValueBuffer = undefined;
3425034446 var rhs_buf: Value.ElemValueBuffer = undefined;
3425134447 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
3425234448 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
34253 if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType()))) {
34449 if (!(try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)))) {
3425434450 return false;
3425534451 }
3425634452 }
......@@ -34270,7 +34466,7 @@ fn compareScalar(
3427034466 switch (op) {
3427134467 .eq => return sema.valuesEqual(lhs, rhs, ty),
3427234468 .neq => return !(try sema.valuesEqual(lhs, rhs, ty)),
34273 else => return Value.compareHeteroAdvanced(lhs, op, rhs, sema.mod.getTarget(), sema),
34469 else => return Value.compareHeteroAdvanced(lhs, op, rhs, sema.mod, sema),
3427434470 }
3427534471}
3427634472
......@@ -34291,14 +34487,15 @@ fn compareVector(
3429134487 rhs: Value,
3429234488 ty: Type,
3429334489) !Value {
34294 assert(ty.zigTypeTag() == .Vector);
34490 const mod = sema.mod;
34491 assert(ty.zigTypeTag(mod) == .Vector);
3429534492 const result_data = try sema.arena.alloc(Value, ty.vectorLen());
3429634493 for (result_data, 0..) |*scalar, i| {
3429734494 var lhs_buf: Value.ElemValueBuffer = undefined;
3429834495 var rhs_buf: Value.ElemValueBuffer = undefined;
3429934496 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
3430034497 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
34301 const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType());
34498 const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod));
3430234499 scalar.* = Value.makeBool(res_bool);
3430334500 }
3430434501 return Value.Tag.aggregate.create(sema.arena, result_data);
......@@ -34312,10 +34509,10 @@ fn compareVector(
3431234509/// Handles const-ness and address spaces in particular.
3431334510/// This code is duplicated in `analyzePtrArithmetic`.
3431434511fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
34512 const mod = sema.mod;
3431534513 const ptr_info = ptr_ty.ptrInfo().data;
34316 const elem_ty = ptr_ty.elemType2();
34514 const elem_ty = ptr_ty.elemType2(mod);
3431734515 const allow_zero = ptr_info.@"allowzero" and (offset orelse 0) == 0;
34318 const target = sema.mod.getTarget();
3431934516 const parent_ty = ptr_ty.childType();
3432034517
3432134518 const VI = Type.Payload.Pointer.Data.VectorIndex;
......@@ -34325,14 +34522,14 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3432534522 alignment: u32 = 0,
3432634523 vector_index: VI = .none,
3432734524 } = if (parent_ty.tag() == .vector and ptr_info.size == .One) blk: {
34328 const elem_bits = elem_ty.bitSize(target);
34525 const elem_bits = elem_ty.bitSize(mod);
3432934526 if (elem_bits == 0) break :blk .{};
3433034527 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
3433134528 if (!is_packed) break :blk .{};
3433234529
3433334530 break :blk .{
3433434531 .host_size = @intCast(u16, parent_ty.arrayLen()),
34335 .alignment = @intCast(u16, parent_ty.abiAlignment(target)),
34532 .alignment = @intCast(u16, parent_ty.abiAlignment(mod)),
3433634533 .vector_index = if (offset) |some| @intToEnum(VI, some) else .runtime,
3433734534 };
3433834535 } else .{};
src/TypedValue.zig+15-27
......@@ -71,7 +71,6 @@ pub fn print(
7171 level: u8,
7272 mod: *Module,
7373) @TypeOf(writer).Error!void {
74 const target = mod.getTarget();
7574 var val = tv.val;
7675 var ty = tv.ty;
7776 if (val.isVariable(mod))
......@@ -117,10 +116,6 @@ pub fn print(
117116 .noreturn_type => return writer.writeAll("noreturn"),
118117 .null_type => return writer.writeAll("@Type(.Null)"),
119118 .undefined_type => return writer.writeAll("@Type(.Undefined)"),
120 .fn_noreturn_no_args_type => return writer.writeAll("fn() noreturn"),
121 .fn_void_no_args_type => return writer.writeAll("fn() void"),
122 .fn_naked_noreturn_no_args_type => return writer.writeAll("fn() callconv(.Naked) noreturn"),
123 .fn_ccc_void_no_args_type => return writer.writeAll("fn() callconv(.C) void"),
124119 .single_const_pointer_to_comptime_int_type => return writer.writeAll("*const comptime_int"),
125120 .anyframe_type => return writer.writeAll("anyframe"),
126121 .const_slice_u8_type => return writer.writeAll("[]const u8"),
......@@ -147,7 +142,7 @@ pub fn print(
147142 if (level == 0) {
148143 return writer.writeAll(".{ ... }");
149144 }
150 if (ty.zigTypeTag() == .Struct) {
145 if (ty.zigTypeTag(mod) == .Struct) {
151146 try writer.writeAll(".{");
152147 const max_len = std.math.min(ty.structFieldCount(), max_aggregate_items);
153148
......@@ -160,7 +155,7 @@ pub fn print(
160155 }
161156 try print(.{
162157 .ty = ty.structFieldType(i),
163 .val = val.fieldValue(ty, i),
158 .val = val.fieldValue(ty, mod, i),
164159 }, writer, level - 1, mod);
165160 }
166161 if (ty.structFieldCount() > max_aggregate_items) {
......@@ -168,7 +163,7 @@ pub fn print(
168163 }
169164 return writer.writeAll("}");
170165 } else {
171 const elem_ty = ty.elemType2();
166 const elem_ty = ty.elemType2(mod);
172167 const len = ty.arrayLen();
173168
174169 if (elem_ty.eql(Type.u8, mod)) str: {
......@@ -177,9 +172,9 @@ pub fn print(
177172
178173 var i: u32 = 0;
179174 while (i < max_len) : (i += 1) {
180 const elem = val.fieldValue(ty, i);
175 const elem = val.fieldValue(ty, mod, i);
181176 if (elem.isUndef()) break :str;
182 buf[i] = std.math.cast(u8, elem.toUnsignedInt(target)) orelse break :str;
177 buf[i] = std.math.cast(u8, elem.toUnsignedInt(mod)) orelse break :str;
183178 }
184179
185180 const truncated = if (len > max_string_len) " (truncated)" else "";
......@@ -194,7 +189,7 @@ pub fn print(
194189 if (i != 0) try writer.writeAll(", ");
195190 try print(.{
196191 .ty = elem_ty,
197 .val = val.fieldValue(ty, i),
192 .val = val.fieldValue(ty, mod, i),
198193 }, writer, level - 1, mod);
199194 }
200195 if (len > max_aggregate_items) {
......@@ -232,25 +227,18 @@ pub fn print(
232227 .bool_true => return writer.writeAll("true"),
233228 .bool_false => return writer.writeAll("false"),
234229 .ty => return val.castTag(.ty).?.data.print(writer, mod),
235 .int_type => {
236 const int_type = val.castTag(.int_type).?.data;
237 return writer.print("{s}{d}", .{
238 if (int_type.signed) "s" else "u",
239 int_type.bits,
240 });
241 },
242230 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", .{}, writer),
243231 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", .{}, writer),
244232 .int_big_positive => return writer.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
245233 .int_big_negative => return writer.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),
246234 .lazy_align => {
247235 const sub_ty = val.castTag(.lazy_align).?.data;
248 const x = sub_ty.abiAlignment(target);
236 const x = sub_ty.abiAlignment(mod);
249237 return writer.print("{d}", .{x});
250238 },
251239 .lazy_size => {
252240 const sub_ty = val.castTag(.lazy_size).?.data;
253 const x = sub_ty.abiSize(target);
241 const x = sub_ty.abiSize(mod);
254242 return writer.print("{d}", .{x});
255243 },
256244 .function => return writer.print("(function '{s}')", .{
......@@ -315,7 +303,7 @@ pub fn print(
315303 }, writer, level - 1, mod);
316304 }
317305
318 if (field_ptr.container_ty.zigTypeTag() == .Struct) {
306 if (field_ptr.container_ty.zigTypeTag(mod) == .Struct) {
319307 switch (field_ptr.container_ty.tag()) {
320308 .tuple => return writer.print(".@\"{d}\"", .{field_ptr.field_index}),
321309 else => {
......@@ -323,7 +311,7 @@ pub fn print(
323311 return writer.print(".{s}", .{field_name});
324312 },
325313 }
326 } else if (field_ptr.container_ty.zigTypeTag() == .Union) {
314 } else if (field_ptr.container_ty.zigTypeTag(mod) == .Union) {
327315 const field_name = field_ptr.container_ty.unionFields().keys()[field_ptr.field_index];
328316 return writer.print(".{s}", .{field_name});
329317 } else if (field_ptr.container_ty.isSlice()) {
......@@ -352,7 +340,7 @@ pub fn print(
352340 var i: u32 = 0;
353341 try writer.writeAll(".{ ");
354342 const elem_tv = TypedValue{
355 .ty = ty.elemType2(),
343 .ty = ty.elemType2(mod),
356344 .val = val.castTag(.repeated).?.data,
357345 };
358346 const len = ty.arrayLen();
......@@ -372,7 +360,7 @@ pub fn print(
372360 }
373361 try writer.writeAll(".{ ");
374362 try print(.{
375 .ty = ty.elemType2(),
363 .ty = ty.elemType2(mod),
376364 .val = ty.sentinel().?,
377365 }, writer, level - 1, mod);
378366 return writer.writeAll(" }");
......@@ -382,8 +370,8 @@ pub fn print(
382370 return writer.writeAll(".{ ... }");
383371 }
384372 const payload = val.castTag(.slice).?.data;
385 const elem_ty = ty.elemType2();
386 const len = payload.len.toUnsignedInt(target);
373 const elem_ty = ty.elemType2(mod);
374 const len = payload.len.toUnsignedInt(mod);
387375
388376 if (elem_ty.eql(Type.u8, mod)) str: {
389377 const max_len = @intCast(usize, std.math.min(len, max_string_len));
......@@ -394,7 +382,7 @@ pub fn print(
394382 var elem_buf: Value.ElemValueBuffer = undefined;
395383 const elem_val = payload.ptr.elemValueBuffer(mod, i, &elem_buf);
396384 if (elem_val.isUndef()) break :str;
397 buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(target)) orelse break :str;
385 buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(mod)) orelse break :str;
398386 }
399387
400388 // TODO would be nice if this had a bit of unicode awareness.
src/Zir.zig+83-435
......@@ -19,6 +19,7 @@ const BigIntConst = std.math.big.int.Const;
1919const BigIntMutable = std.math.big.int.Mutable;
2020const Ast = std.zig.Ast;
2121
22const InternPool = @import("InternPool.zig");
2223const Zir = @This();
2324const Type = @import("type.zig").Type;
2425const Value = @import("value.zig").Value;
......@@ -2041,448 +2042,95 @@ pub const Inst = struct {
20412042 /// The position of a ZIR instruction within the `Zir` instructions array.
20422043 pub const Index = u32;
20432044
2044 /// A reference to a TypedValue or ZIR instruction.
2045 /// A reference to ZIR instruction, or to an InternPool index, or neither.
20452046 ///
2046 /// If the Ref has a tag in this enum, it refers to a TypedValue.
2047 ///
2048 /// If the value of a Ref does not have a tag, it refers to a ZIR instruction.
2049 ///
2050 /// The first values after the the last tag refer to ZIR instructions which may
2051 /// be derived by subtracting `typed_value_map.len`.
2052 ///
2053 /// When adding a tag to this enum, consider adding a corresponding entry to
2054 /// `primitives` in astgen.
2047 /// If the integer tag value is < InternPool.static_len, then it
2048 /// corresponds to an InternPool index. Otherwise, this refers to a ZIR
2049 /// instruction.
20552050 ///
20562051 /// The tag type is specified so that it is safe to bitcast between `[]u32`
20572052 /// and `[]Ref`.
20582053 pub const Ref = enum(u32) {
2054 u1_type = @enumToInt(InternPool.Index.u1_type),
2055 u8_type = @enumToInt(InternPool.Index.u8_type),
2056 i8_type = @enumToInt(InternPool.Index.i8_type),
2057 u16_type = @enumToInt(InternPool.Index.u16_type),
2058 i16_type = @enumToInt(InternPool.Index.i16_type),
2059 u29_type = @enumToInt(InternPool.Index.u29_type),
2060 u32_type = @enumToInt(InternPool.Index.u32_type),
2061 i32_type = @enumToInt(InternPool.Index.i32_type),
2062 u64_type = @enumToInt(InternPool.Index.u64_type),
2063 i64_type = @enumToInt(InternPool.Index.i64_type),
2064 u80_type = @enumToInt(InternPool.Index.u80_type),
2065 u128_type = @enumToInt(InternPool.Index.u128_type),
2066 i128_type = @enumToInt(InternPool.Index.i128_type),
2067 usize_type = @enumToInt(InternPool.Index.usize_type),
2068 isize_type = @enumToInt(InternPool.Index.isize_type),
2069 c_char_type = @enumToInt(InternPool.Index.c_char_type),
2070 c_short_type = @enumToInt(InternPool.Index.c_short_type),
2071 c_ushort_type = @enumToInt(InternPool.Index.c_ushort_type),
2072 c_int_type = @enumToInt(InternPool.Index.c_int_type),
2073 c_uint_type = @enumToInt(InternPool.Index.c_uint_type),
2074 c_long_type = @enumToInt(InternPool.Index.c_long_type),
2075 c_ulong_type = @enumToInt(InternPool.Index.c_ulong_type),
2076 c_longlong_type = @enumToInt(InternPool.Index.c_longlong_type),
2077 c_ulonglong_type = @enumToInt(InternPool.Index.c_ulonglong_type),
2078 c_longdouble_type = @enumToInt(InternPool.Index.c_longdouble_type),
2079 f16_type = @enumToInt(InternPool.Index.f16_type),
2080 f32_type = @enumToInt(InternPool.Index.f32_type),
2081 f64_type = @enumToInt(InternPool.Index.f64_type),
2082 f80_type = @enumToInt(InternPool.Index.f80_type),
2083 f128_type = @enumToInt(InternPool.Index.f128_type),
2084 anyopaque_type = @enumToInt(InternPool.Index.anyopaque_type),
2085 bool_type = @enumToInt(InternPool.Index.bool_type),
2086 void_type = @enumToInt(InternPool.Index.void_type),
2087 type_type = @enumToInt(InternPool.Index.type_type),
2088 anyerror_type = @enumToInt(InternPool.Index.anyerror_type),
2089 comptime_int_type = @enumToInt(InternPool.Index.comptime_int_type),
2090 comptime_float_type = @enumToInt(InternPool.Index.comptime_float_type),
2091 noreturn_type = @enumToInt(InternPool.Index.noreturn_type),
2092 anyframe_type = @enumToInt(InternPool.Index.anyframe_type),
2093 null_type = @enumToInt(InternPool.Index.null_type),
2094 undefined_type = @enumToInt(InternPool.Index.undefined_type),
2095 enum_literal_type = @enumToInt(InternPool.Index.enum_literal_type),
2096 atomic_order_type = @enumToInt(InternPool.Index.atomic_order_type),
2097 atomic_rmw_op_type = @enumToInt(InternPool.Index.atomic_rmw_op_type),
2098 calling_convention_type = @enumToInt(InternPool.Index.calling_convention_type),
2099 address_space_type = @enumToInt(InternPool.Index.address_space_type),
2100 float_mode_type = @enumToInt(InternPool.Index.float_mode_type),
2101 reduce_op_type = @enumToInt(InternPool.Index.reduce_op_type),
2102 call_modifier_type = @enumToInt(InternPool.Index.call_modifier_type),
2103 prefetch_options_type = @enumToInt(InternPool.Index.prefetch_options_type),
2104 export_options_type = @enumToInt(InternPool.Index.export_options_type),
2105 extern_options_type = @enumToInt(InternPool.Index.extern_options_type),
2106 type_info_type = @enumToInt(InternPool.Index.type_info_type),
2107 manyptr_u8_type = @enumToInt(InternPool.Index.manyptr_u8_type),
2108 manyptr_const_u8_type = @enumToInt(InternPool.Index.manyptr_const_u8_type),
2109 single_const_pointer_to_comptime_int_type = @enumToInt(InternPool.Index.single_const_pointer_to_comptime_int_type),
2110 const_slice_u8_type = @enumToInt(InternPool.Index.const_slice_u8_type),
2111 anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),
2112 generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),
2113 var_args_param_type = @enumToInt(InternPool.Index.var_args_param_type),
2114 empty_struct_type = @enumToInt(InternPool.Index.empty_struct_type),
2115 undef = @enumToInt(InternPool.Index.undef),
2116 zero = @enumToInt(InternPool.Index.zero),
2117 zero_usize = @enumToInt(InternPool.Index.zero_usize),
2118 one = @enumToInt(InternPool.Index.one),
2119 one_usize = @enumToInt(InternPool.Index.one_usize),
2120 calling_convention_c = @enumToInt(InternPool.Index.calling_convention_c),
2121 calling_convention_inline = @enumToInt(InternPool.Index.calling_convention_inline),
2122 void_value = @enumToInt(InternPool.Index.void_value),
2123 unreachable_value = @enumToInt(InternPool.Index.unreachable_value),
2124 null_value = @enumToInt(InternPool.Index.null_value),
2125 bool_true = @enumToInt(InternPool.Index.bool_true),
2126 bool_false = @enumToInt(InternPool.Index.bool_false),
2127 empty_struct = @enumToInt(InternPool.Index.empty_struct),
2128 generic_poison = @enumToInt(InternPool.Index.generic_poison),
2129
20592130 /// This Ref does not correspond to any ZIR instruction or constant
20602131 /// value and may instead be used as a sentinel to indicate null.
2061 none,
2062
2063 u1_type,
2064 u8_type,
2065 i8_type,
2066 u16_type,
2067 i16_type,
2068 u29_type,
2069 u32_type,
2070 i32_type,
2071 u64_type,
2072 i64_type,
2073 u128_type,
2074 i128_type,
2075 usize_type,
2076 isize_type,
2077 c_char_type,
2078 c_short_type,
2079 c_ushort_type,
2080 c_int_type,
2081 c_uint_type,
2082 c_long_type,
2083 c_ulong_type,
2084 c_longlong_type,
2085 c_ulonglong_type,
2086 c_longdouble_type,
2087 f16_type,
2088 f32_type,
2089 f64_type,
2090 f80_type,
2091 f128_type,
2092 anyopaque_type,
2093 bool_type,
2094 void_type,
2095 type_type,
2096 anyerror_type,
2097 comptime_int_type,
2098 comptime_float_type,
2099 noreturn_type,
2100 anyframe_type,
2101 null_type,
2102 undefined_type,
2103 enum_literal_type,
2104 atomic_order_type,
2105 atomic_rmw_op_type,
2106 calling_convention_type,
2107 address_space_type,
2108 float_mode_type,
2109 reduce_op_type,
2110 modifier_type,
2111 prefetch_options_type,
2112 export_options_type,
2113 extern_options_type,
2114 type_info_type,
2115 manyptr_u8_type,
2116 manyptr_const_u8_type,
2117 fn_noreturn_no_args_type,
2118 fn_void_no_args_type,
2119 fn_naked_noreturn_no_args_type,
2120 fn_ccc_void_no_args_type,
2121 single_const_pointer_to_comptime_int_type,
2122 const_slice_u8_type,
2123 anyerror_void_error_union_type,
2124 generic_poison_type,
2125
2126 /// `undefined` (untyped)
2127 undef,
2128 /// `0` (comptime_int)
2129 zero,
2130 /// `1` (comptime_int)
2131 one,
2132 /// `{}`
2133 void_value,
2134 /// `unreachable` (noreturn type)
2135 unreachable_value,
2136 /// `null` (untyped)
2137 null_value,
2138 /// `true`
2139 bool_true,
2140 /// `false`
2141 bool_false,
2142 /// `.{}` (untyped)
2143 empty_struct,
2144 /// `0` (usize)
2145 zero_usize,
2146 /// `1` (usize)
2147 one_usize,
2148 /// `std.builtin.CallingConvention.C`
2149 calling_convention_c,
2150 /// `std.builtin.CallingConvention.Inline`
2151 calling_convention_inline,
2152 /// Used for generic parameters where the type and value
2153 /// is not known until generic function instantiation.
2154 generic_poison,
2155 /// This is a special type for variadic parameters of a function call.
2156 /// Casts to it will validate that the type can be passed to a c
2157 /// calling convention function.
2158 var_args_param,
2159
2132 none = std.math.maxInt(u32),
21602133 _,
2161
2162 pub const typed_value_map = std.enums.directEnumArray(Ref, TypedValue, 0, .{
2163 .none = undefined,
2164
2165 .u1_type = .{
2166 .ty = Type.initTag(.type),
2167 .val = Value.initTag(.u1_type),
2168 },
2169 .u8_type = .{
2170 .ty = Type.initTag(.type),
2171 .val = Value.initTag(.u8_type),
2172 },
2173 .i8_type = .{
2174 .ty = Type.initTag(.type),
2175 .val = Value.initTag(.i8_type),
2176 },
2177 .u16_type = .{
2178 .ty = Type.initTag(.type),
2179 .val = Value.initTag(.u16_type),
2180 },
2181 .i16_type = .{
2182 .ty = Type.initTag(.type),
2183 .val = Value.initTag(.i16_type),
2184 },
2185 .u29_type = .{
2186 .ty = Type.initTag(.type),
2187 .val = Value.initTag(.u29_type),
2188 },
2189 .u32_type = .{
2190 .ty = Type.initTag(.type),
2191 .val = Value.initTag(.u32_type),
2192 },
2193 .i32_type = .{
2194 .ty = Type.initTag(.type),
2195 .val = Value.initTag(.i32_type),
2196 },
2197 .u64_type = .{
2198 .ty = Type.initTag(.type),
2199 .val = Value.initTag(.u64_type),
2200 },
2201 .i64_type = .{
2202 .ty = Type.initTag(.type),
2203 .val = Value.initTag(.i64_type),
2204 },
2205 .u128_type = .{
2206 .ty = Type.initTag(.type),
2207 .val = Value.initTag(.u128_type),
2208 },
2209 .i128_type = .{
2210 .ty = Type.initTag(.type),
2211 .val = Value.initTag(.i128_type),
2212 },
2213 .usize_type = .{
2214 .ty = Type.initTag(.type),
2215 .val = Value.initTag(.usize_type),
2216 },
2217 .isize_type = .{
2218 .ty = Type.initTag(.type),
2219 .val = Value.initTag(.isize_type),
2220 },
2221 .c_char_type = .{
2222 .ty = Type.initTag(.type),
2223 .val = Value.initTag(.c_char_type),
2224 },
2225 .c_short_type = .{
2226 .ty = Type.initTag(.type),
2227 .val = Value.initTag(.c_short_type),
2228 },
2229 .c_ushort_type = .{
2230 .ty = Type.initTag(.type),
2231 .val = Value.initTag(.c_ushort_type),
2232 },
2233 .c_int_type = .{
2234 .ty = Type.initTag(.type),
2235 .val = Value.initTag(.c_int_type),
2236 },
2237 .c_uint_type = .{
2238 .ty = Type.initTag(.type),
2239 .val = Value.initTag(.c_uint_type),
2240 },
2241 .c_long_type = .{
2242 .ty = Type.initTag(.type),
2243 .val = Value.initTag(.c_long_type),
2244 },
2245 .c_ulong_type = .{
2246 .ty = Type.initTag(.type),
2247 .val = Value.initTag(.c_ulong_type),
2248 },
2249 .c_longlong_type = .{
2250 .ty = Type.initTag(.type),
2251 .val = Value.initTag(.c_longlong_type),
2252 },
2253 .c_ulonglong_type = .{
2254 .ty = Type.initTag(.type),
2255 .val = Value.initTag(.c_ulonglong_type),
2256 },
2257 .c_longdouble_type = .{
2258 .ty = Type.initTag(.type),
2259 .val = Value.initTag(.c_longdouble_type),
2260 },
2261 .f16_type = .{
2262 .ty = Type.initTag(.type),
2263 .val = Value.initTag(.f16_type),
2264 },
2265 .f32_type = .{
2266 .ty = Type.initTag(.type),
2267 .val = Value.initTag(.f32_type),
2268 },
2269 .f64_type = .{
2270 .ty = Type.initTag(.type),
2271 .val = Value.initTag(.f64_type),
2272 },
2273 .f80_type = .{
2274 .ty = Type.initTag(.type),
2275 .val = Value.initTag(.f80_type),
2276 },
2277 .f128_type = .{
2278 .ty = Type.initTag(.type),
2279 .val = Value.initTag(.f128_type),
2280 },
2281 .anyopaque_type = .{
2282 .ty = Type.initTag(.type),
2283 .val = Value.initTag(.anyopaque_type),
2284 },
2285 .bool_type = .{
2286 .ty = Type.initTag(.type),
2287 .val = Value.initTag(.bool_type),
2288 },
2289 .void_type = .{
2290 .ty = Type.initTag(.type),
2291 .val = Value.initTag(.void_type),
2292 },
2293 .type_type = .{
2294 .ty = Type.initTag(.type),
2295 .val = Value.initTag(.type_type),
2296 },
2297 .anyerror_type = .{
2298 .ty = Type.initTag(.type),
2299 .val = Value.initTag(.anyerror_type),
2300 },
2301 .comptime_int_type = .{
2302 .ty = Type.initTag(.type),
2303 .val = Value.initTag(.comptime_int_type),
2304 },
2305 .comptime_float_type = .{
2306 .ty = Type.initTag(.type),
2307 .val = Value.initTag(.comptime_float_type),
2308 },
2309 .noreturn_type = .{
2310 .ty = Type.initTag(.type),
2311 .val = Value.initTag(.noreturn_type),
2312 },
2313 .anyframe_type = .{
2314 .ty = Type.initTag(.type),
2315 .val = Value.initTag(.anyframe_type),
2316 },
2317 .null_type = .{
2318 .ty = Type.initTag(.type),
2319 .val = Value.initTag(.null_type),
2320 },
2321 .undefined_type = .{
2322 .ty = Type.initTag(.type),
2323 .val = Value.initTag(.undefined_type),
2324 },
2325 .fn_noreturn_no_args_type = .{
2326 .ty = Type.initTag(.type),
2327 .val = Value.initTag(.fn_noreturn_no_args_type),
2328 },
2329 .fn_void_no_args_type = .{
2330 .ty = Type.initTag(.type),
2331 .val = Value.initTag(.fn_void_no_args_type),
2332 },
2333 .fn_naked_noreturn_no_args_type = .{
2334 .ty = Type.initTag(.type),
2335 .val = Value.initTag(.fn_naked_noreturn_no_args_type),
2336 },
2337 .fn_ccc_void_no_args_type = .{
2338 .ty = Type.initTag(.type),
2339 .val = Value.initTag(.fn_ccc_void_no_args_type),
2340 },
2341 .single_const_pointer_to_comptime_int_type = .{
2342 .ty = Type.initTag(.type),
2343 .val = Value.initTag(.single_const_pointer_to_comptime_int_type),
2344 },
2345 .const_slice_u8_type = .{
2346 .ty = Type.initTag(.type),
2347 .val = Value.initTag(.const_slice_u8_type),
2348 },
2349 .anyerror_void_error_union_type = .{
2350 .ty = Type.initTag(.type),
2351 .val = Value.initTag(.anyerror_void_error_union_type),
2352 },
2353 .generic_poison_type = .{
2354 .ty = Type.initTag(.type),
2355 .val = Value.initTag(.generic_poison_type),
2356 },
2357 .enum_literal_type = .{
2358 .ty = Type.initTag(.type),
2359 .val = Value.initTag(.enum_literal_type),
2360 },
2361 .manyptr_u8_type = .{
2362 .ty = Type.initTag(.type),
2363 .val = Value.initTag(.manyptr_u8_type),
2364 },
2365 .manyptr_const_u8_type = .{
2366 .ty = Type.initTag(.type),
2367 .val = Value.initTag(.manyptr_const_u8_type),
2368 },
2369 .atomic_order_type = .{
2370 .ty = Type.initTag(.type),
2371 .val = Value.initTag(.atomic_order_type),
2372 },
2373 .atomic_rmw_op_type = .{
2374 .ty = Type.initTag(.type),
2375 .val = Value.initTag(.atomic_rmw_op_type),
2376 },
2377 .calling_convention_type = .{
2378 .ty = Type.initTag(.type),
2379 .val = Value.initTag(.calling_convention_type),
2380 },
2381 .address_space_type = .{
2382 .ty = Type.initTag(.type),
2383 .val = Value.initTag(.address_space_type),
2384 },
2385 .float_mode_type = .{
2386 .ty = Type.initTag(.type),
2387 .val = Value.initTag(.float_mode_type),
2388 },
2389 .reduce_op_type = .{
2390 .ty = Type.initTag(.type),
2391 .val = Value.initTag(.reduce_op_type),
2392 },
2393 .modifier_type = .{
2394 .ty = Type.initTag(.type),
2395 .val = Value.initTag(.modifier_type),
2396 },
2397 .prefetch_options_type = .{
2398 .ty = Type.initTag(.type),
2399 .val = Value.initTag(.prefetch_options_type),
2400 },
2401 .export_options_type = .{
2402 .ty = Type.initTag(.type),
2403 .val = Value.initTag(.export_options_type),
2404 },
2405 .extern_options_type = .{
2406 .ty = Type.initTag(.type),
2407 .val = Value.initTag(.extern_options_type),
2408 },
2409 .type_info_type = .{
2410 .ty = Type.initTag(.type),
2411 .val = Value.initTag(.type_info_type),
2412 },
2413
2414 .undef = .{
2415 .ty = Type.initTag(.undefined),
2416 .val = Value.initTag(.undef),
2417 },
2418 .zero = .{
2419 .ty = Type.initTag(.comptime_int),
2420 .val = Value.initTag(.zero),
2421 },
2422 .zero_usize = .{
2423 .ty = Type.initTag(.usize),
2424 .val = Value.initTag(.zero),
2425 },
2426 .one = .{
2427 .ty = Type.initTag(.comptime_int),
2428 .val = Value.initTag(.one),
2429 },
2430 .one_usize = .{
2431 .ty = Type.initTag(.usize),
2432 .val = Value.initTag(.one),
2433 },
2434 .void_value = .{
2435 .ty = Type.initTag(.void),
2436 .val = Value.initTag(.void_value),
2437 },
2438 .unreachable_value = .{
2439 .ty = Type.initTag(.noreturn),
2440 .val = Value.initTag(.unreachable_value),
2441 },
2442 .null_value = .{
2443 .ty = Type.initTag(.null),
2444 .val = Value.initTag(.null_value),
2445 },
2446 .bool_true = .{
2447 .ty = Type.initTag(.bool),
2448 .val = Value.initTag(.bool_true),
2449 },
2450 .bool_false = .{
2451 .ty = Type.initTag(.bool),
2452 .val = Value.initTag(.bool_false),
2453 },
2454 .empty_struct = .{
2455 .ty = Type.initTag(.empty_struct_literal),
2456 .val = Value.initTag(.empty_struct_value),
2457 },
2458 .calling_convention_c = .{
2459 .ty = Type.initTag(.calling_convention),
2460 .val = .{ .ptr_otherwise = &calling_convention_c_payload.base },
2461 },
2462 .calling_convention_inline = .{
2463 .ty = Type.initTag(.calling_convention),
2464 .val = .{ .ptr_otherwise = &calling_convention_inline_payload.base },
2465 },
2466 .generic_poison = .{
2467 .ty = Type.initTag(.generic_poison),
2468 .val = Value.initTag(.generic_poison),
2469 },
2470 .var_args_param = undefined,
2471 });
2472 };
2473
2474 /// We would like this to be const but `Value` wants a mutable pointer for
2475 /// its payload field. Nothing should mutate this though.
2476 var calling_convention_c_payload: Value.Payload.U32 = .{
2477 .base = .{ .tag = .enum_field_index },
2478 .data = @enumToInt(std.builtin.CallingConvention.C),
2479 };
2480
2481 /// We would like this to be const but `Value` wants a mutable pointer for
2482 /// its payload field. Nothing should mutate this though.
2483 var calling_convention_inline_payload: Value.Payload.U32 = .{
2484 .base = .{ .tag = .enum_field_index },
2485 .data = @enumToInt(std.builtin.CallingConvention.Inline),
24862134 };
24872135
24882136 /// All instructions have an 8-byte payload, which is contained within
......@@ -4163,7 +3811,7 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
41633811 };
41643812}
41653813
4166const ref_start_index: u32 = Inst.Ref.typed_value_map.len;
3814const ref_start_index: u32 = InternPool.static_len;
41673815
41683816pub fn indexToRef(inst: Inst.Index) Inst.Ref {
41693817 return @intToEnum(Inst.Ref, ref_start_index + inst);
src/arch/aarch64/CodeGen.zig+191-160
......@@ -471,6 +471,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
471471}
472472
473473fn gen(self: *Self) !void {
474 const mod = self.bin_file.options.module.?;
474475 const cc = self.fn_type.fnCallingConvention();
475476 if (cc != .Naked) {
476477 // stp fp, lr, [sp, #-16]!
......@@ -522,8 +523,8 @@ fn gen(self: *Self) !void {
522523
523524 const ty = self.air.typeOfIndex(inst);
524525
525 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
526 const abi_align = ty.abiAlignment(self.target.*);
526 const abi_size = @intCast(u32, ty.abiSize(mod));
527 const abi_align = ty.abiAlignment(mod);
527528 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
528529 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
529530
......@@ -951,8 +952,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
951952 tomb_bits >>= 1;
952953 if (!dies) continue;
953954 const op_int = @enumToInt(op);
954 if (op_int < Air.Inst.Ref.typed_value_map.len) continue;
955 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);
955 if (op_int < Air.ref_start_index) continue;
956 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
956957 self.processDeath(op_index);
957958 }
958959 const is_used = @truncate(u1, tomb_bits) == 0;
......@@ -1026,31 +1027,31 @@ fn allocMem(
10261027
10271028/// Use a pointer instruction as the basis for allocating stack memory.
10281029fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1030 const mod = self.bin_file.options.module.?;
10291031 const elem_ty = self.air.typeOfIndex(inst).elemType();
10301032
1031 if (!elem_ty.hasRuntimeBits()) {
1033 if (!elem_ty.hasRuntimeBits(mod)) {
10321034 // return the stack offset 0. Stack offset 0 will be where all
10331035 // zero-sized stack allocations live as non-zero-sized
10341036 // allocations will always have an offset > 0.
10351037 return @as(u32, 0);
10361038 }
10371039
1038 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
1039 const mod = self.bin_file.options.module.?;
1040 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
10401041 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
10411042 };
10421043 // TODO swap this for inst.ty.ptrAlign
1043 const abi_align = elem_ty.abiAlignment(self.target.*);
1044 const abi_align = elem_ty.abiAlignment(mod);
10441045
10451046 return self.allocMem(abi_size, abi_align, inst);
10461047}
10471048
10481049fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {
1049 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
1050 const mod = self.bin_file.options.module.?;
1050 const mod = self.bin_file.options.module.?;
1051 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
10511052 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
10521053 };
1053 const abi_align = elem_ty.abiAlignment(self.target.*);
1054 const abi_align = elem_ty.abiAlignment(mod);
10541055
10551056 if (reg_ok) {
10561057 // Make sure the type can fit in a register before we try to allocate one.
......@@ -1177,13 +1178,14 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
11771178 if (self.liveness.isUnused(inst))
11781179 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
11791180
1181 const mod = self.bin_file.options.module.?;
11801182 const operand = ty_op.operand;
11811183 const operand_mcv = try self.resolveInst(operand);
11821184 const operand_ty = self.air.typeOf(operand);
1183 const operand_info = operand_ty.intInfo(self.target.*);
1185 const operand_info = operand_ty.intInfo(mod);
11841186
11851187 const dest_ty = self.air.typeOfIndex(inst);
1186 const dest_info = dest_ty.intInfo(self.target.*);
1188 const dest_info = dest_ty.intInfo(mod);
11871189
11881190 const result: MCValue = result: {
11891191 const operand_lock: ?RegisterLock = switch (operand_mcv) {
......@@ -1257,8 +1259,9 @@ fn trunc(
12571259 operand_ty: Type,
12581260 dest_ty: Type,
12591261) !MCValue {
1260 const info_a = operand_ty.intInfo(self.target.*);
1261 const info_b = dest_ty.intInfo(self.target.*);
1262 const mod = self.bin_file.options.module.?;
1263 const info_a = operand_ty.intInfo(mod);
1264 const info_b = dest_ty.intInfo(mod);
12621265
12631266 if (info_b.bits <= 64) {
12641267 const operand_reg = switch (operand) {
......@@ -1319,6 +1322,7 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {
13191322
13201323fn airNot(self: *Self, inst: Air.Inst.Index) !void {
13211324 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1325 const mod = self.bin_file.options.module.?;
13221326 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
13231327 const operand = try self.resolveInst(ty_op.operand);
13241328 const operand_ty = self.air.typeOf(ty_op.operand);
......@@ -1327,7 +1331,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
13271331 .unreach => unreachable,
13281332 .compare_flags => |cond| break :result MCValue{ .compare_flags = cond.negate() },
13291333 else => {
1330 switch (operand_ty.zigTypeTag()) {
1334 switch (operand_ty.zigTypeTag(mod)) {
13311335 .Bool => {
13321336 // TODO convert this to mvn + and
13331337 const op_reg = switch (operand) {
......@@ -1361,7 +1365,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
13611365 },
13621366 .Vector => return self.fail("TODO bitwise not for vectors", .{}),
13631367 .Int => {
1364 const int_info = operand_ty.intInfo(self.target.*);
1368 const int_info = operand_ty.intInfo(mod);
13651369 if (int_info.bits <= 64) {
13661370 const op_reg = switch (operand) {
13671371 .register => |r| r,
......@@ -1413,13 +1417,13 @@ fn minMax(
14131417 rhs_ty: Type,
14141418 maybe_inst: ?Air.Inst.Index,
14151419) !MCValue {
1416 switch (lhs_ty.zigTypeTag()) {
1420 const mod = self.bin_file.options.module.?;
1421 switch (lhs_ty.zigTypeTag(mod)) {
14171422 .Float => return self.fail("TODO ARM min/max on floats", .{}),
14181423 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),
14191424 .Int => {
1420 const mod = self.bin_file.options.module.?;
14211425 assert(lhs_ty.eql(rhs_ty, mod));
1422 const int_info = lhs_ty.intInfo(self.target.*);
1426 const int_info = lhs_ty.intInfo(mod);
14231427 if (int_info.bits <= 64) {
14241428 var lhs_reg: Register = undefined;
14251429 var rhs_reg: Register = undefined;
......@@ -1907,12 +1911,12 @@ fn addSub(
19071911 maybe_inst: ?Air.Inst.Index,
19081912) InnerError!MCValue {
19091913 const mod = self.bin_file.options.module.?;
1910 switch (lhs_ty.zigTypeTag()) {
1914 switch (lhs_ty.zigTypeTag(mod)) {
19111915 .Float => return self.fail("TODO binary operations on floats", .{}),
19121916 .Vector => return self.fail("TODO binary operations on vectors", .{}),
19131917 .Int => {
19141918 assert(lhs_ty.eql(rhs_ty, mod));
1915 const int_info = lhs_ty.intInfo(self.target.*);
1919 const int_info = lhs_ty.intInfo(mod);
19161920 if (int_info.bits <= 64) {
19171921 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
19181922 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
......@@ -1968,11 +1972,11 @@ fn mul(
19681972 maybe_inst: ?Air.Inst.Index,
19691973) InnerError!MCValue {
19701974 const mod = self.bin_file.options.module.?;
1971 switch (lhs_ty.zigTypeTag()) {
1975 switch (lhs_ty.zigTypeTag(mod)) {
19721976 .Vector => return self.fail("TODO binary operations on vectors", .{}),
19731977 .Int => {
19741978 assert(lhs_ty.eql(rhs_ty, mod));
1975 const int_info = lhs_ty.intInfo(self.target.*);
1979 const int_info = lhs_ty.intInfo(mod);
19761980 if (int_info.bits <= 64) {
19771981 // TODO add optimisations for multiplication
19781982 // with immediates, for example a * 2 can be
......@@ -1999,7 +2003,8 @@ fn divFloat(
19992003 _ = rhs_ty;
20002004 _ = maybe_inst;
20012005
2002 switch (lhs_ty.zigTypeTag()) {
2006 const mod = self.bin_file.options.module.?;
2007 switch (lhs_ty.zigTypeTag(mod)) {
20032008 .Float => return self.fail("TODO div_float", .{}),
20042009 .Vector => return self.fail("TODO div_float on vectors", .{}),
20052010 else => unreachable,
......@@ -2015,12 +2020,12 @@ fn divTrunc(
20152020 maybe_inst: ?Air.Inst.Index,
20162021) InnerError!MCValue {
20172022 const mod = self.bin_file.options.module.?;
2018 switch (lhs_ty.zigTypeTag()) {
2023 switch (lhs_ty.zigTypeTag(mod)) {
20192024 .Float => return self.fail("TODO div on floats", .{}),
20202025 .Vector => return self.fail("TODO div on vectors", .{}),
20212026 .Int => {
20222027 assert(lhs_ty.eql(rhs_ty, mod));
2023 const int_info = lhs_ty.intInfo(self.target.*);
2028 const int_info = lhs_ty.intInfo(mod);
20242029 if (int_info.bits <= 64) {
20252030 switch (int_info.signedness) {
20262031 .signed => {
......@@ -2049,12 +2054,12 @@ fn divFloor(
20492054 maybe_inst: ?Air.Inst.Index,
20502055) InnerError!MCValue {
20512056 const mod = self.bin_file.options.module.?;
2052 switch (lhs_ty.zigTypeTag()) {
2057 switch (lhs_ty.zigTypeTag(mod)) {
20532058 .Float => return self.fail("TODO div on floats", .{}),
20542059 .Vector => return self.fail("TODO div on vectors", .{}),
20552060 .Int => {
20562061 assert(lhs_ty.eql(rhs_ty, mod));
2057 const int_info = lhs_ty.intInfo(self.target.*);
2062 const int_info = lhs_ty.intInfo(mod);
20582063 if (int_info.bits <= 64) {
20592064 switch (int_info.signedness) {
20602065 .signed => {
......@@ -2082,12 +2087,12 @@ fn divExact(
20822087 maybe_inst: ?Air.Inst.Index,
20832088) InnerError!MCValue {
20842089 const mod = self.bin_file.options.module.?;
2085 switch (lhs_ty.zigTypeTag()) {
2090 switch (lhs_ty.zigTypeTag(mod)) {
20862091 .Float => return self.fail("TODO div on floats", .{}),
20872092 .Vector => return self.fail("TODO div on vectors", .{}),
20882093 .Int => {
20892094 assert(lhs_ty.eql(rhs_ty, mod));
2090 const int_info = lhs_ty.intInfo(self.target.*);
2095 const int_info = lhs_ty.intInfo(mod);
20912096 if (int_info.bits <= 64) {
20922097 switch (int_info.signedness) {
20932098 .signed => {
......@@ -2118,12 +2123,12 @@ fn rem(
21182123 _ = maybe_inst;
21192124
21202125 const mod = self.bin_file.options.module.?;
2121 switch (lhs_ty.zigTypeTag()) {
2126 switch (lhs_ty.zigTypeTag(mod)) {
21222127 .Float => return self.fail("TODO rem/mod on floats", .{}),
21232128 .Vector => return self.fail("TODO rem/mod on vectors", .{}),
21242129 .Int => {
21252130 assert(lhs_ty.eql(rhs_ty, mod));
2126 const int_info = lhs_ty.intInfo(self.target.*);
2131 const int_info = lhs_ty.intInfo(mod);
21272132 if (int_info.bits <= 64) {
21282133 var lhs_reg: Register = undefined;
21292134 var rhs_reg: Register = undefined;
......@@ -2188,7 +2193,8 @@ fn modulo(
21882193 _ = rhs_ty;
21892194 _ = maybe_inst;
21902195
2191 switch (lhs_ty.zigTypeTag()) {
2196 const mod = self.bin_file.options.module.?;
2197 switch (lhs_ty.zigTypeTag(mod)) {
21922198 .Float => return self.fail("TODO mod on floats", .{}),
21932199 .Vector => return self.fail("TODO mod on vectors", .{}),
21942200 .Int => return self.fail("TODO mod on ints", .{}),
......@@ -2205,10 +2211,11 @@ fn wrappingArithmetic(
22052211 rhs_ty: Type,
22062212 maybe_inst: ?Air.Inst.Index,
22072213) InnerError!MCValue {
2208 switch (lhs_ty.zigTypeTag()) {
2214 const mod = self.bin_file.options.module.?;
2215 switch (lhs_ty.zigTypeTag(mod)) {
22092216 .Vector => return self.fail("TODO binary operations on vectors", .{}),
22102217 .Int => {
2211 const int_info = lhs_ty.intInfo(self.target.*);
2218 const int_info = lhs_ty.intInfo(mod);
22122219 if (int_info.bits <= 64) {
22132220 // Generate an add/sub/mul
22142221 const result: MCValue = switch (tag) {
......@@ -2240,11 +2247,11 @@ fn bitwise(
22402247 maybe_inst: ?Air.Inst.Index,
22412248) InnerError!MCValue {
22422249 const mod = self.bin_file.options.module.?;
2243 switch (lhs_ty.zigTypeTag()) {
2250 switch (lhs_ty.zigTypeTag(mod)) {
22442251 .Vector => return self.fail("TODO binary operations on vectors", .{}),
22452252 .Int => {
22462253 assert(lhs_ty.eql(rhs_ty, mod));
2247 const int_info = lhs_ty.intInfo(self.target.*);
2254 const int_info = lhs_ty.intInfo(mod);
22482255 if (int_info.bits <= 64) {
22492256 // TODO implement bitwise operations with immediates
22502257 const mir_tag: Mir.Inst.Tag = switch (tag) {
......@@ -2274,10 +2281,11 @@ fn shiftExact(
22742281) InnerError!MCValue {
22752282 _ = rhs_ty;
22762283
2277 switch (lhs_ty.zigTypeTag()) {
2284 const mod = self.bin_file.options.module.?;
2285 switch (lhs_ty.zigTypeTag(mod)) {
22782286 .Vector => return self.fail("TODO binary operations on vectors", .{}),
22792287 .Int => {
2280 const int_info = lhs_ty.intInfo(self.target.*);
2288 const int_info = lhs_ty.intInfo(mod);
22812289 if (int_info.bits <= 64) {
22822290 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
22832291
......@@ -2323,10 +2331,11 @@ fn shiftNormal(
23232331 rhs_ty: Type,
23242332 maybe_inst: ?Air.Inst.Index,
23252333) InnerError!MCValue {
2326 switch (lhs_ty.zigTypeTag()) {
2334 const mod = self.bin_file.options.module.?;
2335 switch (lhs_ty.zigTypeTag(mod)) {
23272336 .Vector => return self.fail("TODO binary operations on vectors", .{}),
23282337 .Int => {
2329 const int_info = lhs_ty.intInfo(self.target.*);
2338 const int_info = lhs_ty.intInfo(mod);
23302339 if (int_info.bits <= 64) {
23312340 // Generate a shl_exact/shr_exact
23322341 const result: MCValue = switch (tag) {
......@@ -2362,7 +2371,8 @@ fn booleanOp(
23622371 rhs_ty: Type,
23632372 maybe_inst: ?Air.Inst.Index,
23642373) InnerError!MCValue {
2365 switch (lhs_ty.zigTypeTag()) {
2374 const mod = self.bin_file.options.module.?;
2375 switch (lhs_ty.zigTypeTag(mod)) {
23662376 .Bool => {
23672377 assert((try lhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema
23682378 assert((try rhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema
......@@ -2388,9 +2398,9 @@ fn ptrArithmetic(
23882398 rhs_ty: Type,
23892399 maybe_inst: ?Air.Inst.Index,
23902400) InnerError!MCValue {
2391 switch (lhs_ty.zigTypeTag()) {
2401 const mod = self.bin_file.options.module.?;
2402 switch (lhs_ty.zigTypeTag(mod)) {
23922403 .Pointer => {
2393 const mod = self.bin_file.options.module.?;
23942404 assert(rhs_ty.eql(Type.usize, mod));
23952405
23962406 const ptr_ty = lhs_ty;
......@@ -2398,7 +2408,7 @@ fn ptrArithmetic(
23982408 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type
23992409 else => ptr_ty.childType(),
24002410 };
2401 const elem_size = elem_ty.abiSize(self.target.*);
2411 const elem_size = elem_ty.abiSize(mod);
24022412
24032413 const base_tag: Air.Inst.Tag = switch (tag) {
24042414 .ptr_add => .add,
......@@ -2511,6 +2521,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
25112521 const tag = self.air.instructions.items(.tag)[inst];
25122522 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
25132523 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2524 const mod = self.bin_file.options.module.?;
25142525 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
25152526 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
25162527 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
......@@ -2518,16 +2529,15 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
25182529 const rhs_ty = self.air.typeOf(extra.rhs);
25192530
25202531 const tuple_ty = self.air.typeOfIndex(inst);
2521 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));
2522 const tuple_align = tuple_ty.abiAlignment(self.target.*);
2523 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));
2532 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
2533 const tuple_align = tuple_ty.abiAlignment(mod);
2534 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
25242535
2525 switch (lhs_ty.zigTypeTag()) {
2536 switch (lhs_ty.zigTypeTag(mod)) {
25262537 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
25272538 .Int => {
2528 const mod = self.bin_file.options.module.?;
25292539 assert(lhs_ty.eql(rhs_ty, mod));
2530 const int_info = lhs_ty.intInfo(self.target.*);
2540 const int_info = lhs_ty.intInfo(mod);
25312541 switch (int_info.bits) {
25322542 1...31, 33...63 => {
25332543 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
......@@ -2639,24 +2649,23 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
26392649 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
26402650 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
26412651 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
2652 const mod = self.bin_file.options.module.?;
26422653 const result: MCValue = result: {
2643 const mod = self.bin_file.options.module.?;
2644
26452654 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
26462655 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
26472656 const lhs_ty = self.air.typeOf(extra.lhs);
26482657 const rhs_ty = self.air.typeOf(extra.rhs);
26492658
26502659 const tuple_ty = self.air.typeOfIndex(inst);
2651 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));
2652 const tuple_align = tuple_ty.abiAlignment(self.target.*);
2653 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));
2660 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
2661 const tuple_align = tuple_ty.abiAlignment(mod);
2662 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
26542663
2655 switch (lhs_ty.zigTypeTag()) {
2664 switch (lhs_ty.zigTypeTag(mod)) {
26562665 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
26572666 .Int => {
26582667 assert(lhs_ty.eql(rhs_ty, mod));
2659 const int_info = lhs_ty.intInfo(self.target.*);
2668 const int_info = lhs_ty.intInfo(mod);
26602669 if (int_info.bits <= 32) {
26612670 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
26622671
......@@ -2864,6 +2873,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
28642873 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
28652874 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
28662875 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
2876 const mod = self.bin_file.options.module.?;
28672877 const result: MCValue = result: {
28682878 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
28692879 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
......@@ -2871,14 +2881,14 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
28712881 const rhs_ty = self.air.typeOf(extra.rhs);
28722882
28732883 const tuple_ty = self.air.typeOfIndex(inst);
2874 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));
2875 const tuple_align = tuple_ty.abiAlignment(self.target.*);
2876 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));
2884 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
2885 const tuple_align = tuple_ty.abiAlignment(mod);
2886 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
28772887
2878 switch (lhs_ty.zigTypeTag()) {
2888 switch (lhs_ty.zigTypeTag(mod)) {
28792889 .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),
28802890 .Int => {
2881 const int_info = lhs_ty.intInfo(self.target.*);
2891 const int_info = lhs_ty.intInfo(mod);
28822892 if (int_info.bits <= 64) {
28832893 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
28842894
......@@ -3011,10 +3021,11 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
30113021}
30123022
30133023fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue {
3024 const mod = self.bin_file.options.module.?;
30143025 var opt_buf: Type.Payload.ElemType = undefined;
30153026 const payload_ty = optional_ty.optionalChild(&opt_buf);
3016 if (!payload_ty.hasRuntimeBits()) return MCValue.none;
3017 if (optional_ty.isPtrLikeOptional()) {
3027 if (!payload_ty.hasRuntimeBits(mod)) return MCValue.none;
3028 if (optional_ty.isPtrLikeOptional(mod)) {
30183029 // TODO should we reuse the operand here?
30193030 const raw_reg = try self.register_manager.allocReg(inst, gp);
30203031 const reg = self.registerAlias(raw_reg, payload_ty);
......@@ -3055,16 +3066,17 @@ fn errUnionErr(
30553066 error_union_ty: Type,
30563067 maybe_inst: ?Air.Inst.Index,
30573068) !MCValue {
3069 const mod = self.bin_file.options.module.?;
30583070 const err_ty = error_union_ty.errorUnionSet();
30593071 const payload_ty = error_union_ty.errorUnionPayload();
30603072 if (err_ty.errorSetIsEmpty()) {
30613073 return MCValue{ .immediate = 0 };
30623074 }
3063 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3075 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
30643076 return try error_union_bind.resolveToMcv(self);
30653077 }
30663078
3067 const err_offset = @intCast(u32, errUnionErrorOffset(payload_ty, self.target.*));
3079 const err_offset = @intCast(u32, errUnionErrorOffset(payload_ty, mod));
30683080 switch (try error_union_bind.resolveToMcv(self)) {
30693081 .register => {
30703082 var operand_reg: Register = undefined;
......@@ -3086,7 +3098,7 @@ fn errUnionErr(
30863098 );
30873099
30883100 const err_bit_offset = err_offset * 8;
3089 const err_bit_size = @intCast(u32, err_ty.abiSize(self.target.*)) * 8;
3101 const err_bit_size = @intCast(u32, err_ty.abiSize(mod)) * 8;
30903102
30913103 _ = try self.addInst(.{
30923104 .tag = .ubfx, // errors are unsigned integers
......@@ -3134,16 +3146,17 @@ fn errUnionPayload(
31343146 error_union_ty: Type,
31353147 maybe_inst: ?Air.Inst.Index,
31363148) !MCValue {
3149 const mod = self.bin_file.options.module.?;
31373150 const err_ty = error_union_ty.errorUnionSet();
31383151 const payload_ty = error_union_ty.errorUnionPayload();
31393152 if (err_ty.errorSetIsEmpty()) {
31403153 return try error_union_bind.resolveToMcv(self);
31413154 }
3142 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3155 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
31433156 return MCValue.none;
31443157 }
31453158
3146 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target.*));
3159 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, mod));
31473160 switch (try error_union_bind.resolveToMcv(self)) {
31483161 .register => {
31493162 var operand_reg: Register = undefined;
......@@ -3165,10 +3178,10 @@ fn errUnionPayload(
31653178 );
31663179
31673180 const payload_bit_offset = payload_offset * 8;
3168 const payload_bit_size = @intCast(u32, payload_ty.abiSize(self.target.*)) * 8;
3181 const payload_bit_size = @intCast(u32, payload_ty.abiSize(mod)) * 8;
31693182
31703183 _ = try self.addInst(.{
3171 .tag = if (payload_ty.isSignedInt()) Mir.Inst.Tag.sbfx else .ubfx,
3184 .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,
31723185 .data = .{
31733186 .rr_lsb_width = .{
31743187 // Set both registers to the X variant to get the full width
......@@ -3245,6 +3258,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
32453258}
32463259
32473260fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3261 const mod = self.bin_file.options.module.?;
32483262 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
32493263
32503264 if (self.liveness.isUnused(inst)) {
......@@ -3253,7 +3267,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
32533267
32543268 const result: MCValue = result: {
32553269 const payload_ty = self.air.typeOf(ty_op.operand);
3256 if (!payload_ty.hasRuntimeBits()) {
3270 if (!payload_ty.hasRuntimeBits(mod)) {
32573271 break :result MCValue{ .immediate = 1 };
32583272 }
32593273
......@@ -3265,7 +3279,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
32653279 };
32663280 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
32673281
3268 if (optional_ty.isPtrLikeOptional()) {
3282 if (optional_ty.isPtrLikeOptional(mod)) {
32693283 // TODO should we check if we can reuse the operand?
32703284 const raw_reg = try self.register_manager.allocReg(inst, gp);
32713285 const reg = self.registerAlias(raw_reg, payload_ty);
......@@ -3273,9 +3287,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
32733287 break :result MCValue{ .register = reg };
32743288 }
32753289
3276 const optional_abi_size = @intCast(u32, optional_ty.abiSize(self.target.*));
3277 const optional_abi_align = optional_ty.abiAlignment(self.target.*);
3278 const offset = @intCast(u32, payload_ty.abiSize(self.target.*));
3290 const optional_abi_size = @intCast(u32, optional_ty.abiSize(mod));
3291 const optional_abi_align = optional_ty.abiAlignment(mod);
3292 const offset = @intCast(u32, payload_ty.abiSize(mod));
32793293
32803294 const stack_offset = try self.allocMem(optional_abi_size, optional_abi_align, inst);
32813295 try self.genSetStack(payload_ty, stack_offset, operand);
......@@ -3289,19 +3303,20 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
32893303
32903304/// T to E!T
32913305fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3306 const mod = self.bin_file.options.module.?;
32923307 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
32933308 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
32943309 const error_union_ty = self.air.getRefType(ty_op.ty);
32953310 const error_ty = error_union_ty.errorUnionSet();
32963311 const payload_ty = error_union_ty.errorUnionPayload();
32973312 const operand = try self.resolveInst(ty_op.operand);
3298 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result operand;
3313 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
32993314
3300 const abi_size = @intCast(u32, error_union_ty.abiSize(self.target.*));
3301 const abi_align = error_union_ty.abiAlignment(self.target.*);
3315 const abi_size = @intCast(u32, error_union_ty.abiSize(mod));
3316 const abi_align = error_union_ty.abiAlignment(mod);
33023317 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
3303 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);
3304 const err_off = errUnionErrorOffset(payload_ty, self.target.*);
3318 const payload_off = errUnionPayloadOffset(payload_ty, mod);
3319 const err_off = errUnionErrorOffset(payload_ty, mod);
33053320 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), operand);
33063321 try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), .{ .immediate = 0 });
33073322
......@@ -3314,17 +3329,18 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
33143329fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
33153330 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
33163331 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3332 const mod = self.bin_file.options.module.?;
33173333 const error_union_ty = self.air.getRefType(ty_op.ty);
33183334 const error_ty = error_union_ty.errorUnionSet();
33193335 const payload_ty = error_union_ty.errorUnionPayload();
33203336 const operand = try self.resolveInst(ty_op.operand);
3321 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result operand;
3337 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
33223338
3323 const abi_size = @intCast(u32, error_union_ty.abiSize(self.target.*));
3324 const abi_align = error_union_ty.abiAlignment(self.target.*);
3339 const abi_size = @intCast(u32, error_union_ty.abiSize(mod));
3340 const abi_align = error_union_ty.abiAlignment(mod);
33253341 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
3326 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);
3327 const err_off = errUnionErrorOffset(payload_ty, self.target.*);
3342 const payload_off = errUnionPayloadOffset(payload_ty, mod);
3343 const err_off = errUnionErrorOffset(payload_ty, mod);
33283344 try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), operand);
33293345 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), .undef);
33303346
......@@ -3440,8 +3456,9 @@ fn ptrElemVal(
34403456 ptr_ty: Type,
34413457 maybe_inst: ?Air.Inst.Index,
34423458) !MCValue {
3459 const mod = self.bin_file.options.module.?;
34433460 const elem_ty = ptr_ty.childType();
3444 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
3461 const elem_size = @intCast(u32, elem_ty.abiSize(mod));
34453462
34463463 // TODO optimize for elem_sizes of 1, 2, 4, 8
34473464 switch (elem_size) {
......@@ -3597,8 +3614,9 @@ fn reuseOperand(
35973614}
35983615
35993616fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
3617 const mod = self.bin_file.options.module.?;
36003618 const elem_ty = ptr_ty.elemType();
3601 const elem_size = elem_ty.abiSize(self.target.*);
3619 const elem_size = elem_ty.abiSize(mod);
36023620
36033621 switch (ptr) {
36043622 .none => unreachable,
......@@ -3846,9 +3864,10 @@ fn genInlineMemsetCode(
38463864fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
38473865 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
38483866 const elem_ty = self.air.typeOfIndex(inst);
3849 const elem_size = elem_ty.abiSize(self.target.*);
3867 const mod = self.bin_file.options.module.?;
3868 const elem_size = elem_ty.abiSize(mod);
38503869 const result: MCValue = result: {
3851 if (!elem_ty.hasRuntimeBits())
3870 if (!elem_ty.hasRuntimeBits(mod))
38523871 break :result MCValue.none;
38533872
38543873 const ptr = try self.resolveInst(ty_op.operand);
......@@ -3874,11 +3893,12 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
38743893}
38753894
38763895fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void {
3877 const abi_size = ty.abiSize(self.target.*);
3896 const mod = self.bin_file.options.module.?;
3897 const abi_size = ty.abiSize(mod);
38783898
38793899 const tag: Mir.Inst.Tag = switch (abi_size) {
3880 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb_immediate else .ldrb_immediate,
3881 2 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsh_immediate else .ldrh_immediate,
3900 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_immediate else .ldrb_immediate,
3901 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_immediate else .ldrh_immediate,
38823902 4 => .ldr_immediate,
38833903 8 => .ldr_immediate,
38843904 3, 5, 6, 7 => return self.fail("TODO: genLdrRegister for more abi_sizes", .{}),
......@@ -3896,7 +3916,8 @@ fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type
38963916}
38973917
38983918fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void {
3899 const abi_size = ty.abiSize(self.target.*);
3919 const mod = self.bin_file.options.module.?;
3920 const abi_size = ty.abiSize(mod);
39003921
39013922 const tag: Mir.Inst.Tag = switch (abi_size) {
39023923 1 => .strb_immediate,
......@@ -3917,8 +3938,9 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type
39173938}
39183939
39193940fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
3941 const mod = self.bin_file.options.module.?;
39203942 log.debug("store: storing {} to {}", .{ value, ptr });
3921 const abi_size = value_ty.abiSize(self.target.*);
3943 const abi_size = value_ty.abiSize(mod);
39223944
39233945 switch (ptr) {
39243946 .none => unreachable,
......@@ -4069,10 +4091,11 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
40694091
40704092fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
40714093 return if (self.liveness.isUnused(inst)) .dead else result: {
4094 const mod = self.bin_file.options.module.?;
40724095 const mcv = try self.resolveInst(operand);
40734096 const ptr_ty = self.air.typeOf(operand);
40744097 const struct_ty = ptr_ty.childType();
4075 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
4098 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
40764099 switch (mcv) {
40774100 .ptr_stack_offset => |off| {
40784101 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
......@@ -4093,10 +4116,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
40934116 const operand = extra.struct_operand;
40944117 const index = extra.field_index;
40954118 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4119 const mod = self.bin_file.options.module.?;
40964120 const mcv = try self.resolveInst(operand);
40974121 const struct_ty = self.air.typeOf(operand);
40984122 const struct_field_ty = struct_ty.structFieldType(index);
4099 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
4123 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
41004124
41014125 switch (mcv) {
41024126 .dead, .unreach => unreachable,
......@@ -4142,12 +4166,13 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
41424166}
41434167
41444168fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
4169 const mod = self.bin_file.options.module.?;
41454170 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
41464171 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
41474172 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
41484173 const field_ptr = try self.resolveInst(extra.field_ptr);
41494174 const struct_ty = self.air.getRefType(ty_pl.ty).childType();
4150 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(extra.field_index, self.target.*));
4175 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(extra.field_index, mod));
41514176 switch (field_ptr) {
41524177 .ptr_stack_offset => |off| {
41534178 break :result MCValue{ .ptr_stack_offset = off + struct_field_offset };
......@@ -4223,8 +4248,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42234248 const extra = self.air.extraData(Air.Call, pl_op.payload);
42244249 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
42254250 const ty = self.air.typeOf(callee);
4251 const mod = self.bin_file.options.module.?;
42264252
4227 const fn_ty = switch (ty.zigTypeTag()) {
4253 const fn_ty = switch (ty.zigTypeTag(mod)) {
42284254 .Fn => ty,
42294255 .Pointer => ty.childType(),
42304256 else => unreachable,
......@@ -4246,8 +4272,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42464272 if (info.return_value == .stack_offset) {
42474273 log.debug("airCall: return by reference", .{});
42484274 const ret_ty = fn_ty.fnReturnType();
4249 const ret_abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));
4250 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(self.target.*));
4275 const ret_abi_size = @intCast(u32, ret_ty.abiSize(mod));
4276 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(mod));
42514277 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);
42524278
42534279 const ret_ptr_reg = self.registerAlias(.x0, Type.usize);
......@@ -4289,8 +4315,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42894315
42904316 // Due to incremental compilation, how function calls are generated depends
42914317 // on linking.
4292 const mod = self.bin_file.options.module.?;
4293 if (self.air.value(callee)) |func_value| {
4318 if (self.air.value(callee, mod)) |func_value| {
42944319 if (func_value.castTag(.function)) |func_payload| {
42954320 const func = func_payload.data;
42964321
......@@ -4369,7 +4394,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43694394 return self.fail("TODO implement calling bitcasted functions", .{});
43704395 }
43714396 } else {
4372 assert(ty.zigTypeTag() == .Pointer);
4397 assert(ty.zigTypeTag(mod) == .Pointer);
43734398 const mcv = try self.resolveInst(callee);
43744399 try self.genSetReg(ty, .x30, mcv);
43754400
......@@ -4410,11 +4435,12 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
44104435 const un_op = self.air.instructions.items(.data)[inst].un_op;
44114436 const operand = try self.resolveInst(un_op);
44124437 const ret_ty = self.fn_type.fnReturnType();
4438 const mod = self.bin_file.options.module.?;
44134439
44144440 switch (self.ret_mcv) {
44154441 .none => {},
44164442 .immediate => {
4417 assert(ret_ty.isError());
4443 assert(ret_ty.isError(mod));
44184444 },
44194445 .register => |reg| {
44204446 // Return result by value
......@@ -4465,8 +4491,9 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
44654491 // location.
44664492 const op_inst = Air.refToIndex(un_op).?;
44674493 if (self.air.instructions.items(.tag)[op_inst] != .ret_ptr) {
4468 const abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));
4469 const abi_align = ret_ty.abiAlignment(self.target.*);
4494 const mod = self.bin_file.options.module.?;
4495 const abi_size = @intCast(u32, ret_ty.abiSize(mod));
4496 const abi_align = ret_ty.abiAlignment(mod);
44704497
44714498 const offset = try self.allocMem(abi_size, abi_align, null);
44724499
......@@ -4501,21 +4528,21 @@ fn cmp(
45014528 lhs_ty: Type,
45024529 op: math.CompareOperator,
45034530) !MCValue {
4504 var int_buffer: Type.Payload.Bits = undefined;
4505 const int_ty = switch (lhs_ty.zigTypeTag()) {
4531 const mod = self.bin_file.options.module.?;
4532 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
45064533 .Optional => blk: {
45074534 var opt_buffer: Type.Payload.ElemType = undefined;
45084535 const payload_ty = lhs_ty.optionalChild(&opt_buffer);
4509 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
4536 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
45104537 break :blk Type.initTag(.u1);
4511 } else if (lhs_ty.isPtrLikeOptional()) {
4538 } else if (lhs_ty.isPtrLikeOptional(mod)) {
45124539 break :blk Type.usize;
45134540 } else {
45144541 return self.fail("TODO ARM cmp non-pointer optionals", .{});
45154542 }
45164543 },
45174544 .Float => return self.fail("TODO ARM cmp floats", .{}),
4518 .Enum => lhs_ty.intTagType(&int_buffer),
4545 .Enum => lhs_ty.intTagType(),
45194546 .Int => lhs_ty,
45204547 .Bool => Type.initTag(.u1),
45214548 .Pointer => Type.usize,
......@@ -4523,7 +4550,7 @@ fn cmp(
45234550 else => unreachable,
45244551 };
45254552
4526 const int_info = int_ty.intInfo(self.target.*);
4553 const int_info = int_ty.intInfo(mod);
45274554 if (int_info.bits <= 64) {
45284555 try self.spillCompareFlagsIfOccupied();
45294556
......@@ -4687,8 +4714,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
46874714 // whether it needs to be spilled in the branches
46884715 if (self.liveness.operandDies(inst, 0)) {
46894716 const op_int = @enumToInt(pl_op.operand);
4690 if (op_int >= Air.Inst.Ref.typed_value_map.len) {
4691 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);
4717 if (op_int >= Air.ref_start_index) {
4718 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
46924719 self.processDeath(op_index);
46934720 }
46944721 }
......@@ -4819,13 +4846,14 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
48194846}
48204847
48214848fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue {
4822 const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional()) blk: {
4849 const mod = self.bin_file.options.module.?;
4850 const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional(mod)) blk: {
48234851 var buf: Type.Payload.ElemType = undefined;
48244852 const payload_ty = operand_ty.optionalChild(&buf);
4825 if (!payload_ty.hasRuntimeBitsIgnoreComptime())
4853 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
48264854 break :blk .{ .ty = operand_ty, .bind = operand_bind };
48274855
4828 const offset = @intCast(u32, payload_ty.abiSize(self.target.*));
4856 const offset = @intCast(u32, payload_ty.abiSize(mod));
48294857 const operand_mcv = try operand_bind.resolveToMcv(self);
48304858 const new_mcv: MCValue = switch (operand_mcv) {
48314859 .register => |source_reg| new: {
......@@ -4838,7 +4866,7 @@ fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue {
48384866 try self.genSetReg(payload_ty, dest_reg, operand_mcv);
48394867 } else {
48404868 _ = try self.addInst(.{
4841 .tag = if (payload_ty.isSignedInt())
4869 .tag = if (payload_ty.isSignedInt(mod))
48424870 Mir.Inst.Tag.asr_immediate
48434871 else
48444872 Mir.Inst.Tag.lsr_immediate,
......@@ -5210,9 +5238,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
52105238}
52115239
52125240fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5241 const mod = self.bin_file.options.module.?;
52135242 const block_data = self.blocks.getPtr(block).?;
52145243
5215 if (self.air.typeOf(operand).hasRuntimeBits()) {
5244 if (self.air.typeOf(operand).hasRuntimeBits(mod)) {
52165245 const operand_mcv = try self.resolveInst(operand);
52175246 const block_mcv = block_data.mcv;
52185247 if (block_mcv == .none) {
......@@ -5386,7 +5415,8 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
53865415}
53875416
53885417fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5389 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
5418 const mod = self.bin_file.options.module.?;
5419 const abi_size = @intCast(u32, ty.abiSize(mod));
53905420 switch (mcv) {
53915421 .dead => unreachable,
53925422 .unreach, .none => return, // Nothing to do.
......@@ -5445,7 +5475,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
54455475 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });
54465476
54475477 const overflow_bit_ty = ty.structFieldType(1);
5448 const overflow_bit_offset = @intCast(u32, ty.structFieldOffset(1, self.target.*));
5478 const overflow_bit_offset = @intCast(u32, ty.structFieldOffset(1, mod));
54495479 const raw_cond_reg = try self.register_manager.allocReg(null, gp);
54505480 const cond_reg = self.registerAlias(raw_cond_reg, overflow_bit_ty);
54515481
......@@ -5559,6 +5589,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
55595589}
55605590
55615591fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
5592 const mod = self.bin_file.options.module.?;
55625593 switch (mcv) {
55635594 .dead => unreachable,
55645595 .unreach, .none => return, // Nothing to do.
......@@ -5669,13 +5700,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
56695700 try self.genLdrRegister(reg, reg.toX(), ty);
56705701 },
56715702 .stack_offset => |off| {
5672 const abi_size = ty.abiSize(self.target.*);
5703 const abi_size = ty.abiSize(mod);
56735704
56745705 switch (abi_size) {
56755706 1, 2, 4, 8 => {
56765707 const tag: Mir.Inst.Tag = switch (abi_size) {
5677 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb_stack else .ldrb_stack,
5678 2 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsh_stack else .ldrh_stack,
5708 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack else .ldrb_stack,
5709 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_stack else .ldrh_stack,
56795710 4, 8 => .ldr_stack,
56805711 else => unreachable, // unexpected abi size
56815712 };
......@@ -5693,13 +5724,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
56935724 }
56945725 },
56955726 .stack_argument_offset => |off| {
5696 const abi_size = ty.abiSize(self.target.*);
5727 const abi_size = ty.abiSize(mod);
56975728
56985729 switch (abi_size) {
56995730 1, 2, 4, 8 => {
57005731 const tag: Mir.Inst.Tag = switch (abi_size) {
5701 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,
5702 2 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsh_stack_argument else .ldrh_stack_argument,
5732 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,
5733 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_stack_argument else .ldrh_stack_argument,
57035734 4, 8 => .ldr_stack_argument,
57045735 else => unreachable, // unexpected abi size
57055736 };
......@@ -5720,7 +5751,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
57205751}
57215752
57225753fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5723 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
5754 const mod = self.bin_file.options.module.?;
5755 const abi_size = @intCast(u32, ty.abiSize(mod));
57245756 switch (mcv) {
57255757 .dead => unreachable,
57265758 .none, .unreach => return,
......@@ -5728,7 +5760,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
57285760 if (!self.wantSafety())
57295761 return; // The already existing value will do just fine.
57305762 // TODO Upgrade this to a memset call when we have that available.
5731 switch (ty.abiSize(self.target.*)) {
5763 switch (ty.abiSize(mod)) {
57325764 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }),
57335765 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),
57345766 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),
......@@ -6087,14 +6119,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
60876119}
60886120
60896121fn airTry(self: *Self, inst: Air.Inst.Index) !void {
6122 const mod = self.bin_file.options.module.?;
60906123 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
60916124 const extra = self.air.extraData(Air.Try, pl_op.payload);
60926125 const body = self.air.extra[extra.end..][0..extra.data.body_len];
60936126 const result: MCValue = result: {
60946127 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
60956128 const error_union_ty = self.air.typeOf(pl_op.operand);
6096 const error_union_size = @intCast(u32, error_union_ty.abiSize(self.target.*));
6097 const error_union_align = error_union_ty.abiAlignment(self.target.*);
6129 const error_union_size = @intCast(u32, error_union_ty.abiSize(mod));
6130 const error_union_align = error_union_ty.abiAlignment(mod);
60986131
60996132 // The error union will die in the body. However, we need the
61006133 // error union after the body in order to extract the payload
......@@ -6123,22 +6156,18 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
61236156}
61246157
61256158fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
6126 // First section of indexes correspond to a set number of constant values.
6127 const ref_int = @enumToInt(inst);
6128 if (ref_int < Air.Inst.Ref.typed_value_map.len) {
6129 const tv = Air.Inst.Ref.typed_value_map[ref_int];
6130 if (!tv.ty.hasRuntimeBitsIgnoreComptime() and !tv.ty.isError()) {
6131 return MCValue{ .none = {} };
6132 }
6133 return self.genTypedValue(tv);
6134 }
6159 const mod = self.bin_file.options.module.?;
61356160
61366161 // If the type has no codegen bits, no need to store it.
61376162 const inst_ty = self.air.typeOf(inst);
6138 if (!inst_ty.hasRuntimeBitsIgnoreComptime() and !inst_ty.isError())
6163 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))
61396164 return MCValue{ .none = {} };
61406165
6141 const inst_index = @intCast(Air.Inst.Index, ref_int - Air.Inst.Ref.typed_value_map.len);
6166 const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{
6167 .ty = inst_ty,
6168 .val = self.air.value(inst, mod).?,
6169 });
6170
61426171 switch (self.air.instructions.items(.tag)[inst_index]) {
61436172 .constant => {
61446173 // Constants have static lifetimes, so they are always memoized in the outer most table.
......@@ -6222,6 +6251,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62226251 errdefer self.gpa.free(result.args);
62236252
62246253 const ret_ty = fn_ty.fnReturnType();
6254 const mod = self.bin_file.options.module.?;
62256255
62266256 switch (cc) {
62276257 .Naked => {
......@@ -6236,14 +6266,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62366266 var ncrn: usize = 0; // Next Core Register Number
62376267 var nsaa: u32 = 0; // Next stacked argument address
62386268
6239 if (ret_ty.zigTypeTag() == .NoReturn) {
6269 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
62406270 result.return_value = .{ .unreach = {} };
6241 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime() and !ret_ty.isError()) {
6271 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {
62426272 result.return_value = .{ .none = {} };
62436273 } else {
6244 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));
6274 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
62456275 if (ret_ty_size == 0) {
6246 assert(ret_ty.isError());
6276 assert(ret_ty.isError(mod));
62476277 result.return_value = .{ .immediate = 0 };
62486278 } else if (ret_ty_size <= 8) {
62496279 result.return_value = .{ .register = self.registerAlias(c_abi_int_return_regs[0], ret_ty) };
......@@ -6253,7 +6283,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62536283 }
62546284
62556285 for (param_types, 0..) |ty, i| {
6256 const param_size = @intCast(u32, ty.abiSize(self.target.*));
6286 const param_size = @intCast(u32, ty.abiSize(mod));
62576287 if (param_size == 0) {
62586288 result.args[i] = .{ .none = {} };
62596289 continue;
......@@ -6261,7 +6291,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62616291
62626292 // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned
62636293 // values to spread across odd-numbered registers.
6264 if (ty.abiAlignment(self.target.*) == 16 and !self.target.isDarwin()) {
6294 if (ty.abiAlignment(mod) == 16 and !self.target.isDarwin()) {
62656295 // Round up NCRN to the next even number
62666296 ncrn += ncrn % 2;
62676297 }
......@@ -6279,7 +6309,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62796309 ncrn = 8;
62806310 // TODO Apple allows the arguments on the stack to be non-8-byte aligned provided
62816311 // that the entire stack space consumed by the arguments is 8-byte aligned.
6282 if (ty.abiAlignment(self.target.*) == 8) {
6312 if (ty.abiAlignment(mod) == 8) {
62836313 if (nsaa % 8 != 0) {
62846314 nsaa += 8 - (nsaa % 8);
62856315 }
......@@ -6294,14 +6324,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62946324 result.stack_align = 16;
62956325 },
62966326 .Unspecified => {
6297 if (ret_ty.zigTypeTag() == .NoReturn) {
6327 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
62986328 result.return_value = .{ .unreach = {} };
6299 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime() and !ret_ty.isError()) {
6329 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {
63006330 result.return_value = .{ .none = {} };
63016331 } else {
6302 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));
6332 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
63036333 if (ret_ty_size == 0) {
6304 assert(ret_ty.isError());
6334 assert(ret_ty.isError(mod));
63056335 result.return_value = .{ .immediate = 0 };
63066336 } else if (ret_ty_size <= 8) {
63076337 result.return_value = .{ .register = self.registerAlias(.x0, ret_ty) };
......@@ -6318,9 +6348,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
63186348 var stack_offset: u32 = 0;
63196349
63206350 for (param_types, 0..) |ty, i| {
6321 if (ty.abiSize(self.target.*) > 0) {
6322 const param_size = @intCast(u32, ty.abiSize(self.target.*));
6323 const param_alignment = ty.abiAlignment(self.target.*);
6351 if (ty.abiSize(mod) > 0) {
6352 const param_size = @intCast(u32, ty.abiSize(mod));
6353 const param_alignment = ty.abiAlignment(mod);
63246354
63256355 stack_offset = std.mem.alignForwardGeneric(u32, stack_offset, param_alignment);
63266356 result.args[i] = .{ .stack_argument_offset = stack_offset };
......@@ -6371,7 +6401,8 @@ fn parseRegName(name: []const u8) ?Register {
63716401}
63726402
63736403fn registerAlias(self: *Self, reg: Register, ty: Type) Register {
6374 const abi_size = ty.abiSize(self.target.*);
6404 const mod = self.bin_file.options.module.?;
6405 const abi_size = ty.abiSize(mod);
63756406
63766407 switch (reg.class()) {
63776408 .general_purpose => {
src/arch/aarch64/abi.zig+19-17
......@@ -4,6 +4,7 @@ const bits = @import("bits.zig");
44const Register = bits.Register;
55const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
66const Type = @import("../../type.zig").Type;
7const Module = @import("../../Module.zig");
78
89pub const Class = union(enum) {
910 memory,
......@@ -14,40 +15,40 @@ pub const Class = union(enum) {
1415};
1516
1617/// For `float_array` the second element will be the amount of floats.
17pub fn classifyType(ty: Type, target: std.Target) Class {
18 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime());
18pub fn classifyType(ty: Type, mod: *const Module) Class {
19 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod));
1920
2021 var maybe_float_bits: ?u16 = null;
21 switch (ty.zigTypeTag()) {
22 switch (ty.zigTypeTag(mod)) {
2223 .Struct => {
2324 if (ty.containerLayout() == .Packed) return .byval;
24 const float_count = countFloats(ty, target, &maybe_float_bits);
25 const float_count = countFloats(ty, mod, &maybe_float_bits);
2526 if (float_count <= sret_float_count) return .{ .float_array = float_count };
2627
27 const bit_size = ty.bitSize(target);
28 const bit_size = ty.bitSize(mod);
2829 if (bit_size > 128) return .memory;
2930 if (bit_size > 64) return .double_integer;
3031 return .integer;
3132 },
3233 .Union => {
3334 if (ty.containerLayout() == .Packed) return .byval;
34 const float_count = countFloats(ty, target, &maybe_float_bits);
35 const float_count = countFloats(ty, mod, &maybe_float_bits);
3536 if (float_count <= sret_float_count) return .{ .float_array = float_count };
3637
37 const bit_size = ty.bitSize(target);
38 const bit_size = ty.bitSize(mod);
3839 if (bit_size > 128) return .memory;
3940 if (bit_size > 64) return .double_integer;
4041 return .integer;
4142 },
4243 .Int, .Enum, .ErrorSet, .Float, .Bool => return .byval,
4344 .Vector => {
44 const bit_size = ty.bitSize(target);
45 const bit_size = ty.bitSize(mod);
4546 // TODO is this controlled by a cpu feature?
4647 if (bit_size > 128) return .memory;
4748 return .byval;
4849 },
4950 .Optional => {
50 std.debug.assert(ty.isPtrLikeOptional());
51 std.debug.assert(ty.isPtrLikeOptional(mod));
5152 return .byval;
5253 },
5354 .Pointer => {
......@@ -73,14 +74,15 @@ pub fn classifyType(ty: Type, target: std.Target) Class {
7374}
7475
7576const sret_float_count = 4;
76fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u8 {
77fn countFloats(ty: Type, mod: *const Module, maybe_float_bits: *?u16) u8 {
78 const target = mod.getTarget();
7779 const invalid = std.math.maxInt(u8);
78 switch (ty.zigTypeTag()) {
80 switch (ty.zigTypeTag(mod)) {
7981 .Union => {
8082 const fields = ty.unionFields();
8183 var max_count: u8 = 0;
8284 for (fields.values()) |field| {
83 const field_count = countFloats(field.ty, target, maybe_float_bits);
85 const field_count = countFloats(field.ty, mod, maybe_float_bits);
8486 if (field_count == invalid) return invalid;
8587 if (field_count > max_count) max_count = field_count;
8688 if (max_count > sret_float_count) return invalid;
......@@ -93,7 +95,7 @@ fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u8 {
9395 var i: u32 = 0;
9496 while (i < fields_len) : (i += 1) {
9597 const field_ty = ty.structFieldType(i);
96 const field_count = countFloats(field_ty, target, maybe_float_bits);
98 const field_count = countFloats(field_ty, mod, maybe_float_bits);
9799 if (field_count == invalid) return invalid;
98100 count += field_count;
99101 if (count > sret_float_count) return invalid;
......@@ -113,12 +115,12 @@ fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u8 {
113115 }
114116}
115117
116pub fn getFloatArrayType(ty: Type) ?Type {
117 switch (ty.zigTypeTag()) {
118pub fn getFloatArrayType(ty: Type, mod: *const Module) ?Type {
119 switch (ty.zigTypeTag(mod)) {
118120 .Union => {
119121 const fields = ty.unionFields();
120122 for (fields.values()) |field| {
121 if (getFloatArrayType(field.ty)) |some| return some;
123 if (getFloatArrayType(field.ty, mod)) |some| return some;
122124 }
123125 return null;
124126 },
......@@ -127,7 +129,7 @@ pub fn getFloatArrayType(ty: Type) ?Type {
127129 var i: u32 = 0;
128130 while (i < fields_len) : (i += 1) {
129131 const field_ty = ty.structFieldType(i);
130 if (getFloatArrayType(field_ty)) |some| return some;
132 if (getFloatArrayType(field_ty, mod)) |some| return some;
131133 }
132134 return null;
133135 },
src/arch/arm/CodeGen.zig+187-155
......@@ -520,8 +520,9 @@ fn gen(self: *Self) !void {
520520
521521 const ty = self.air.typeOfIndex(inst);
522522
523 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
524 const abi_align = ty.abiAlignment(self.target.*);
523 const mod = self.bin_file.options.module.?;
524 const abi_size = @intCast(u32, ty.abiSize(mod));
525 const abi_align = ty.abiAlignment(mod);
525526 const stack_offset = try self.allocMem(abi_size, abi_align, inst);
526527 try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
527528
......@@ -937,8 +938,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
937938 tomb_bits >>= 1;
938939 if (!dies) continue;
939940 const op_int = @enumToInt(op);
940 if (op_int < Air.Inst.Ref.typed_value_map.len) continue;
941 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);
941 if (op_int < Air.ref_start_index) continue;
942 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
942943 self.processDeath(op_index);
943944 }
944945 const is_used = @truncate(u1, tomb_bits) == 0;
......@@ -1006,9 +1007,10 @@ fn allocMem(
10061007
10071008/// Use a pointer instruction as the basis for allocating stack memory.
10081009fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1010 const mod = self.bin_file.options.module.?;
10091011 const elem_ty = self.air.typeOfIndex(inst).elemType();
10101012
1011 if (!elem_ty.hasRuntimeBits()) {
1013 if (!elem_ty.hasRuntimeBits(mod)) {
10121014 // As this stack item will never be dereferenced at runtime,
10131015 // return the stack offset 0. Stack offset 0 will be where all
10141016 // zero-sized stack allocations live as non-zero-sized
......@@ -1016,22 +1018,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
10161018 return @as(u32, 0);
10171019 }
10181020
1019 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
1020 const mod = self.bin_file.options.module.?;
1021 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
10211022 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
10221023 };
10231024 // TODO swap this for inst.ty.ptrAlign
1024 const abi_align = elem_ty.abiAlignment(self.target.*);
1025 const abi_align = elem_ty.abiAlignment(mod);
10251026
10261027 return self.allocMem(abi_size, abi_align, inst);
10271028}
10281029
10291030fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {
1030 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
1031 const mod = self.bin_file.options.module.?;
1031 const mod = self.bin_file.options.module.?;
1032 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
10321033 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
10331034 };
1034 const abi_align = elem_ty.abiAlignment(self.target.*);
1035 const abi_align = elem_ty.abiAlignment(mod);
10351036
10361037 if (reg_ok) {
10371038 // Make sure the type can fit in a register before we try to allocate one.
......@@ -1158,10 +1159,11 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
11581159 const operand_ty = self.air.typeOf(ty_op.operand);
11591160 const dest_ty = self.air.typeOfIndex(inst);
11601161
1161 const operand_abi_size = operand_ty.abiSize(self.target.*);
1162 const dest_abi_size = dest_ty.abiSize(self.target.*);
1163 const info_a = operand_ty.intInfo(self.target.*);
1164 const info_b = dest_ty.intInfo(self.target.*);
1162 const mod = self.bin_file.options.module.?;
1163 const operand_abi_size = operand_ty.abiSize(mod);
1164 const dest_abi_size = dest_ty.abiSize(mod);
1165 const info_a = operand_ty.intInfo(mod);
1166 const info_b = dest_ty.intInfo(mod);
11651167
11661168 const dst_mcv: MCValue = blk: {
11671169 if (info_a.bits == info_b.bits) {
......@@ -1215,8 +1217,9 @@ fn trunc(
12151217 operand_ty: Type,
12161218 dest_ty: Type,
12171219) !MCValue {
1218 const info_a = operand_ty.intInfo(self.target.*);
1219 const info_b = dest_ty.intInfo(self.target.*);
1220 const mod = self.bin_file.options.module.?;
1221 const info_a = operand_ty.intInfo(mod);
1222 const info_b = dest_ty.intInfo(mod);
12201223
12211224 if (info_b.bits <= 32) {
12221225 if (info_a.bits > 32) {
......@@ -1278,6 +1281,7 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {
12781281
12791282fn airNot(self: *Self, inst: Air.Inst.Index) !void {
12801283 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1284 const mod = self.bin_file.options.module.?;
12811285 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
12821286 const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
12831287 const operand_ty = self.air.typeOf(ty_op.operand);
......@@ -1286,7 +1290,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
12861290 .unreach => unreachable,
12871291 .cpsr_flags => |cond| break :result MCValue{ .cpsr_flags = cond.negate() },
12881292 else => {
1289 switch (operand_ty.zigTypeTag()) {
1293 switch (operand_ty.zigTypeTag(mod)) {
12901294 .Bool => {
12911295 var op_reg: Register = undefined;
12921296 var dest_reg: Register = undefined;
......@@ -1319,7 +1323,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
13191323 },
13201324 .Vector => return self.fail("TODO bitwise not for vectors", .{}),
13211325 .Int => {
1322 const int_info = operand_ty.intInfo(self.target.*);
1326 const int_info = operand_ty.intInfo(mod);
13231327 if (int_info.bits <= 32) {
13241328 var op_reg: Register = undefined;
13251329 var dest_reg: Register = undefined;
......@@ -1373,13 +1377,13 @@ fn minMax(
13731377 rhs_ty: Type,
13741378 maybe_inst: ?Air.Inst.Index,
13751379) !MCValue {
1376 switch (lhs_ty.zigTypeTag()) {
1380 const mod = self.bin_file.options.module.?;
1381 switch (lhs_ty.zigTypeTag(mod)) {
13771382 .Float => return self.fail("TODO ARM min/max on floats", .{}),
13781383 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),
13791384 .Int => {
1380 const mod = self.bin_file.options.module.?;
13811385 assert(lhs_ty.eql(rhs_ty, mod));
1382 const int_info = lhs_ty.intInfo(self.target.*);
1386 const int_info = lhs_ty.intInfo(mod);
13831387 if (int_info.bits <= 32) {
13841388 var lhs_reg: Register = undefined;
13851389 var rhs_reg: Register = undefined;
......@@ -1582,6 +1586,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
15821586 const tag = self.air.instructions.items(.tag)[inst];
15831587 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
15841588 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1589 const mod = self.bin_file.options.module.?;
15851590 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
15861591 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
15871592 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
......@@ -1589,16 +1594,15 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
15891594 const rhs_ty = self.air.typeOf(extra.rhs);
15901595
15911596 const tuple_ty = self.air.typeOfIndex(inst);
1592 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));
1593 const tuple_align = tuple_ty.abiAlignment(self.target.*);
1594 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));
1597 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
1598 const tuple_align = tuple_ty.abiAlignment(mod);
1599 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
15951600
1596 switch (lhs_ty.zigTypeTag()) {
1601 switch (lhs_ty.zigTypeTag(mod)) {
15971602 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
15981603 .Int => {
1599 const mod = self.bin_file.options.module.?;
16001604 assert(lhs_ty.eql(rhs_ty, mod));
1601 const int_info = lhs_ty.intInfo(self.target.*);
1605 const int_info = lhs_ty.intInfo(mod);
16021606 if (int_info.bits < 32) {
16031607 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
16041608
......@@ -1695,6 +1699,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
16951699 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
16961700 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
16971701 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
1702 const mod = self.bin_file.options.module.?;
16981703 const result: MCValue = result: {
16991704 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
17001705 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
......@@ -1702,16 +1707,15 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
17021707 const rhs_ty = self.air.typeOf(extra.rhs);
17031708
17041709 const tuple_ty = self.air.typeOfIndex(inst);
1705 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));
1706 const tuple_align = tuple_ty.abiAlignment(self.target.*);
1707 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));
1710 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
1711 const tuple_align = tuple_ty.abiAlignment(mod);
1712 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
17081713
1709 switch (lhs_ty.zigTypeTag()) {
1714 switch (lhs_ty.zigTypeTag(mod)) {
17101715 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
17111716 .Int => {
1712 const mod = self.bin_file.options.module.?;
17131717 assert(lhs_ty.eql(rhs_ty, mod));
1714 const int_info = lhs_ty.intInfo(self.target.*);
1718 const int_info = lhs_ty.intInfo(mod);
17151719 if (int_info.bits <= 16) {
17161720 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
17171721
......@@ -1859,19 +1863,20 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
18591863 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
18601864 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
18611865 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
1866 const mod = self.bin_file.options.module.?;
18621867 const result: MCValue = result: {
18631868 const lhs_ty = self.air.typeOf(extra.lhs);
18641869 const rhs_ty = self.air.typeOf(extra.rhs);
18651870
18661871 const tuple_ty = self.air.typeOfIndex(inst);
1867 const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*));
1868 const tuple_align = tuple_ty.abiAlignment(self.target.*);
1869 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, self.target.*));
1872 const tuple_size = @intCast(u32, tuple_ty.abiSize(mod));
1873 const tuple_align = tuple_ty.abiAlignment(mod);
1874 const overflow_bit_offset = @intCast(u32, tuple_ty.structFieldOffset(1, mod));
18701875
1871 switch (lhs_ty.zigTypeTag()) {
1876 switch (lhs_ty.zigTypeTag(mod)) {
18721877 .Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),
18731878 .Int => {
1874 const int_info = lhs_ty.intInfo(self.target.*);
1879 const int_info = lhs_ty.intInfo(mod);
18751880 if (int_info.bits <= 32) {
18761881 const stack_offset = try self.allocMem(tuple_size, tuple_align, inst);
18771882
......@@ -2017,7 +2022,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
20172022 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
20182023 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
20192024 const optional_ty = self.air.typeOfIndex(inst);
2020 const abi_size = @intCast(u32, optional_ty.abiSize(self.target.*));
2025 const mod = self.bin_file.options.module.?;
2026 const abi_size = @intCast(u32, optional_ty.abiSize(mod));
20212027
20222028 // Optional with a zero-bit payload type is just a boolean true
20232029 if (abi_size == 1) {
......@@ -2036,16 +2042,17 @@ fn errUnionErr(
20362042 error_union_ty: Type,
20372043 maybe_inst: ?Air.Inst.Index,
20382044) !MCValue {
2045 const mod = self.bin_file.options.module.?;
20392046 const err_ty = error_union_ty.errorUnionSet();
20402047 const payload_ty = error_union_ty.errorUnionPayload();
20412048 if (err_ty.errorSetIsEmpty()) {
20422049 return MCValue{ .immediate = 0 };
20432050 }
2044 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
2051 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
20452052 return try error_union_bind.resolveToMcv(self);
20462053 }
20472054
2048 const err_offset = @intCast(u32, errUnionErrorOffset(payload_ty, self.target.*));
2055 const err_offset = @intCast(u32, errUnionErrorOffset(payload_ty, mod));
20492056 switch (try error_union_bind.resolveToMcv(self)) {
20502057 .register => {
20512058 var operand_reg: Register = undefined;
......@@ -2067,7 +2074,7 @@ fn errUnionErr(
20672074 );
20682075
20692076 const err_bit_offset = err_offset * 8;
2070 const err_bit_size = @intCast(u32, err_ty.abiSize(self.target.*)) * 8;
2077 const err_bit_size = @intCast(u32, err_ty.abiSize(mod)) * 8;
20712078
20722079 _ = try self.addInst(.{
20732080 .tag = .ubfx, // errors are unsigned integers
......@@ -2112,16 +2119,17 @@ fn errUnionPayload(
21122119 error_union_ty: Type,
21132120 maybe_inst: ?Air.Inst.Index,
21142121) !MCValue {
2122 const mod = self.bin_file.options.module.?;
21152123 const err_ty = error_union_ty.errorUnionSet();
21162124 const payload_ty = error_union_ty.errorUnionPayload();
21172125 if (err_ty.errorSetIsEmpty()) {
21182126 return try error_union_bind.resolveToMcv(self);
21192127 }
2120 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
2128 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
21212129 return MCValue.none;
21222130 }
21232131
2124 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target.*));
2132 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, mod));
21252133 switch (try error_union_bind.resolveToMcv(self)) {
21262134 .register => {
21272135 var operand_reg: Register = undefined;
......@@ -2143,10 +2151,10 @@ fn errUnionPayload(
21432151 );
21442152
21452153 const payload_bit_offset = payload_offset * 8;
2146 const payload_bit_size = @intCast(u32, payload_ty.abiSize(self.target.*)) * 8;
2154 const payload_bit_size = @intCast(u32, payload_ty.abiSize(mod)) * 8;
21472155
21482156 _ = try self.addInst(.{
2149 .tag = if (payload_ty.isSignedInt()) Mir.Inst.Tag.sbfx else .ubfx,
2157 .tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,
21502158 .data = .{ .rr_lsb_width = .{
21512159 .rd = dest_reg,
21522160 .rn = operand_reg,
......@@ -2221,19 +2229,20 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
22212229
22222230/// T to E!T
22232231fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
2232 const mod = self.bin_file.options.module.?;
22242233 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
22252234 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
22262235 const error_union_ty = self.air.getRefType(ty_op.ty);
22272236 const error_ty = error_union_ty.errorUnionSet();
22282237 const payload_ty = error_union_ty.errorUnionPayload();
22292238 const operand = try self.resolveInst(ty_op.operand);
2230 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result operand;
2239 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
22312240
2232 const abi_size = @intCast(u32, error_union_ty.abiSize(self.target.*));
2233 const abi_align = error_union_ty.abiAlignment(self.target.*);
2241 const abi_size = @intCast(u32, error_union_ty.abiSize(mod));
2242 const abi_align = error_union_ty.abiAlignment(mod);
22342243 const stack_offset = @intCast(u32, try self.allocMem(abi_size, abi_align, inst));
2235 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);
2236 const err_off = errUnionErrorOffset(payload_ty, self.target.*);
2244 const payload_off = errUnionPayloadOffset(payload_ty, mod);
2245 const err_off = errUnionErrorOffset(payload_ty, mod);
22372246 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), operand);
22382247 try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), .{ .immediate = 0 });
22392248
......@@ -2244,19 +2253,20 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
22442253
22452254/// E to E!T
22462255fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2256 const mod = self.bin_file.options.module.?;
22472257 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
22482258 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
22492259 const error_union_ty = self.air.getRefType(ty_op.ty);
22502260 const error_ty = error_union_ty.errorUnionSet();
22512261 const payload_ty = error_union_ty.errorUnionPayload();
22522262 const operand = try self.resolveInst(ty_op.operand);
2253 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result operand;
2263 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
22542264
2255 const abi_size = @intCast(u32, error_union_ty.abiSize(self.target.*));
2256 const abi_align = error_union_ty.abiAlignment(self.target.*);
2265 const abi_size = @intCast(u32, error_union_ty.abiSize(mod));
2266 const abi_align = error_union_ty.abiAlignment(mod);
22572267 const stack_offset = @intCast(u32, try self.allocMem(abi_size, abi_align, inst));
2258 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);
2259 const err_off = errUnionErrorOffset(payload_ty, self.target.*);
2268 const payload_off = errUnionPayloadOffset(payload_ty, mod);
2269 const err_off = errUnionErrorOffset(payload_ty, mod);
22602270 try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), operand);
22612271 try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), .undef);
22622272
......@@ -2361,7 +2371,8 @@ fn ptrElemVal(
23612371 maybe_inst: ?Air.Inst.Index,
23622372) !MCValue {
23632373 const elem_ty = ptr_ty.childType();
2364 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
2374 const mod = self.bin_file.options.module.?;
2375 const elem_size = @intCast(u32, elem_ty.abiSize(mod));
23652376
23662377 switch (elem_size) {
23672378 1, 4 => {
......@@ -2647,7 +2658,8 @@ fn reuseOperand(
26472658
26482659fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
26492660 const elem_ty = ptr_ty.elemType();
2650 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
2661 const mod = self.bin_file.options.module.?;
2662 const elem_size = @intCast(u32, elem_ty.abiSize(mod));
26512663
26522664 switch (ptr) {
26532665 .none => unreachable,
......@@ -2722,10 +2734,11 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
27222734}
27232735
27242736fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
2737 const mod = self.bin_file.options.module.?;
27252738 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27262739 const elem_ty = self.air.typeOfIndex(inst);
27272740 const result: MCValue = result: {
2728 if (!elem_ty.hasRuntimeBits())
2741 if (!elem_ty.hasRuntimeBits(mod))
27292742 break :result MCValue.none;
27302743
27312744 const ptr = try self.resolveInst(ty_op.operand);
......@@ -2734,7 +2747,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
27342747 break :result MCValue.dead;
27352748
27362749 const dest_mcv: MCValue = blk: {
2737 const ptr_fits_dest = elem_ty.abiSize(self.target.*) <= 4;
2750 const ptr_fits_dest = elem_ty.abiSize(mod) <= 4;
27382751 if (ptr_fits_dest and self.reuseOperand(inst, ty_op.operand, 0, ptr)) {
27392752 // The MCValue that holds the pointer can be re-used as the value.
27402753 break :blk ptr;
......@@ -2750,7 +2763,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
27502763}
27512764
27522765fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
2753 const elem_size = @intCast(u32, value_ty.abiSize(self.target.*));
2766 const mod = self.bin_file.options.module.?;
2767 const elem_size = @intCast(u32, value_ty.abiSize(mod));
27542768
27552769 switch (ptr) {
27562770 .none => unreachable,
......@@ -2869,10 +2883,11 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
28692883
28702884fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
28712885 return if (self.liveness.isUnused(inst)) .dead else result: {
2886 const mod = self.bin_file.options.module.?;
28722887 const mcv = try self.resolveInst(operand);
28732888 const ptr_ty = self.air.typeOf(operand);
28742889 const struct_ty = ptr_ty.childType();
2875 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
2890 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
28762891 switch (mcv) {
28772892 .ptr_stack_offset => |off| {
28782893 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
......@@ -2892,10 +2907,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
28922907 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
28932908 const operand = extra.struct_operand;
28942909 const index = extra.field_index;
2910 const mod = self.bin_file.options.module.?;
28952911 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
28962912 const mcv = try self.resolveInst(operand);
28972913 const struct_ty = self.air.typeOf(operand);
2898 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
2914 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
28992915 const struct_field_ty = struct_ty.structFieldType(index);
29002916
29012917 switch (mcv) {
......@@ -2959,10 +2975,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
29592975 );
29602976
29612977 const field_bit_offset = struct_field_offset * 8;
2962 const field_bit_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)) * 8;
2978 const field_bit_size = @intCast(u32, struct_field_ty.abiSize(mod)) * 8;
29632979
29642980 _ = try self.addInst(.{
2965 .tag = if (struct_field_ty.isSignedInt()) Mir.Inst.Tag.sbfx else .ubfx,
2981 .tag = if (struct_field_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,
29662982 .data = .{ .rr_lsb_width = .{
29672983 .rd = dest_reg,
29682984 .rn = operand_reg,
......@@ -2981,17 +2997,18 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
29812997}
29822998
29832999fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
3000 const mod = self.bin_file.options.module.?;
29843001 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
29853002 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
29863003 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
29873004 const field_ptr = try self.resolveInst(extra.field_ptr);
29883005 const struct_ty = self.air.getRefType(ty_pl.ty).childType();
29893006
2990 if (struct_ty.zigTypeTag() == .Union) {
3007 if (struct_ty.zigTypeTag(mod) == .Union) {
29913008 return self.fail("TODO implement @fieldParentPtr codegen for unions", .{});
29923009 }
29933010
2994 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(extra.field_index, self.target.*));
3011 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(extra.field_index, mod));
29953012 switch (field_ptr) {
29963013 .ptr_stack_offset => |off| {
29973014 break :result MCValue{ .ptr_stack_offset = off + struct_field_offset };
......@@ -3375,12 +3392,12 @@ fn addSub(
33753392 maybe_inst: ?Air.Inst.Index,
33763393) InnerError!MCValue {
33773394 const mod = self.bin_file.options.module.?;
3378 switch (lhs_ty.zigTypeTag()) {
3395 switch (lhs_ty.zigTypeTag(mod)) {
33793396 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
33803397 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
33813398 .Int => {
33823399 assert(lhs_ty.eql(rhs_ty, mod));
3383 const int_info = lhs_ty.intInfo(self.target.*);
3400 const int_info = lhs_ty.intInfo(mod);
33843401 if (int_info.bits <= 32) {
33853402 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
33863403 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
......@@ -3431,12 +3448,12 @@ fn mul(
34313448 maybe_inst: ?Air.Inst.Index,
34323449) InnerError!MCValue {
34333450 const mod = self.bin_file.options.module.?;
3434 switch (lhs_ty.zigTypeTag()) {
3451 switch (lhs_ty.zigTypeTag(mod)) {
34353452 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
34363453 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
34373454 .Int => {
34383455 assert(lhs_ty.eql(rhs_ty, mod));
3439 const int_info = lhs_ty.intInfo(self.target.*);
3456 const int_info = lhs_ty.intInfo(mod);
34403457 if (int_info.bits <= 32) {
34413458 // TODO add optimisations for multiplication
34423459 // with immediates, for example a * 2 can be
......@@ -3463,7 +3480,8 @@ fn divFloat(
34633480 _ = rhs_ty;
34643481 _ = maybe_inst;
34653482
3466 switch (lhs_ty.zigTypeTag()) {
3483 const mod = self.bin_file.options.module.?;
3484 switch (lhs_ty.zigTypeTag(mod)) {
34673485 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
34683486 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
34693487 else => unreachable,
......@@ -3479,12 +3497,12 @@ fn divTrunc(
34793497 maybe_inst: ?Air.Inst.Index,
34803498) InnerError!MCValue {
34813499 const mod = self.bin_file.options.module.?;
3482 switch (lhs_ty.zigTypeTag()) {
3500 switch (lhs_ty.zigTypeTag(mod)) {
34833501 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
34843502 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
34853503 .Int => {
34863504 assert(lhs_ty.eql(rhs_ty, mod));
3487 const int_info = lhs_ty.intInfo(self.target.*);
3505 const int_info = lhs_ty.intInfo(mod);
34883506 if (int_info.bits <= 32) {
34893507 switch (int_info.signedness) {
34903508 .signed => {
......@@ -3522,12 +3540,12 @@ fn divFloor(
35223540 maybe_inst: ?Air.Inst.Index,
35233541) InnerError!MCValue {
35243542 const mod = self.bin_file.options.module.?;
3525 switch (lhs_ty.zigTypeTag()) {
3543 switch (lhs_ty.zigTypeTag(mod)) {
35263544 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
35273545 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
35283546 .Int => {
35293547 assert(lhs_ty.eql(rhs_ty, mod));
3530 const int_info = lhs_ty.intInfo(self.target.*);
3548 const int_info = lhs_ty.intInfo(mod);
35313549 if (int_info.bits <= 32) {
35323550 switch (int_info.signedness) {
35333551 .signed => {
......@@ -3569,7 +3587,8 @@ fn divExact(
35693587 _ = rhs_ty;
35703588 _ = maybe_inst;
35713589
3572 switch (lhs_ty.zigTypeTag()) {
3590 const mod = self.bin_file.options.module.?;
3591 switch (lhs_ty.zigTypeTag(mod)) {
35733592 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
35743593 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
35753594 .Int => return self.fail("TODO ARM div_exact", .{}),
......@@ -3586,12 +3605,12 @@ fn rem(
35863605 maybe_inst: ?Air.Inst.Index,
35873606) InnerError!MCValue {
35883607 const mod = self.bin_file.options.module.?;
3589 switch (lhs_ty.zigTypeTag()) {
3608 switch (lhs_ty.zigTypeTag(mod)) {
35903609 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
35913610 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
35923611 .Int => {
35933612 assert(lhs_ty.eql(rhs_ty, mod));
3594 const int_info = lhs_ty.intInfo(self.target.*);
3613 const int_info = lhs_ty.intInfo(mod);
35953614 if (int_info.bits <= 32) {
35963615 switch (int_info.signedness) {
35973616 .signed => {
......@@ -3654,7 +3673,8 @@ fn modulo(
36543673 _ = rhs_ty;
36553674 _ = maybe_inst;
36563675
3657 switch (lhs_ty.zigTypeTag()) {
3676 const mod = self.bin_file.options.module.?;
3677 switch (lhs_ty.zigTypeTag(mod)) {
36583678 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
36593679 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
36603680 .Int => return self.fail("TODO ARM mod", .{}),
......@@ -3671,10 +3691,11 @@ fn wrappingArithmetic(
36713691 rhs_ty: Type,
36723692 maybe_inst: ?Air.Inst.Index,
36733693) InnerError!MCValue {
3674 switch (lhs_ty.zigTypeTag()) {
3694 const mod = self.bin_file.options.module.?;
3695 switch (lhs_ty.zigTypeTag(mod)) {
36753696 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
36763697 .Int => {
3677 const int_info = lhs_ty.intInfo(self.target.*);
3698 const int_info = lhs_ty.intInfo(mod);
36783699 if (int_info.bits <= 32) {
36793700 // Generate an add/sub/mul
36803701 const result: MCValue = switch (tag) {
......@@ -3708,12 +3729,12 @@ fn bitwise(
37083729 rhs_ty: Type,
37093730 maybe_inst: ?Air.Inst.Index,
37103731) InnerError!MCValue {
3711 switch (lhs_ty.zigTypeTag()) {
3732 const mod = self.bin_file.options.module.?;
3733 switch (lhs_ty.zigTypeTag(mod)) {
37123734 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
37133735 .Int => {
3714 const mod = self.bin_file.options.module.?;
37153736 assert(lhs_ty.eql(rhs_ty, mod));
3716 const int_info = lhs_ty.intInfo(self.target.*);
3737 const int_info = lhs_ty.intInfo(mod);
37173738 if (int_info.bits <= 32) {
37183739 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
37193740 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
......@@ -3753,16 +3774,17 @@ fn shiftExact(
37533774 rhs_ty: Type,
37543775 maybe_inst: ?Air.Inst.Index,
37553776) InnerError!MCValue {
3756 switch (lhs_ty.zigTypeTag()) {
3777 const mod = self.bin_file.options.module.?;
3778 switch (lhs_ty.zigTypeTag(mod)) {
37573779 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
37583780 .Int => {
3759 const int_info = lhs_ty.intInfo(self.target.*);
3781 const int_info = lhs_ty.intInfo(mod);
37603782 if (int_info.bits <= 32) {
37613783 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
37623784
37633785 const mir_tag: Mir.Inst.Tag = switch (tag) {
37643786 .shl_exact => .lsl,
3765 .shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) {
3787 .shr_exact => switch (lhs_ty.intInfo(mod).signedness) {
37663788 .signed => Mir.Inst.Tag.asr,
37673789 .unsigned => Mir.Inst.Tag.lsr,
37683790 },
......@@ -3791,10 +3813,11 @@ fn shiftNormal(
37913813 rhs_ty: Type,
37923814 maybe_inst: ?Air.Inst.Index,
37933815) InnerError!MCValue {
3794 switch (lhs_ty.zigTypeTag()) {
3816 const mod = self.bin_file.options.module.?;
3817 switch (lhs_ty.zigTypeTag(mod)) {
37953818 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
37963819 .Int => {
3797 const int_info = lhs_ty.intInfo(self.target.*);
3820 const int_info = lhs_ty.intInfo(mod);
37983821 if (int_info.bits <= 32) {
37993822 // Generate a shl_exact/shr_exact
38003823 const result: MCValue = switch (tag) {
......@@ -3833,7 +3856,8 @@ fn booleanOp(
38333856 rhs_ty: Type,
38343857 maybe_inst: ?Air.Inst.Index,
38353858) InnerError!MCValue {
3836 switch (lhs_ty.zigTypeTag()) {
3859 const mod = self.bin_file.options.module.?;
3860 switch (lhs_ty.zigTypeTag(mod)) {
38373861 .Bool => {
38383862 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
38393863 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
......@@ -3866,9 +3890,9 @@ fn ptrArithmetic(
38663890 rhs_ty: Type,
38673891 maybe_inst: ?Air.Inst.Index,
38683892) InnerError!MCValue {
3869 switch (lhs_ty.zigTypeTag()) {
3893 const mod = self.bin_file.options.module.?;
3894 switch (lhs_ty.zigTypeTag(mod)) {
38703895 .Pointer => {
3871 const mod = self.bin_file.options.module.?;
38723896 assert(rhs_ty.eql(Type.usize, mod));
38733897
38743898 const ptr_ty = lhs_ty;
......@@ -3876,7 +3900,7 @@ fn ptrArithmetic(
38763900 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type
38773901 else => ptr_ty.childType(),
38783902 };
3879 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
3903 const elem_size = @intCast(u32, elem_ty.abiSize(mod));
38803904
38813905 const base_tag: Air.Inst.Tag = switch (tag) {
38823906 .ptr_add => .add,
......@@ -3903,11 +3927,12 @@ fn ptrArithmetic(
39033927}
39043928
39053929fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) !void {
3906 const abi_size = ty.abiSize(self.target.*);
3930 const mod = self.bin_file.options.module.?;
3931 const abi_size = ty.abiSize(mod);
39073932
39083933 const tag: Mir.Inst.Tag = switch (abi_size) {
3909 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb else .ldrb,
3910 2 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsh else .ldrh,
3934 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb,
3935 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh else .ldrh,
39113936 3, 4 => .ldr,
39123937 else => unreachable,
39133938 };
......@@ -3924,7 +3949,7 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type)
39243949 } };
39253950
39263951 const data: Mir.Inst.Data = switch (abi_size) {
3927 1 => if (ty.isSignedInt()) rr_extra_offset else rr_offset,
3952 1 => if (ty.isSignedInt(mod)) rr_extra_offset else rr_offset,
39283953 2 => rr_extra_offset,
39293954 3, 4 => rr_offset,
39303955 else => unreachable,
......@@ -3937,7 +3962,8 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type)
39373962}
39383963
39393964fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Type) !void {
3940 const abi_size = ty.abiSize(self.target.*);
3965 const mod = self.bin_file.options.module.?;
3966 const abi_size = ty.abiSize(mod);
39413967
39423968 const tag: Mir.Inst.Tag = switch (abi_size) {
39433969 1 => .strb,
......@@ -4197,8 +4223,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
41974223 const extra = self.air.extraData(Air.Call, pl_op.payload);
41984224 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
41994225 const ty = self.air.typeOf(callee);
4226 const mod = self.bin_file.options.module.?;
42004227
4201 const fn_ty = switch (ty.zigTypeTag()) {
4228 const fn_ty = switch (ty.zigTypeTag(mod)) {
42024229 .Fn => ty,
42034230 .Pointer => ty.childType(),
42044231 else => unreachable,
......@@ -4226,8 +4253,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42264253 const r0_lock: ?RegisterLock = if (info.return_value == .stack_offset) blk: {
42274254 log.debug("airCall: return by reference", .{});
42284255 const ret_ty = fn_ty.fnReturnType();
4229 const ret_abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));
4230 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(self.target.*));
4256 const ret_abi_size = @intCast(u32, ret_ty.abiSize(mod));
4257 const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(mod));
42314258 const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);
42324259
42334260 var ptr_ty_payload: Type.Payload.ElemType = .{
......@@ -4270,7 +4297,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42704297
42714298 // Due to incremental compilation, how function calls are generated depends
42724299 // on linking.
4273 if (self.air.value(callee)) |func_value| {
4300 if (self.air.value(callee, mod)) |func_value| {
42744301 if (func_value.castTag(.function)) |func_payload| {
42754302 const func = func_payload.data;
42764303
......@@ -4294,7 +4321,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42944321 return self.fail("TODO implement calling bitcasted functions", .{});
42954322 }
42964323 } else {
4297 assert(ty.zigTypeTag() == .Pointer);
4324 assert(ty.zigTypeTag(mod) == .Pointer);
42984325 const mcv = try self.resolveInst(callee);
42994326
43004327 try self.genSetReg(Type.initTag(.usize), .lr, mcv);
......@@ -4356,11 +4383,12 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
43564383 const un_op = self.air.instructions.items(.data)[inst].un_op;
43574384 const operand = try self.resolveInst(un_op);
43584385 const ret_ty = self.fn_type.fnReturnType();
4386 const mod = self.bin_file.options.module.?;
43594387
43604388 switch (self.ret_mcv) {
43614389 .none => {},
43624390 .immediate => {
4363 assert(ret_ty.isError());
4391 assert(ret_ty.isError(mod));
43644392 },
43654393 .register => |reg| {
43664394 // Return result by value
......@@ -4411,8 +4439,9 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
44114439 // location.
44124440 const op_inst = Air.refToIndex(un_op).?;
44134441 if (self.air.instructions.items(.tag)[op_inst] != .ret_ptr) {
4414 const abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));
4415 const abi_align = ret_ty.abiAlignment(self.target.*);
4442 const mod = self.bin_file.options.module.?;
4443 const abi_size = @intCast(u32, ret_ty.abiSize(mod));
4444 const abi_align = ret_ty.abiAlignment(mod);
44164445
44174446 const offset = try self.allocMem(abi_size, abi_align, null);
44184447
......@@ -4448,21 +4477,21 @@ fn cmp(
44484477 lhs_ty: Type,
44494478 op: math.CompareOperator,
44504479) !MCValue {
4451 var int_buffer: Type.Payload.Bits = undefined;
4452 const int_ty = switch (lhs_ty.zigTypeTag()) {
4480 const mod = self.bin_file.options.module.?;
4481 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
44534482 .Optional => blk: {
44544483 var opt_buffer: Type.Payload.ElemType = undefined;
44554484 const payload_ty = lhs_ty.optionalChild(&opt_buffer);
4456 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
4485 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
44574486 break :blk Type.initTag(.u1);
4458 } else if (lhs_ty.isPtrLikeOptional()) {
4487 } else if (lhs_ty.isPtrLikeOptional(mod)) {
44594488 break :blk Type.usize;
44604489 } else {
44614490 return self.fail("TODO ARM cmp non-pointer optionals", .{});
44624491 }
44634492 },
44644493 .Float => return self.fail("TODO ARM cmp floats", .{}),
4465 .Enum => lhs_ty.intTagType(&int_buffer),
4494 .Enum => lhs_ty.intTagType(),
44664495 .Int => lhs_ty,
44674496 .Bool => Type.initTag(.u1),
44684497 .Pointer => Type.usize,
......@@ -4470,7 +4499,7 @@ fn cmp(
44704499 else => unreachable,
44714500 };
44724501
4473 const int_info = int_ty.intInfo(self.target.*);
4502 const int_info = int_ty.intInfo(mod);
44744503 if (int_info.bits <= 32) {
44754504 try self.spillCompareFlagsIfOccupied();
44764505
......@@ -4636,8 +4665,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
46364665 // whether it needs to be spilled in the branches
46374666 if (self.liveness.operandDies(inst, 0)) {
46384667 const op_int = @enumToInt(pl_op.operand);
4639 if (op_int >= Air.Inst.Ref.typed_value_map.len) {
4640 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);
4668 if (op_int >= Air.ref_start_index) {
4669 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
46414670 self.processDeath(op_index);
46424671 }
46434672 }
......@@ -4772,8 +4801,9 @@ fn isNull(
47724801 operand_bind: ReadArg.Bind,
47734802 operand_ty: Type,
47744803) !MCValue {
4775 if (operand_ty.isPtrLikeOptional()) {
4776 assert(operand_ty.abiSize(self.target.*) == 4);
4804 const mod = self.bin_file.options.module.?;
4805 if (operand_ty.isPtrLikeOptional(mod)) {
4806 assert(operand_ty.abiSize(mod) == 4);
47774807
47784808 const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } };
47794809 return self.cmp(operand_bind, imm_bind, Type.usize, .eq);
......@@ -5131,9 +5161,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
51315161}
51325162
51335163fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5164 const mod = self.bin_file.options.module.?;
51345165 const block_data = self.blocks.getPtr(block).?;
51355166
5136 if (self.air.typeOf(operand).hasRuntimeBits()) {
5167 if (self.air.typeOf(operand).hasRuntimeBits(mod)) {
51375168 const operand_mcv = try self.resolveInst(operand);
51385169 const block_mcv = block_data.mcv;
51395170 if (block_mcv == .none) {
......@@ -5301,7 +5332,8 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
53015332}
53025333
53035334fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5304 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
5335 const mod = self.bin_file.options.module.?;
5336 const abi_size = @intCast(u32, ty.abiSize(mod));
53055337 switch (mcv) {
53065338 .dead => unreachable,
53075339 .unreach, .none => return, // Nothing to do.
......@@ -5382,7 +5414,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
53825414 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg });
53835415
53845416 const overflow_bit_ty = ty.structFieldType(1);
5385 const overflow_bit_offset = @intCast(u32, ty.structFieldOffset(1, self.target.*));
5417 const overflow_bit_offset = @intCast(u32, ty.structFieldOffset(1, mod));
53865418 const cond_reg = try self.register_manager.allocReg(null, gp);
53875419
53885420 // C flag: movcs reg, #1
......@@ -5466,6 +5498,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
54665498}
54675499
54685500fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
5501 const mod = self.bin_file.options.module.?;
54695502 switch (mcv) {
54705503 .dead => unreachable,
54715504 .unreach, .none => return, // Nothing to do.
......@@ -5640,17 +5673,17 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
56405673 },
56415674 .stack_offset => |off| {
56425675 // TODO: maybe addressing from sp instead of fp
5643 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
5676 const abi_size = @intCast(u32, ty.abiSize(mod));
56445677
56455678 const tag: Mir.Inst.Tag = switch (abi_size) {
5646 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb else .ldrb,
5647 2 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsh else .ldrh,
5679 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb,
5680 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh else .ldrh,
56485681 3, 4 => .ldr,
56495682 else => unreachable,
56505683 };
56515684
56525685 const extra_offset = switch (abi_size) {
5653 1 => ty.isSignedInt(),
5686 1 => ty.isSignedInt(mod),
56545687 2 => true,
56555688 3, 4 => false,
56565689 else => unreachable,
......@@ -5691,11 +5724,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
56915724 }
56925725 },
56935726 .stack_argument_offset => |off| {
5694 const abi_size = ty.abiSize(self.target.*);
5727 const abi_size = ty.abiSize(mod);
56955728
56965729 const tag: Mir.Inst.Tag = switch (abi_size) {
5697 1 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,
5698 2 => if (ty.isSignedInt()) Mir.Inst.Tag.ldrsh_stack_argument else .ldrh_stack_argument,
5730 1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,
5731 2 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsh_stack_argument else .ldrh_stack_argument,
56995732 3, 4 => .ldr_stack_argument,
57005733 else => unreachable,
57015734 };
......@@ -5712,7 +5745,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
57125745}
57135746
57145747fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5715 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
5748 const mod = self.bin_file.options.module.?;
5749 const abi_size = @intCast(u32, ty.abiSize(mod));
57165750 switch (mcv) {
57175751 .dead => unreachable,
57185752 .none, .unreach => return,
......@@ -6039,8 +6073,9 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
60396073 const result: MCValue = result: {
60406074 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
60416075 const error_union_ty = self.air.typeOf(pl_op.operand);
6042 const error_union_size = @intCast(u32, error_union_ty.abiSize(self.target.*));
6043 const error_union_align = error_union_ty.abiAlignment(self.target.*);
6076 const mod = self.bin_file.options.module.?;
6077 const error_union_size = @intCast(u32, error_union_ty.abiSize(mod));
6078 const error_union_align = error_union_ty.abiAlignment(mod);
60446079
60456080 // The error union will die in the body. However, we need the
60466081 // error union after the body in order to extract the payload
......@@ -6069,22 +6104,18 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
60696104}
60706105
60716106fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
6072 // First section of indexes correspond to a set number of constant values.
6073 const ref_int = @enumToInt(inst);
6074 if (ref_int < Air.Inst.Ref.typed_value_map.len) {
6075 const tv = Air.Inst.Ref.typed_value_map[ref_int];
6076 if (!tv.ty.hasRuntimeBitsIgnoreComptime() and !tv.ty.isError()) {
6077 return MCValue{ .none = {} };
6078 }
6079 return self.genTypedValue(tv);
6080 }
6107 const mod = self.bin_file.options.module.?;
60816108
60826109 // If the type has no codegen bits, no need to store it.
60836110 const inst_ty = self.air.typeOf(inst);
6084 if (!inst_ty.hasRuntimeBitsIgnoreComptime() and !inst_ty.isError())
6111 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))
60856112 return MCValue{ .none = {} };
60866113
6087 const inst_index = @intCast(Air.Inst.Index, ref_int - Air.Inst.Ref.typed_value_map.len);
6114 const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{
6115 .ty = inst_ty,
6116 .val = self.air.value(inst, mod).?,
6117 });
6118
60886119 switch (self.air.instructions.items(.tag)[inst_index]) {
60896120 .constant => {
60906121 // Constants have static lifetimes, so they are always memoized in the outer most table.
......@@ -6166,6 +6197,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
61666197 errdefer self.gpa.free(result.args);
61676198
61686199 const ret_ty = fn_ty.fnReturnType();
6200 const mod = self.bin_file.options.module.?;
61696201
61706202 switch (cc) {
61716203 .Naked => {
......@@ -6180,12 +6212,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
61806212 var ncrn: usize = 0; // Next Core Register Number
61816213 var nsaa: u32 = 0; // Next stacked argument address
61826214
6183 if (ret_ty.zigTypeTag() == .NoReturn) {
6215 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
61846216 result.return_value = .{ .unreach = {} };
6185 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {
6217 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
61866218 result.return_value = .{ .none = {} };
61876219 } else {
6188 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));
6220 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
61896221 // TODO handle cases where multiple registers are used
61906222 if (ret_ty_size <= 4) {
61916223 result.return_value = .{ .register = c_abi_int_return_regs[0] };
......@@ -6200,10 +6232,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62006232 }
62016233
62026234 for (param_types, 0..) |ty, i| {
6203 if (ty.abiAlignment(self.target.*) == 8)
6235 if (ty.abiAlignment(mod) == 8)
62046236 ncrn = std.mem.alignForwardGeneric(usize, ncrn, 2);
62056237
6206 const param_size = @intCast(u32, ty.abiSize(self.target.*));
6238 const param_size = @intCast(u32, ty.abiSize(mod));
62076239 if (std.math.divCeil(u32, param_size, 4) catch unreachable <= 4 - ncrn) {
62086240 if (param_size <= 4) {
62096241 result.args[i] = .{ .register = c_abi_int_param_regs[ncrn] };
......@@ -6215,7 +6247,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62156247 return self.fail("TODO MCValues split between registers and stack", .{});
62166248 } else {
62176249 ncrn = 4;
6218 if (ty.abiAlignment(self.target.*) == 8)
6250 if (ty.abiAlignment(mod) == 8)
62196251 nsaa = std.mem.alignForwardGeneric(u32, nsaa, 8);
62206252
62216253 result.args[i] = .{ .stack_argument_offset = nsaa };
......@@ -6227,14 +6259,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62276259 result.stack_align = 8;
62286260 },
62296261 .Unspecified => {
6230 if (ret_ty.zigTypeTag() == .NoReturn) {
6262 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
62316263 result.return_value = .{ .unreach = {} };
6232 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime() and !ret_ty.isError()) {
6264 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {
62336265 result.return_value = .{ .none = {} };
62346266 } else {
6235 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));
6267 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
62366268 if (ret_ty_size == 0) {
6237 assert(ret_ty.isError());
6269 assert(ret_ty.isError(mod));
62386270 result.return_value = .{ .immediate = 0 };
62396271 } else if (ret_ty_size <= 4) {
62406272 result.return_value = .{ .register = .r0 };
......@@ -6250,9 +6282,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62506282 var stack_offset: u32 = 0;
62516283
62526284 for (param_types, 0..) |ty, i| {
6253 if (ty.abiSize(self.target.*) > 0) {
6254 const param_size = @intCast(u32, ty.abiSize(self.target.*));
6255 const param_alignment = ty.abiAlignment(self.target.*);
6285 if (ty.abiSize(mod) > 0) {
6286 const param_size = @intCast(u32, ty.abiSize(mod));
6287 const param_alignment = ty.abiAlignment(mod);
62566288
62576289 stack_offset = std.mem.alignForwardGeneric(u32, stack_offset, param_alignment);
62586290 result.args[i] = .{ .stack_argument_offset = stack_offset };
src/arch/arm/abi.zig+22-19
......@@ -1,8 +1,10 @@
11const std = @import("std");
2const assert = std.debug.assert;
23const bits = @import("bits.zig");
34const Register = bits.Register;
45const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
56const Type = @import("../../type.zig").Type;
7const Module = @import("../../Module.zig");
68
79pub const Class = union(enum) {
810 memory,
......@@ -22,28 +24,28 @@ pub const Class = union(enum) {
2224
2325pub const Context = enum { ret, arg };
2426
25pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {
26 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime());
27pub fn classifyType(ty: Type, mod: *const Module, ctx: Context) Class {
28 assert(ty.hasRuntimeBitsIgnoreComptime(mod));
2729
2830 var maybe_float_bits: ?u16 = null;
2931 const max_byval_size = 512;
30 switch (ty.zigTypeTag()) {
32 switch (ty.zigTypeTag(mod)) {
3133 .Struct => {
32 const bit_size = ty.bitSize(target);
34 const bit_size = ty.bitSize(mod);
3335 if (ty.containerLayout() == .Packed) {
3436 if (bit_size > 64) return .memory;
3537 return .byval;
3638 }
3739 if (bit_size > max_byval_size) return .memory;
38 const float_count = countFloats(ty, target, &maybe_float_bits);
40 const float_count = countFloats(ty, mod, &maybe_float_bits);
3941 if (float_count <= byval_float_count) return .byval;
4042
4143 const fields = ty.structFieldCount();
4244 var i: u32 = 0;
4345 while (i < fields) : (i += 1) {
4446 const field_ty = ty.structFieldType(i);
45 const field_alignment = ty.structFieldAlign(i, target);
46 const field_size = field_ty.bitSize(target);
47 const field_alignment = ty.structFieldAlign(i, mod);
48 const field_size = field_ty.bitSize(mod);
4749 if (field_size > 32 or field_alignment > 32) {
4850 return Class.arrSize(bit_size, 64);
4951 }
......@@ -51,17 +53,17 @@ pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {
5153 return Class.arrSize(bit_size, 32);
5254 },
5355 .Union => {
54 const bit_size = ty.bitSize(target);
56 const bit_size = ty.bitSize(mod);
5557 if (ty.containerLayout() == .Packed) {
5658 if (bit_size > 64) return .memory;
5759 return .byval;
5860 }
5961 if (bit_size > max_byval_size) return .memory;
60 const float_count = countFloats(ty, target, &maybe_float_bits);
62 const float_count = countFloats(ty, mod, &maybe_float_bits);
6163 if (float_count <= byval_float_count) return .byval;
6264
6365 for (ty.unionFields().values()) |field| {
64 if (field.ty.bitSize(target) > 32 or field.normalAlignment(target) > 32) {
66 if (field.ty.bitSize(mod) > 32 or field.normalAlignment(mod) > 32) {
6567 return Class.arrSize(bit_size, 64);
6668 }
6769 }
......@@ -71,28 +73,28 @@ pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {
7173 .Int => {
7274 // TODO this is incorrect for _BitInt(128) but implementing
7375 // this correctly makes implementing compiler-rt impossible.
74 // const bit_size = ty.bitSize(target);
76 // const bit_size = ty.bitSize(mod);
7577 // if (bit_size > 64) return .memory;
7678 return .byval;
7779 },
7880 .Enum, .ErrorSet => {
79 const bit_size = ty.bitSize(target);
81 const bit_size = ty.bitSize(mod);
8082 if (bit_size > 64) return .memory;
8183 return .byval;
8284 },
8385 .Vector => {
84 const bit_size = ty.bitSize(target);
86 const bit_size = ty.bitSize(mod);
8587 // TODO is this controlled by a cpu feature?
8688 if (ctx == .ret and bit_size > 128) return .memory;
8789 if (bit_size > 512) return .memory;
8890 return .byval;
8991 },
9092 .Optional => {
91 std.debug.assert(ty.isPtrLikeOptional());
93 assert(ty.isPtrLikeOptional(mod));
9294 return .byval;
9395 },
9496 .Pointer => {
95 std.debug.assert(!ty.isSlice());
97 assert(!ty.isSlice());
9698 return .byval;
9799 },
98100 .ErrorUnion,
......@@ -114,14 +116,15 @@ pub fn classifyType(ty: Type, target: std.Target, ctx: Context) Class {
114116}
115117
116118const byval_float_count = 4;
117fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u32 {
119fn countFloats(ty: Type, mod: *const Module, maybe_float_bits: *?u16) u32 {
120 const target = mod.getTarget();
118121 const invalid = std.math.maxInt(u32);
119 switch (ty.zigTypeTag()) {
122 switch (ty.zigTypeTag(mod)) {
120123 .Union => {
121124 const fields = ty.unionFields();
122125 var max_count: u32 = 0;
123126 for (fields.values()) |field| {
124 const field_count = countFloats(field.ty, target, maybe_float_bits);
127 const field_count = countFloats(field.ty, mod, maybe_float_bits);
125128 if (field_count == invalid) return invalid;
126129 if (field_count > max_count) max_count = field_count;
127130 if (max_count > byval_float_count) return invalid;
......@@ -134,7 +137,7 @@ fn countFloats(ty: Type, target: std.Target, maybe_float_bits: *?u16) u32 {
134137 var i: u32 = 0;
135138 while (i < fields_len) : (i += 1) {
136139 const field_ty = ty.structFieldType(i);
137 const field_count = countFloats(field_ty, target, maybe_float_bits);
140 const field_count = countFloats(field_ty, mod, maybe_float_bits);
138141 if (field_count == invalid) return invalid;
139142 count += field_count;
140143 if (count > byval_float_count) return invalid;
src/arch/riscv64/CodeGen.zig+37-35
......@@ -755,8 +755,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
755755 tomb_bits >>= 1;
756756 if (!dies) continue;
757757 const op_int = @enumToInt(op);
758 if (op_int < Air.Inst.Ref.typed_value_map.len) continue;
759 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);
758 if (op_int < Air.ref_start_index) continue;
759 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
760760 self.processDeath(op_index);
761761 }
762762 const is_used = @truncate(u1, tomb_bits) == 0;
......@@ -805,22 +805,22 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
805805/// Use a pointer instruction as the basis for allocating stack memory.
806806fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
807807 const elem_ty = self.air.typeOfIndex(inst).elemType();
808 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
809 const mod = self.bin_file.options.module.?;
808 const mod = self.bin_file.options.module.?;
809 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
810810 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
811811 };
812812 // TODO swap this for inst.ty.ptrAlign
813 const abi_align = elem_ty.abiAlignment(self.target.*);
813 const abi_align = elem_ty.abiAlignment(mod);
814814 return self.allocMem(inst, abi_size, abi_align);
815815}
816816
817817fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
818818 const elem_ty = self.air.typeOfIndex(inst);
819 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
820 const mod = self.bin_file.options.module.?;
819 const mod = self.bin_file.options.module.?;
820 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
821821 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
822822 };
823 const abi_align = elem_ty.abiAlignment(self.target.*);
823 const abi_align = elem_ty.abiAlignment(mod);
824824 if (abi_align > self.stack_align)
825825 self.stack_align = abi_align;
826826
......@@ -893,10 +893,11 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
893893 if (self.liveness.isUnused(inst))
894894 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
895895
896 const mod = self.bin_file.options.module.?;
896897 const operand_ty = self.air.typeOf(ty_op.operand);
897898 const operand = try self.resolveInst(ty_op.operand);
898 const info_a = operand_ty.intInfo(self.target.*);
899 const info_b = self.air.typeOfIndex(inst).intInfo(self.target.*);
899 const info_a = operand_ty.intInfo(mod);
900 const info_b = self.air.typeOfIndex(inst).intInfo(mod);
900901 if (info_a.signedness != info_b.signedness)
901902 return self.fail("TODO gen intcast sign safety in semantic analysis", .{});
902903
......@@ -1068,18 +1069,18 @@ fn binOp(
10681069 lhs_ty: Type,
10691070 rhs_ty: Type,
10701071) InnerError!MCValue {
1072 const mod = self.bin_file.options.module.?;
10711073 switch (tag) {
10721074 // Arithmetic operations on integers and floats
10731075 .add,
10741076 .sub,
10751077 => {
1076 switch (lhs_ty.zigTypeTag()) {
1078 switch (lhs_ty.zigTypeTag(mod)) {
10771079 .Float => return self.fail("TODO binary operations on floats", .{}),
10781080 .Vector => return self.fail("TODO binary operations on vectors", .{}),
10791081 .Int => {
1080 const mod = self.bin_file.options.module.?;
10811082 assert(lhs_ty.eql(rhs_ty, mod));
1082 const int_info = lhs_ty.intInfo(self.target.*);
1083 const int_info = lhs_ty.intInfo(mod);
10831084 if (int_info.bits <= 64) {
10841085 // TODO immediate operands
10851086 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
......@@ -1093,14 +1094,14 @@ fn binOp(
10931094 .ptr_add,
10941095 .ptr_sub,
10951096 => {
1096 switch (lhs_ty.zigTypeTag()) {
1097 switch (lhs_ty.zigTypeTag(mod)) {
10971098 .Pointer => {
10981099 const ptr_ty = lhs_ty;
10991100 const elem_ty = switch (ptr_ty.ptrSize()) {
11001101 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type
11011102 else => ptr_ty.childType(),
11021103 };
1103 const elem_size = elem_ty.abiSize(self.target.*);
1104 const elem_size = elem_ty.abiSize(mod);
11041105
11051106 if (elem_size == 1) {
11061107 const base_tag: Air.Inst.Tag = switch (tag) {
......@@ -1331,10 +1332,11 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
13311332fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
13321333 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
13331334 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1335 const mod = self.bin_file.options.module.?;
13341336 const optional_ty = self.air.typeOfIndex(inst);
13351337
13361338 // Optional with a zero-bit payload type is just a boolean true
1337 if (optional_ty.abiSize(self.target.*) == 1)
1339 if (optional_ty.abiSize(mod) == 1)
13381340 break :result MCValue{ .immediate = 1 };
13391341
13401342 return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch});
......@@ -1526,7 +1528,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
15261528 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
15271529 const elem_ty = self.air.typeOfIndex(inst);
15281530 const result: MCValue = result: {
1529 if (!elem_ty.hasRuntimeBits())
1531 const mod = self.bin_file.options.module.?;
1532 if (!elem_ty.hasRuntimeBits(mod))
15301533 break :result MCValue.none;
15311534
15321535 const ptr = try self.resolveInst(ty_op.operand);
......@@ -1698,6 +1701,7 @@ fn airFence(self: *Self) !void {
16981701}
16991702
17001703fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
1704 const mod = self.bin_file.options.module.?;
17011705 if (modifier == .always_tail) return self.fail("TODO implement tail calls for riscv64", .{});
17021706 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
17031707 const fn_ty = self.air.typeOf(pl_op.operand);
......@@ -1736,7 +1740,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
17361740 }
17371741 }
17381742
1739 if (self.air.value(callee)) |func_value| {
1743 if (self.air.value(callee, mod)) |func_value| {
17401744 if (func_value.castTag(.function)) |func_payload| {
17411745 const func = func_payload.data;
17421746 const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
......@@ -1828,7 +1832,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
18281832 const ty = self.air.typeOf(bin_op.lhs);
18291833 const mod = self.bin_file.options.module.?;
18301834 assert(ty.eql(self.air.typeOf(bin_op.rhs), mod));
1831 if (ty.zigTypeTag() == .ErrorSet)
1835 if (ty.zigTypeTag(mod) == .ErrorSet)
18321836 return self.fail("TODO implement cmp for errors", .{});
18331837
18341838 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -2107,7 +2111,8 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
21072111fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
21082112 const block_data = self.blocks.getPtr(block).?;
21092113
2110 if (self.air.typeOf(operand).hasRuntimeBits()) {
2114 const mod = self.bin_file.options.module.?;
2115 if (self.air.typeOf(operand).hasRuntimeBits(mod)) {
21112116 const operand_mcv = try self.resolveInst(operand);
21122117 const block_mcv = block_data.mcv;
21132118 if (block_mcv == .none) {
......@@ -2533,22 +2538,18 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
25332538}
25342539
25352540fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
2536 // First section of indexes correspond to a set number of constant values.
2537 const ref_int = @enumToInt(inst);
2538 if (ref_int < Air.Inst.Ref.typed_value_map.len) {
2539 const tv = Air.Inst.Ref.typed_value_map[ref_int];
2540 if (!tv.ty.hasRuntimeBits()) {
2541 return MCValue{ .none = {} };
2542 }
2543 return self.genTypedValue(tv);
2544 }
2541 const mod = self.bin_file.options.module.?;
25452542
25462543 // If the type has no codegen bits, no need to store it.
25472544 const inst_ty = self.air.typeOf(inst);
2548 if (!inst_ty.hasRuntimeBits())
2545 if (!inst_ty.hasRuntimeBits(mod))
25492546 return MCValue{ .none = {} };
25502547
2551 const inst_index = @intCast(Air.Inst.Index, ref_int - Air.Inst.Ref.typed_value_map.len);
2548 const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{
2549 .ty = inst_ty,
2550 .val = self.air.value(inst, mod).?,
2551 });
2552
25522553 switch (self.air.instructions.items(.tag)[inst_index]) {
25532554 .constant => {
25542555 // Constants have static lifetimes, so they are always memoized in the outer most table.
......@@ -2630,6 +2631,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
26302631 errdefer self.gpa.free(result.args);
26312632
26322633 const ret_ty = fn_ty.fnReturnType();
2634 const mod = self.bin_file.options.module.?;
26332635
26342636 switch (cc) {
26352637 .Naked => {
......@@ -2650,7 +2652,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
26502652 const argument_registers = [_]Register{ .a0, .a1, .a2, .a3, .a4, .a5, .a6, .a7 };
26512653
26522654 for (param_types, 0..) |ty, i| {
2653 const param_size = @intCast(u32, ty.abiSize(self.target.*));
2655 const param_size = @intCast(u32, ty.abiSize(mod));
26542656 if (param_size <= 8) {
26552657 if (next_register < argument_registers.len) {
26562658 result.args[i] = .{ .register = argument_registers[next_register] };
......@@ -2680,14 +2682,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
26802682 else => return self.fail("TODO implement function parameters for {} on riscv64", .{cc}),
26812683 }
26822684
2683 if (ret_ty.zigTypeTag() == .NoReturn) {
2685 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
26842686 result.return_value = .{ .unreach = {} };
2685 } else if (!ret_ty.hasRuntimeBits()) {
2687 } else if (!ret_ty.hasRuntimeBits(mod)) {
26862688 result.return_value = .{ .none = {} };
26872689 } else switch (cc) {
26882690 .Naked => unreachable,
26892691 .Unspecified, .C => {
2690 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));
2692 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
26912693 if (ret_ty_size <= 8) {
26922694 result.return_value = .{ .register = .a0 };
26932695 } else if (ret_ty_size <= 16) {
src/arch/riscv64/abi.zig+10-8
......@@ -3,16 +3,18 @@ const bits = @import("bits.zig");
33const Register = bits.Register;
44const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
55const Type = @import("../../type.zig").Type;
6const Module = @import("../../Module.zig");
67
78pub const Class = enum { memory, byval, integer, double_integer };
89
9pub fn classifyType(ty: Type, target: std.Target) Class {
10 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime());
10pub fn classifyType(ty: Type, mod: *const Module) Class {
11 const target = mod.getTarget();
12 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(mod));
1113
1214 const max_byval_size = target.ptrBitWidth() * 2;
13 switch (ty.zigTypeTag()) {
15 switch (ty.zigTypeTag(mod)) {
1416 .Struct => {
15 const bit_size = ty.bitSize(target);
17 const bit_size = ty.bitSize(mod);
1618 if (ty.containerLayout() == .Packed) {
1719 if (bit_size > max_byval_size) return .memory;
1820 return .byval;
......@@ -23,7 +25,7 @@ pub fn classifyType(ty: Type, target: std.Target) Class {
2325 return .integer;
2426 },
2527 .Union => {
26 const bit_size = ty.bitSize(target);
28 const bit_size = ty.bitSize(mod);
2729 if (ty.containerLayout() == .Packed) {
2830 if (bit_size > max_byval_size) return .memory;
2931 return .byval;
......@@ -36,17 +38,17 @@ pub fn classifyType(ty: Type, target: std.Target) Class {
3638 .Bool => return .integer,
3739 .Float => return .byval,
3840 .Int, .Enum, .ErrorSet => {
39 const bit_size = ty.bitSize(target);
41 const bit_size = ty.bitSize(mod);
4042 if (bit_size > max_byval_size) return .memory;
4143 return .byval;
4244 },
4345 .Vector => {
44 const bit_size = ty.bitSize(target);
46 const bit_size = ty.bitSize(mod);
4547 if (bit_size > max_byval_size) return .memory;
4648 return .integer;
4749 },
4850 .Optional => {
49 std.debug.assert(ty.isPtrLikeOptional());
51 std.debug.assert(ty.isPtrLikeOptional(mod));
5052 return .byval;
5153 },
5254 .Pointer => {
src/arch/sparc64/CodeGen.zig+129-110
......@@ -758,18 +758,18 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
758758 const tag = self.air.instructions.items(.tag)[inst];
759759 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
760760 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
761 const mod = self.bin_file.options.module.?;
761762 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
762763 const lhs = try self.resolveInst(extra.lhs);
763764 const rhs = try self.resolveInst(extra.rhs);
764765 const lhs_ty = self.air.typeOf(extra.lhs);
765766 const rhs_ty = self.air.typeOf(extra.rhs);
766767
767 switch (lhs_ty.zigTypeTag()) {
768 switch (lhs_ty.zigTypeTag(mod)) {
768769 .Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
769770 .Int => {
770 const mod = self.bin_file.options.module.?;
771771 assert(lhs_ty.eql(rhs_ty, mod));
772 const int_info = lhs_ty.intInfo(self.target.*);
772 const int_info = lhs_ty.intInfo(mod);
773773 switch (int_info.bits) {
774774 32, 64 => {
775775 // Only say yes if the operation is
......@@ -1018,7 +1018,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
10181018 switch (arg) {
10191019 .stack_offset => |off| {
10201020 const mod = self.bin_file.options.module.?;
1021 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) orelse {
1021 const abi_size = math.cast(u32, ty.abiSize(mod)) orelse {
10221022 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});
10231023 };
10241024 const offset = off + abi_size;
......@@ -1203,6 +1203,7 @@ fn airBreakpoint(self: *Self) !void {
12031203}
12041204
12051205fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
1206 const mod = self.bin_file.options.module.?;
12061207 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
12071208
12081209 // We have hardware byteswapper in SPARCv9, don't let mainstream compilers mislead you.
......@@ -1218,14 +1219,14 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
12181219 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
12191220 const operand = try self.resolveInst(ty_op.operand);
12201221 const operand_ty = self.air.typeOf(ty_op.operand);
1221 switch (operand_ty.zigTypeTag()) {
1222 switch (operand_ty.zigTypeTag(mod)) {
12221223 .Vector => return self.fail("TODO byteswap for vectors", .{}),
12231224 .Int => {
1224 const int_info = operand_ty.intInfo(self.target.*);
1225 const int_info = operand_ty.intInfo(mod);
12251226 if (int_info.bits == 8) break :result operand;
12261227
12271228 const abi_size = int_info.bits >> 3;
1228 const abi_align = operand_ty.abiAlignment(self.target.*);
1229 const abi_align = operand_ty.abiAlignment(mod);
12291230 const opposite_endian_asi = switch (self.target.cpu.arch.endian()) {
12301231 Endian.Big => ASI.asi_primary_little,
12311232 Endian.Little => ASI.asi_primary,
......@@ -1294,7 +1295,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
12941295 const extra = self.air.extraData(Air.Call, pl_op.payload);
12951296 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end .. extra.end + extra.data.args_len]);
12961297 const ty = self.air.typeOf(callee);
1297 const fn_ty = switch (ty.zigTypeTag()) {
1298 const mod = self.bin_file.options.module.?;
1299 const fn_ty = switch (ty.zigTypeTag(mod)) {
12981300 .Fn => ty,
12991301 .Pointer => ty.childType(),
13001302 else => unreachable,
......@@ -1337,7 +1339,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
13371339
13381340 // Due to incremental compilation, how function calls are generated depends
13391341 // on linking.
1340 if (self.air.value(callee)) |func_value| {
1342 if (self.air.value(callee, mod)) |func_value| {
13411343 if (self.bin_file.tag == link.File.Elf.base_tag) {
13421344 if (func_value.castTag(.function)) |func_payload| {
13431345 const func = func_payload.data;
......@@ -1374,7 +1376,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
13741376 }
13751377 } else @panic("TODO SPARCv9 currently does not support non-ELF binaries");
13761378 } else {
1377 assert(ty.zigTypeTag() == .Pointer);
1379 assert(ty.zigTypeTag(mod) == .Pointer);
13781380 const mcv = try self.resolveInst(callee);
13791381 try self.genSetReg(ty, .o7, mcv);
13801382
......@@ -1422,15 +1424,15 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
14221424
14231425fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
14241426 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1427 const mod = self.bin_file.options.module.?;
14251428 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
14261429 const lhs = try self.resolveInst(bin_op.lhs);
14271430 const rhs = try self.resolveInst(bin_op.rhs);
14281431 const lhs_ty = self.air.typeOf(bin_op.lhs);
14291432
1430 var int_buffer: Type.Payload.Bits = undefined;
1431 const int_ty = switch (lhs_ty.zigTypeTag()) {
1433 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
14321434 .Vector => unreachable, // Handled by cmp_vector.
1433 .Enum => lhs_ty.intTagType(&int_buffer),
1435 .Enum => lhs_ty.intTagType(),
14341436 .Int => lhs_ty,
14351437 .Bool => Type.initTag(.u1),
14361438 .Pointer => Type.usize,
......@@ -1438,9 +1440,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
14381440 .Optional => blk: {
14391441 var opt_buffer: Type.Payload.ElemType = undefined;
14401442 const payload_ty = lhs_ty.optionalChild(&opt_buffer);
1441 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1443 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
14421444 break :blk Type.initTag(.u1);
1443 } else if (lhs_ty.isPtrLikeOptional()) {
1445 } else if (lhs_ty.isPtrLikeOptional(mod)) {
14441446 break :blk Type.usize;
14451447 } else {
14461448 return self.fail("TODO SPARCv9 cmp non-pointer optionals", .{});
......@@ -1450,7 +1452,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
14501452 else => unreachable,
14511453 };
14521454
1453 const int_info = int_ty.intInfo(self.target.*);
1455 const int_info = int_ty.intInfo(mod);
14541456 if (int_info.bits <= 64) {
14551457 _ = try self.binOp(.cmp_eq, lhs, rhs, int_ty, int_ty, BinOpMetadata{
14561458 .lhs = bin_op.lhs,
......@@ -1512,8 +1514,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
15121514 // whether it needs to be spilled in the branches
15131515 if (self.liveness.operandDies(inst, 0)) {
15141516 const op_int = @enumToInt(pl_op.operand);
1515 if (op_int >= Air.Inst.Ref.typed_value_map.len) {
1516 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);
1517 if (op_int >= Air.ref_start_index) {
1518 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
15171519 self.processDeath(op_index);
15181520 }
15191521 }
......@@ -1752,10 +1754,11 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
17521754 if (self.liveness.isUnused(inst))
17531755 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
17541756
1757 const mod = self.bin_file.options.module.?;
17551758 const operand_ty = self.air.typeOf(ty_op.operand);
17561759 const operand = try self.resolveInst(ty_op.operand);
1757 const info_a = operand_ty.intInfo(self.target.*);
1758 const info_b = self.air.typeOfIndex(inst).intInfo(self.target.*);
1760 const info_a = operand_ty.intInfo(mod);
1761 const info_b = self.air.typeOfIndex(inst).intInfo(mod);
17591762 if (info_a.signedness != info_b.signedness)
17601763 return self.fail("TODO gen intcast sign safety in semantic analysis", .{});
17611764
......@@ -1814,9 +1817,10 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
18141817fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
18151818 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
18161819 const elem_ty = self.air.typeOfIndex(inst);
1817 const elem_size = elem_ty.abiSize(self.target.*);
1820 const mod = self.bin_file.options.module.?;
1821 const elem_size = elem_ty.abiSize(mod);
18181822 const result: MCValue = result: {
1819 if (!elem_ty.hasRuntimeBits())
1823 if (!elem_ty.hasRuntimeBits(mod))
18201824 break :result MCValue.none;
18211825
18221826 const ptr = try self.resolveInst(ty_op.operand);
......@@ -2037,18 +2041,18 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
20372041 //const tag = self.air.instructions.items(.tag)[inst];
20382042 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
20392043 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2044 const mod = self.bin_file.options.module.?;
20402045 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
20412046 const lhs = try self.resolveInst(extra.lhs);
20422047 const rhs = try self.resolveInst(extra.rhs);
20432048 const lhs_ty = self.air.typeOf(extra.lhs);
20442049 const rhs_ty = self.air.typeOf(extra.rhs);
20452050
2046 switch (lhs_ty.zigTypeTag()) {
2051 switch (lhs_ty.zigTypeTag(mod)) {
20472052 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
20482053 .Int => {
2049 const mod = self.bin_file.options.module.?;
20502054 assert(lhs_ty.eql(rhs_ty, mod));
2051 const int_info = lhs_ty.intInfo(self.target.*);
2055 const int_info = lhs_ty.intInfo(mod);
20522056 switch (int_info.bits) {
20532057 1...32 => {
20542058 try self.spillConditionFlagsIfOccupied();
......@@ -2101,6 +2105,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
21012105
21022106fn airNot(self: *Self, inst: Air.Inst.Index) !void {
21032107 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2108 const mod = self.bin_file.options.module.?;
21042109 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
21052110 const operand = try self.resolveInst(ty_op.operand);
21062111 const operand_ty = self.air.typeOf(ty_op.operand);
......@@ -2116,7 +2121,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
21162121 };
21172122 },
21182123 else => {
2119 switch (operand_ty.zigTypeTag()) {
2124 switch (operand_ty.zigTypeTag(mod)) {
21202125 .Bool => {
21212126 const op_reg = switch (operand) {
21222127 .register => |r| r,
......@@ -2150,7 +2155,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
21502155 },
21512156 .Vector => return self.fail("TODO bitwise not for vectors", .{}),
21522157 .Int => {
2153 const int_info = operand_ty.intInfo(self.target.*);
2158 const int_info = operand_ty.intInfo(mod);
21542159 if (int_info.bits <= 64) {
21552160 const op_reg = switch (operand) {
21562161 .register => |r| r,
......@@ -2332,16 +2337,17 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
23322337fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
23332338 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
23342339 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2340 const mod = self.bin_file.options.module.?;
23352341 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
23362342 const lhs = try self.resolveInst(extra.lhs);
23372343 const rhs = try self.resolveInst(extra.rhs);
23382344 const lhs_ty = self.air.typeOf(extra.lhs);
23392345 const rhs_ty = self.air.typeOf(extra.rhs);
23402346
2341 switch (lhs_ty.zigTypeTag()) {
2347 switch (lhs_ty.zigTypeTag(mod)) {
23422348 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
23432349 .Int => {
2344 const int_info = lhs_ty.intInfo(self.target.*);
2350 const int_info = lhs_ty.intInfo(mod);
23452351 if (int_info.bits <= 64) {
23462352 try self.spillConditionFlagsIfOccupied();
23472353
......@@ -2449,7 +2455,8 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
24492455
24502456 const slice_ty = self.air.typeOf(bin_op.lhs);
24512457 const elem_ty = slice_ty.childType();
2452 const elem_size = elem_ty.abiSize(self.target.*);
2458 const mod = self.bin_file.options.module.?;
2459 const elem_size = elem_ty.abiSize(mod);
24532460
24542461 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
24552462 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
......@@ -2564,9 +2571,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
25642571 const operand = extra.struct_operand;
25652572 const index = extra.field_index;
25662573 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2574 const mod = self.bin_file.options.module.?;
25672575 const mcv = try self.resolveInst(operand);
25682576 const struct_ty = self.air.typeOf(operand);
2569 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
2577 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
25702578
25712579 switch (mcv) {
25722580 .dead, .unreach => unreachable,
......@@ -2701,7 +2709,8 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
27012709 const error_union_ty = self.air.typeOf(ty_op.operand);
27022710 const payload_ty = error_union_ty.errorUnionPayload();
27032711 const mcv = try self.resolveInst(ty_op.operand);
2704 if (!payload_ty.hasRuntimeBits()) break :result mcv;
2712 const mod = self.bin_file.options.module.?;
2713 if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;
27052714
27062715 return self.fail("TODO implement unwrap error union error for non-empty payloads", .{});
27072716 };
......@@ -2713,7 +2722,8 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
27132722 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
27142723 const error_union_ty = self.air.typeOf(ty_op.operand);
27152724 const payload_ty = error_union_ty.errorUnionPayload();
2716 if (!payload_ty.hasRuntimeBits()) break :result MCValue.none;
2725 const mod = self.bin_file.options.module.?;
2726 if (!payload_ty.hasRuntimeBits(mod)) break :result MCValue.none;
27172727
27182728 return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{});
27192729 };
......@@ -2727,7 +2737,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
27272737 const error_union_ty = self.air.getRefType(ty_op.ty);
27282738 const payload_ty = error_union_ty.errorUnionPayload();
27292739 const mcv = try self.resolveInst(ty_op.operand);
2730 if (!payload_ty.hasRuntimeBits()) break :result mcv;
2740 const mod = self.bin_file.options.module.?;
2741 if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;
27312742
27322743 return self.fail("TODO implement wrap errunion error for non-empty payloads", .{});
27332744 };
......@@ -2747,7 +2758,8 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
27472758 const optional_ty = self.air.typeOfIndex(inst);
27482759
27492760 // Optional with a zero-bit payload type is just a boolean true
2750 if (optional_ty.abiSize(self.target.*) == 1)
2761 const mod = self.bin_file.options.module.?;
2762 if (optional_ty.abiSize(mod) == 1)
27512763 break :result MCValue{ .immediate = 1 };
27522764
27532765 return self.fail("TODO implement wrap optional for {}", .{self.target.cpu.arch});
......@@ -2784,7 +2796,8 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
27842796fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
27852797 const elem_ty = self.air.typeOfIndex(inst).elemType();
27862798
2787 if (!elem_ty.hasRuntimeBits()) {
2799 const mod = self.bin_file.options.module.?;
2800 if (!elem_ty.hasRuntimeBits(mod)) {
27882801 // As this stack item will never be dereferenced at runtime,
27892802 // return the stack offset 0. Stack offset 0 will be where all
27902803 // zero-sized stack allocations live as non-zero-sized
......@@ -2792,22 +2805,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
27922805 return @as(u32, 0);
27932806 }
27942807
2795 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
2796 const mod = self.bin_file.options.module.?;
2808 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
27972809 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
27982810 };
27992811 // TODO swap this for inst.ty.ptrAlign
2800 const abi_align = elem_ty.abiAlignment(self.target.*);
2812 const abi_align = elem_ty.abiAlignment(mod);
28012813 return self.allocMem(inst, abi_size, abi_align);
28022814}
28032815
28042816fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
28052817 const elem_ty = self.air.typeOfIndex(inst);
2806 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) orelse {
2807 const mod = self.bin_file.options.module.?;
2818 const mod = self.bin_file.options.module.?;
2819 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
28082820 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
28092821 };
2810 const abi_align = elem_ty.abiAlignment(self.target.*);
2822 const abi_align = elem_ty.abiAlignment(mod);
28112823 if (abi_align > self.stack_align)
28122824 self.stack_align = abi_align;
28132825
......@@ -2860,12 +2872,12 @@ fn binOp(
28602872 .xor,
28612873 .cmp_eq,
28622874 => {
2863 switch (lhs_ty.zigTypeTag()) {
2875 switch (lhs_ty.zigTypeTag(mod)) {
28642876 .Float => return self.fail("TODO binary operations on floats", .{}),
28652877 .Vector => return self.fail("TODO binary operations on vectors", .{}),
28662878 .Int => {
28672879 assert(lhs_ty.eql(rhs_ty, mod));
2868 const int_info = lhs_ty.intInfo(self.target.*);
2880 const int_info = lhs_ty.intInfo(mod);
28692881 if (int_info.bits <= 64) {
28702882 // Only say yes if the operation is
28712883 // commutative, i.e. we can swap both of the
......@@ -2934,10 +2946,10 @@ fn binOp(
29342946 const result = try self.binOp(base_tag, lhs, rhs, lhs_ty, rhs_ty, metadata);
29352947
29362948 // Truncate if necessary
2937 switch (lhs_ty.zigTypeTag()) {
2949 switch (lhs_ty.zigTypeTag(mod)) {
29382950 .Vector => return self.fail("TODO binary operations on vectors", .{}),
29392951 .Int => {
2940 const int_info = lhs_ty.intInfo(self.target.*);
2952 const int_info = lhs_ty.intInfo(mod);
29412953 if (int_info.bits <= 64) {
29422954 const result_reg = result.register;
29432955 try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
......@@ -2951,11 +2963,11 @@ fn binOp(
29512963 },
29522964
29532965 .div_trunc => {
2954 switch (lhs_ty.zigTypeTag()) {
2966 switch (lhs_ty.zigTypeTag(mod)) {
29552967 .Vector => return self.fail("TODO binary operations on vectors", .{}),
29562968 .Int => {
29572969 assert(lhs_ty.eql(rhs_ty, mod));
2958 const int_info = lhs_ty.intInfo(self.target.*);
2970 const int_info = lhs_ty.intInfo(mod);
29592971 if (int_info.bits <= 64) {
29602972 const rhs_immediate_ok = switch (tag) {
29612973 .div_trunc => rhs == .immediate and rhs.immediate <= std.math.maxInt(u12),
......@@ -2984,14 +2996,14 @@ fn binOp(
29842996 },
29852997
29862998 .ptr_add => {
2987 switch (lhs_ty.zigTypeTag()) {
2999 switch (lhs_ty.zigTypeTag(mod)) {
29883000 .Pointer => {
29893001 const ptr_ty = lhs_ty;
29903002 const elem_ty = switch (ptr_ty.ptrSize()) {
29913003 .One => ptr_ty.childType().childType(), // ptr to array, so get array element type
29923004 else => ptr_ty.childType(),
29933005 };
2994 const elem_size = elem_ty.abiSize(self.target.*);
3006 const elem_size = elem_ty.abiSize(mod);
29953007
29963008 if (elem_size == 1) {
29973009 const base_tag: Mir.Inst.Tag = switch (tag) {
......@@ -3016,7 +3028,7 @@ fn binOp(
30163028 .bool_and,
30173029 .bool_or,
30183030 => {
3019 switch (lhs_ty.zigTypeTag()) {
3031 switch (lhs_ty.zigTypeTag(mod)) {
30203032 .Bool => {
30213033 assert(lhs != .immediate); // should have been handled by Sema
30223034 assert(rhs != .immediate); // should have been handled by Sema
......@@ -3046,10 +3058,10 @@ fn binOp(
30463058 const result = try self.binOp(base_tag, lhs, rhs, lhs_ty, rhs_ty, metadata);
30473059
30483060 // Truncate if necessary
3049 switch (lhs_ty.zigTypeTag()) {
3061 switch (lhs_ty.zigTypeTag(mod)) {
30503062 .Vector => return self.fail("TODO binary operations on vectors", .{}),
30513063 .Int => {
3052 const int_info = lhs_ty.intInfo(self.target.*);
3064 const int_info = lhs_ty.intInfo(mod);
30533065 if (int_info.bits <= 64) {
30543066 // 32 and 64 bit operands doesn't need truncating
30553067 if (int_info.bits == 32 or int_info.bits == 64) return result;
......@@ -3068,10 +3080,10 @@ fn binOp(
30683080 .shl_exact,
30693081 .shr_exact,
30703082 => {
3071 switch (lhs_ty.zigTypeTag()) {
3083 switch (lhs_ty.zigTypeTag(mod)) {
30723084 .Vector => return self.fail("TODO binary operations on vectors", .{}),
30733085 .Int => {
3074 const int_info = lhs_ty.intInfo(self.target.*);
3086 const int_info = lhs_ty.intInfo(mod);
30753087 if (int_info.bits <= 64) {
30763088 const rhs_immediate_ok = rhs == .immediate;
30773089
......@@ -3393,7 +3405,8 @@ fn binOpRegister(
33933405fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
33943406 const block_data = self.blocks.getPtr(block).?;
33953407
3396 if (self.air.typeOf(operand).hasRuntimeBits()) {
3408 const mod = self.bin_file.options.module.?;
3409 if (self.air.typeOf(operand).hasRuntimeBits(mod)) {
33973410 const operand_mcv = try self.resolveInst(operand);
33983411 const block_mcv = block_data.mcv;
33993412 if (block_mcv == .none) {
......@@ -3512,16 +3525,17 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
35123525
35133526/// Given an error union, returns the payload
35143527fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
3528 const mod = self.bin_file.options.module.?;
35153529 const err_ty = error_union_ty.errorUnionSet();
35163530 const payload_ty = error_union_ty.errorUnionPayload();
35173531 if (err_ty.errorSetIsEmpty()) {
35183532 return error_union_mcv;
35193533 }
3520 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3534 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
35213535 return MCValue.none;
35223536 }
35233537
3524 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target.*));
3538 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, mod));
35253539 switch (error_union_mcv) {
35263540 .register => return self.fail("TODO errUnionPayload for registers", .{}),
35273541 .stack_offset => |off| {
......@@ -3555,8 +3569,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
35553569 tomb_bits >>= 1;
35563570 if (!dies) continue;
35573571 const op_int = @enumToInt(op);
3558 if (op_int < Air.Inst.Ref.typed_value_map.len) continue;
3559 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);
3572 if (op_int < Air.ref_start_index) continue;
3573 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
35603574 self.processDeath(op_index);
35613575 }
35623576 const is_used = @truncate(u1, tomb_bits) == 0;
......@@ -3730,6 +3744,7 @@ fn genLoadASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Reg
37303744}
37313745
37323746fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
3747 const mod = self.bin_file.options.module.?;
37333748 switch (mcv) {
37343749 .dead => unreachable,
37353750 .unreach, .none => return, // Nothing to do.
......@@ -3928,19 +3943,20 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
39283943 // The value is in memory at a hard-coded address.
39293944 // If the type is a pointer, it means the pointer address is at this memory location.
39303945 try self.genSetReg(ty, reg, .{ .immediate = addr });
3931 try self.genLoad(reg, reg, i13, 0, ty.abiSize(self.target.*));
3946 try self.genLoad(reg, reg, i13, 0, ty.abiSize(mod));
39323947 },
39333948 .stack_offset => |off| {
39343949 const real_offset = realStackOffset(off);
39353950 const simm13 = math.cast(i13, real_offset) orelse
39363951 return self.fail("TODO larger stack offsets: {}", .{real_offset});
3937 try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(self.target.*));
3952 try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(mod));
39383953 },
39393954 }
39403955}
39413956
39423957fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
3943 const abi_size = ty.abiSize(self.target.*);
3958 const mod = self.bin_file.options.module.?;
3959 const abi_size = ty.abiSize(mod);
39443960 switch (mcv) {
39453961 .dead => unreachable,
39463962 .unreach, .none => return, // Nothing to do.
......@@ -3948,7 +3964,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
39483964 if (!self.wantSafety())
39493965 return; // The already existing value will do just fine.
39503966 // TODO Upgrade this to a memset call when we have that available.
3951 switch (ty.abiSize(self.target.*)) {
3967 switch (ty.abiSize(mod)) {
39523968 1 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaa }),
39533969 2 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaa }),
39543970 4 => return self.genSetStack(ty, stack_offset, .{ .immediate = 0xaaaaaaaa }),
......@@ -3978,7 +3994,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
39783994 try self.genSetStack(wrapped_ty, stack_offset, .{ .register = rwo.reg });
39793995
39803996 const overflow_bit_ty = ty.structFieldType(1);
3981 const overflow_bit_offset = @intCast(u32, ty.structFieldOffset(1, self.target.*));
3997 const overflow_bit_offset = @intCast(u32, ty.structFieldOffset(1, mod));
39823998 const cond_reg = try self.register_manager.allocReg(null, gp);
39833999
39844000 // TODO handle floating point CCRs
......@@ -4152,13 +4168,14 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
41524168}
41534169
41544170fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
4171 const mod = self.bin_file.options.module.?;
41554172 const error_type = ty.errorUnionSet();
41564173 const payload_type = ty.errorUnionPayload();
41574174
4158 if (!error_type.hasRuntimeBits()) {
4175 if (!error_type.hasRuntimeBits(mod)) {
41594176 return MCValue{ .immediate = 0 }; // always false
4160 } else if (!payload_type.hasRuntimeBits()) {
4161 if (error_type.abiSize(self.target.*) <= 8) {
4177 } else if (!payload_type.hasRuntimeBits(mod)) {
4178 if (error_type.abiSize(mod) <= 8) {
41624179 const reg_mcv: MCValue = switch (operand) {
41634180 .register => operand,
41644181 else => .{ .register = try self.copyToTmpRegister(error_type, operand) },
......@@ -4249,8 +4266,9 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void {
42494266}
42504267
42514268fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
4269 const mod = self.bin_file.options.module.?;
42524270 const elem_ty = ptr_ty.elemType();
4253 const elem_size = elem_ty.abiSize(self.target.*);
4271 const elem_size = elem_ty.abiSize(mod);
42544272
42554273 switch (ptr) {
42564274 .none => unreachable,
......@@ -4321,11 +4339,11 @@ fn minMax(
43214339) InnerError!MCValue {
43224340 const mod = self.bin_file.options.module.?;
43234341 assert(lhs_ty.eql(rhs_ty, mod));
4324 switch (lhs_ty.zigTypeTag()) {
4342 switch (lhs_ty.zigTypeTag(mod)) {
43254343 .Float => return self.fail("TODO min/max on floats", .{}),
43264344 .Vector => return self.fail("TODO min/max on vectors", .{}),
43274345 .Int => {
4328 const int_info = lhs_ty.intInfo(self.target.*);
4346 const int_info = lhs_ty.intInfo(mod);
43294347 if (int_info.bits <= 64) {
43304348 // TODO skip register setting when one of the operands
43314349 // is a small (fits in i13) immediate.
......@@ -4455,6 +4473,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
44554473 errdefer self.gpa.free(result.args);
44564474
44574475 const ret_ty = fn_ty.fnReturnType();
4476 const mod = self.bin_file.options.module.?;
44584477
44594478 switch (cc) {
44604479 .Naked => {
......@@ -4478,7 +4497,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
44784497 };
44794498
44804499 for (param_types, 0..) |ty, i| {
4481 const param_size = @intCast(u32, ty.abiSize(self.target.*));
4500 const param_size = @intCast(u32, ty.abiSize(mod));
44824501 if (param_size <= 8) {
44834502 if (next_register < argument_registers.len) {
44844503 result.args[i] = .{ .register = argument_registers[next_register] };
......@@ -4505,12 +4524,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
45054524 result.stack_byte_count = next_stack_offset;
45064525 result.stack_align = 16;
45074526
4508 if (ret_ty.zigTypeTag() == .NoReturn) {
4527 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
45094528 result.return_value = .{ .unreach = {} };
4510 } else if (!ret_ty.hasRuntimeBits()) {
4529 } else if (!ret_ty.hasRuntimeBits(mod)) {
45114530 result.return_value = .{ .none = {} };
45124531 } else {
4513 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));
4532 const ret_ty_size = @intCast(u32, ret_ty.abiSize(mod));
45144533 // The callee puts the return values in %i0-%i3, which becomes %o0-%o3 inside the caller.
45154534 if (ret_ty_size <= 8) {
45164535 result.return_value = switch (role) {
......@@ -4528,40 +4547,37 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
45284547 return result;
45294548}
45304549
4531fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
4532 // First section of indexes correspond to a set number of constant values.
4533 const ref_int = @enumToInt(inst);
4534 if (ref_int < Air.Inst.Ref.typed_value_map.len) {
4535 const tv = Air.Inst.Ref.typed_value_map[ref_int];
4536 if (!tv.ty.hasRuntimeBitsIgnoreComptime() and !tv.ty.isError()) {
4537 return MCValue{ .none = {} };
4538 }
4539 return self.genTypedValue(tv);
4540 }
4550fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
4551 const mod = self.bin_file.options.module.?;
4552 const ty = self.air.typeOf(ref);
45414553
45424554 // If the type has no codegen bits, no need to store it.
4543 const inst_ty = self.air.typeOf(inst);
4544 if (!inst_ty.hasRuntimeBitsIgnoreComptime() and !inst_ty.isError())
4545 return MCValue{ .none = {} };
4546
4547 const inst_index = @intCast(Air.Inst.Index, ref_int - Air.Inst.Ref.typed_value_map.len);
4548 switch (self.air.instructions.items(.tag)[inst_index]) {
4549 .constant => {
4550 // Constants have static lifetimes, so they are always memoized in the outer most table.
4551 const branch = &self.branch_stack.items[0];
4552 const gop = try branch.inst_table.getOrPut(self.gpa, inst_index);
4553 if (!gop.found_existing) {
4554 const ty_pl = self.air.instructions.items(.data)[inst_index].ty_pl;
4555 gop.value_ptr.* = try self.genTypedValue(.{
4556 .ty = inst_ty,
4557 .val = self.air.values[ty_pl.payload],
4558 });
4559 }
4560 return gop.value_ptr.*;
4561 },
4562 .const_ty => unreachable,
4563 else => return self.getResolvedInstValue(inst_index),
4555 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;
4556
4557 if (Air.refToIndex(ref)) |inst| {
4558 switch (self.air.instructions.items(.tag)[inst]) {
4559 .constant => {
4560 // Constants have static lifetimes, so they are always memoized in the outer most table.
4561 const branch = &self.branch_stack.items[0];
4562 const gop = try branch.inst_table.getOrPut(self.gpa, inst);
4563 if (!gop.found_existing) {
4564 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4565 gop.value_ptr.* = try self.genTypedValue(.{
4566 .ty = ty,
4567 .val = self.air.values[ty_pl.payload],
4568 });
4569 }
4570 return gop.value_ptr.*;
4571 },
4572 .const_ty => unreachable,
4573 else => return self.getResolvedInstValue(inst),
4574 }
45644575 }
4576
4577 return self.genTypedValue(.{
4578 .ty = ty,
4579 .val = self.air.value(ref, mod).?,
4580 });
45654581}
45664582
45674583fn ret(self: *Self, mcv: MCValue) !void {
......@@ -4666,7 +4682,8 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
46664682}
46674683
46684684fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
4669 const abi_size = value_ty.abiSize(self.target.*);
4685 const mod = self.bin_file.options.module.?;
4686 const abi_size = value_ty.abiSize(mod);
46704687
46714688 switch (ptr) {
46724689 .none => unreachable,
......@@ -4707,10 +4724,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
47074724
47084725fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
47094726 return if (self.liveness.isUnused(inst)) .dead else result: {
4727 const mod = self.bin_file.options.module.?;
47104728 const mcv = try self.resolveInst(operand);
47114729 const ptr_ty = self.air.typeOf(operand);
47124730 const struct_ty = ptr_ty.childType();
4713 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
4731 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod));
47144732 switch (mcv) {
47154733 .ptr_stack_offset => |off| {
47164734 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
......@@ -4748,8 +4766,9 @@ fn trunc(
47484766 operand_ty: Type,
47494767 dest_ty: Type,
47504768) !MCValue {
4751 const info_a = operand_ty.intInfo(self.target.*);
4752 const info_b = dest_ty.intInfo(self.target.*);
4769 const mod = self.bin_file.options.module.?;
4770 const info_a = operand_ty.intInfo(mod);
4771 const info_b = dest_ty.intInfo(mod);
47534772
47544773 if (info_b.bits <= 64) {
47554774 const operand_reg = switch (operand) {
src/arch/wasm/CodeGen.zig+504-462
......@@ -788,9 +788,10 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
788788 const gop = try func.branches.items[0].values.getOrPut(func.gpa, ref);
789789 assert(!gop.found_existing);
790790
791 const val = func.air.value(ref).?;
791 const mod = func.bin_file.base.options.module.?;
792 const val = func.air.value(ref, mod).?;
792793 const ty = func.air.typeOf(ref);
793 if (!ty.hasRuntimeBitsIgnoreComptime() and !ty.isInt() and !ty.isError()) {
794 if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) {
794795 gop.value_ptr.* = WValue{ .none = {} };
795796 return gop.value_ptr.*;
796797 }
......@@ -801,7 +802,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
801802 //
802803 // In the other cases, we will simply lower the constant to a value that fits
803804 // into a single local (such as a pointer, integer, bool, etc).
804 const result = if (isByRef(ty, func.target)) blk: {
805 const result = if (isByRef(ty, mod)) blk: {
805806 const sym_index = try func.bin_file.lowerUnnamedConst(.{ .ty = ty, .val = val }, func.decl_index);
806807 break :blk WValue{ .memory = sym_index };
807808 } else try func.lowerConstant(val, ty);
......@@ -987,8 +988,9 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32
987988}
988989
989990/// Using a given `Type`, returns the corresponding type
990fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {
991 return switch (ty.zigTypeTag()) {
991fn typeToValtype(ty: Type, mod: *Module) wasm.Valtype {
992 const target = mod.getTarget();
993 return switch (ty.zigTypeTag(mod)) {
992994 .Float => blk: {
993995 const bits = ty.floatBits(target);
994996 if (bits == 16) return wasm.Valtype.i32; // stored/loaded as u16
......@@ -998,7 +1000,7 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {
9981000 return wasm.Valtype.i32; // represented as pointer to stack
9991001 },
10001002 .Int, .Enum => blk: {
1001 const info = ty.intInfo(target);
1003 const info = ty.intInfo(mod);
10021004 if (info.bits <= 32) break :blk wasm.Valtype.i32;
10031005 if (info.bits > 32 and info.bits <= 128) break :blk wasm.Valtype.i64;
10041006 break :blk wasm.Valtype.i32; // represented as pointer to stack
......@@ -1006,22 +1008,18 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {
10061008 .Struct => switch (ty.containerLayout()) {
10071009 .Packed => {
10081010 const struct_obj = ty.castTag(.@"struct").?.data;
1009 return typeToValtype(struct_obj.backing_int_ty, target);
1011 return typeToValtype(struct_obj.backing_int_ty, mod);
10101012 },
10111013 else => wasm.Valtype.i32,
10121014 },
1013 .Vector => switch (determineSimdStoreStrategy(ty, target)) {
1015 .Vector => switch (determineSimdStoreStrategy(ty, mod)) {
10141016 .direct => wasm.Valtype.v128,
10151017 .unrolled => wasm.Valtype.i32,
10161018 },
10171019 .Union => switch (ty.containerLayout()) {
10181020 .Packed => {
1019 var int_ty_payload: Type.Payload.Bits = .{
1020 .base = .{ .tag = .int_unsigned },
1021 .data = @intCast(u16, ty.bitSize(target)),
1022 };
1023 const int_ty = Type.initPayload(&int_ty_payload.base);
1024 return typeToValtype(int_ty, target);
1021 const int_ty = mod.intType(.unsigned, @intCast(u16, ty.bitSize(mod))) catch @panic("out of memory");
1022 return typeToValtype(int_ty, mod);
10251023 },
10261024 else => wasm.Valtype.i32,
10271025 },
......@@ -1030,17 +1028,17 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {
10301028}
10311029
10321030/// Using a given `Type`, returns the byte representation of its wasm value type
1033fn genValtype(ty: Type, target: std.Target) u8 {
1034 return wasm.valtype(typeToValtype(ty, target));
1031fn genValtype(ty: Type, mod: *Module) u8 {
1032 return wasm.valtype(typeToValtype(ty, mod));
10351033}
10361034
10371035/// Using a given `Type`, returns the corresponding wasm value type
10381036/// Differently from `genValtype` this also allows `void` to create a block
10391037/// with no return type
1040fn genBlockType(ty: Type, target: std.Target) u8 {
1038fn genBlockType(ty: Type, mod: *Module) u8 {
10411039 return switch (ty.tag()) {
10421040 .void, .noreturn => wasm.block_empty,
1043 else => genValtype(ty, target),
1041 else => genValtype(ty, mod),
10441042 };
10451043}
10461044
......@@ -1101,7 +1099,8 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {
11011099/// Creates one locals for a given `Type`.
11021100/// Returns a corresponding `Wvalue` with `local` as active tag
11031101fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1104 const valtype = typeToValtype(ty, func.target);
1102 const mod = func.bin_file.base.options.module.?;
1103 const valtype = typeToValtype(ty, mod);
11051104 switch (valtype) {
11061105 .i32 => if (func.free_locals_i32.popOrNull()) |index| {
11071106 log.debug("reusing local ({d}) of type {}", .{ index, valtype });
......@@ -1132,7 +1131,8 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
11321131/// Ensures a new local will be created. This is useful when it's useful
11331132/// to use a zero-initialized local.
11341133fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1135 try func.locals.append(func.gpa, genValtype(ty, func.target));
1134 const mod = func.bin_file.base.options.module.?;
1135 try func.locals.append(func.gpa, genValtype(ty, mod));
11361136 const initial_index = func.local_index;
11371137 func.local_index += 1;
11381138 return WValue{ .local = .{ .value = initial_index, .references = 1 } };
......@@ -1140,48 +1140,54 @@ fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
11401140
11411141/// Generates a `wasm.Type` from a given function type.
11421142/// Memory is owned by the caller.
1143fn genFunctype(gpa: Allocator, cc: std.builtin.CallingConvention, params: []const Type, return_type: Type, target: std.Target) !wasm.Type {
1143fn genFunctype(
1144 gpa: Allocator,
1145 cc: std.builtin.CallingConvention,
1146 params: []const Type,
1147 return_type: Type,
1148 mod: *Module,
1149) !wasm.Type {
11441150 var temp_params = std.ArrayList(wasm.Valtype).init(gpa);
11451151 defer temp_params.deinit();
11461152 var returns = std.ArrayList(wasm.Valtype).init(gpa);
11471153 defer returns.deinit();
11481154
1149 if (firstParamSRet(cc, return_type, target)) {
1155 if (firstParamSRet(cc, return_type, mod)) {
11501156 try temp_params.append(.i32); // memory address is always a 32-bit handle
1151 } else if (return_type.hasRuntimeBitsIgnoreComptime()) {
1157 } else if (return_type.hasRuntimeBitsIgnoreComptime(mod)) {
11521158 if (cc == .C) {
1153 const res_classes = abi.classifyType(return_type, target);
1159 const res_classes = abi.classifyType(return_type, mod);
11541160 assert(res_classes[0] == .direct and res_classes[1] == .none);
1155 const scalar_type = abi.scalarType(return_type, target);
1156 try returns.append(typeToValtype(scalar_type, target));
1161 const scalar_type = abi.scalarType(return_type, mod);
1162 try returns.append(typeToValtype(scalar_type, mod));
11571163 } else {
1158 try returns.append(typeToValtype(return_type, target));
1164 try returns.append(typeToValtype(return_type, mod));
11591165 }
1160 } else if (return_type.isError()) {
1166 } else if (return_type.isError(mod)) {
11611167 try returns.append(.i32);
11621168 }
11631169
11641170 // param types
11651171 for (params) |param_type| {
1166 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;
1172 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
11671173
11681174 switch (cc) {
11691175 .C => {
1170 const param_classes = abi.classifyType(param_type, target);
1176 const param_classes = abi.classifyType(param_type, mod);
11711177 for (param_classes) |class| {
11721178 if (class == .none) continue;
11731179 if (class == .direct) {
1174 const scalar_type = abi.scalarType(param_type, target);
1175 try temp_params.append(typeToValtype(scalar_type, target));
1180 const scalar_type = abi.scalarType(param_type, mod);
1181 try temp_params.append(typeToValtype(scalar_type, mod));
11761182 } else {
1177 try temp_params.append(typeToValtype(param_type, target));
1183 try temp_params.append(typeToValtype(param_type, mod));
11781184 }
11791185 }
11801186 },
1181 else => if (isByRef(param_type, target))
1187 else => if (isByRef(param_type, mod))
11821188 try temp_params.append(.i32)
11831189 else
1184 try temp_params.append(typeToValtype(param_type, target)),
1190 try temp_params.append(typeToValtype(param_type, mod)),
11851191 }
11861192 }
11871193
......@@ -1227,7 +1233,8 @@ pub fn generate(
12271233
12281234fn genFunc(func: *CodeGen) InnerError!void {
12291235 const fn_info = func.decl.ty.fnInfo();
1230 var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types, fn_info.return_type, func.target);
1236 const mod = func.bin_file.base.options.module.?;
1237 var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types, fn_info.return_type, mod);
12311238 defer func_type.deinit(func.gpa);
12321239 _ = try func.bin_file.storeDeclType(func.decl_index, func_type);
12331240
......@@ -1254,7 +1261,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
12541261 if (func_type.returns.len != 0 and func.air.instructions.len > 0) {
12551262 const inst = @intCast(u32, func.air.instructions.len - 1);
12561263 const last_inst_ty = func.air.typeOfIndex(inst);
1257 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime() or last_inst_ty.isNoReturn()) {
1264 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn()) {
12581265 try func.addTag(.@"unreachable");
12591266 }
12601267 }
......@@ -1335,6 +1342,7 @@ const CallWValues = struct {
13351342};
13361343
13371344fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWValues {
1345 const mod = func.bin_file.base.options.module.?;
13381346 const cc = fn_ty.fnCallingConvention();
13391347 const param_types = try func.gpa.alloc(Type, fn_ty.fnParamLen());
13401348 defer func.gpa.free(param_types);
......@@ -1351,7 +1359,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
13511359 // Check if we store the result as a pointer to the stack rather than
13521360 // by value
13531361 const fn_info = fn_ty.fnInfo();
1354 if (firstParamSRet(fn_info.cc, fn_info.return_type, func.target)) {
1362 if (firstParamSRet(fn_info.cc, fn_info.return_type, mod)) {
13551363 // the sret arg will be passed as first argument, therefore we
13561364 // set the `return_value` before allocating locals for regular args.
13571365 result.return_value = .{ .local = .{ .value = func.local_index, .references = 1 } };
......@@ -1361,7 +1369,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
13611369 switch (cc) {
13621370 .Unspecified => {
13631371 for (param_types) |ty| {
1364 if (!ty.hasRuntimeBitsIgnoreComptime()) {
1372 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
13651373 continue;
13661374 }
13671375
......@@ -1371,7 +1379,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
13711379 },
13721380 .C => {
13731381 for (param_types) |ty| {
1374 const ty_classes = abi.classifyType(ty, func.target);
1382 const ty_classes = abi.classifyType(ty, mod);
13751383 for (ty_classes) |class| {
13761384 if (class == .none) continue;
13771385 try args.append(.{ .local = .{ .value = func.local_index, .references = 1 } });
......@@ -1385,11 +1393,11 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
13851393 return result;
13861394}
13871395
1388fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, target: std.Target) bool {
1396fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, mod: *const Module) bool {
13891397 switch (cc) {
1390 .Unspecified, .Inline => return isByRef(return_type, target),
1398 .Unspecified, .Inline => return isByRef(return_type, mod),
13911399 .C => {
1392 const ty_classes = abi.classifyType(return_type, target);
1400 const ty_classes = abi.classifyType(return_type, mod);
13931401 if (ty_classes[0] == .indirect) return true;
13941402 if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true;
13951403 return false;
......@@ -1405,16 +1413,17 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
14051413 return func.lowerToStack(value);
14061414 }
14071415
1408 const ty_classes = abi.classifyType(ty, func.target);
1416 const mod = func.bin_file.base.options.module.?;
1417 const ty_classes = abi.classifyType(ty, mod);
14091418 assert(ty_classes[0] != .none);
1410 switch (ty.zigTypeTag()) {
1419 switch (ty.zigTypeTag(mod)) {
14111420 .Struct, .Union => {
14121421 if (ty_classes[0] == .indirect) {
14131422 return func.lowerToStack(value);
14141423 }
14151424 assert(ty_classes[0] == .direct);
1416 const scalar_type = abi.scalarType(ty, func.target);
1417 const abi_size = scalar_type.abiSize(func.target);
1425 const scalar_type = abi.scalarType(ty, mod);
1426 const abi_size = scalar_type.abiSize(mod);
14181427 try func.emitWValue(value);
14191428
14201429 // When the value lives in the virtual stack, we must load it onto the actual stack
......@@ -1422,12 +1431,12 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
14221431 const opcode = buildOpcode(.{
14231432 .op = .load,
14241433 .width = @intCast(u8, abi_size),
1425 .signedness = if (scalar_type.isSignedInt()) .signed else .unsigned,
1426 .valtype1 = typeToValtype(scalar_type, func.target),
1434 .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,
1435 .valtype1 = typeToValtype(scalar_type, mod),
14271436 });
14281437 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{
14291438 .offset = value.offset(),
1430 .alignment = scalar_type.abiAlignment(func.target),
1439 .alignment = scalar_type.abiAlignment(mod),
14311440 });
14321441 }
14331442 },
......@@ -1436,7 +1445,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
14361445 return func.lowerToStack(value);
14371446 }
14381447 assert(ty_classes[0] == .direct and ty_classes[1] == .direct);
1439 assert(ty.abiSize(func.target) == 16);
1448 assert(ty.abiSize(mod) == 16);
14401449 // in this case we have an integer or float that must be lowered as 2 i64's.
14411450 try func.emitWValue(value);
14421451 try func.addMemArg(.i64_load, .{ .offset = value.offset(), .alignment = 8 });
......@@ -1503,18 +1512,18 @@ fn restoreStackPointer(func: *CodeGen) !void {
15031512///
15041513/// Asserts Type has codegenbits
15051514fn allocStack(func: *CodeGen, ty: Type) !WValue {
1506 assert(ty.hasRuntimeBitsIgnoreComptime());
1515 const mod = func.bin_file.base.options.module.?;
1516 assert(ty.hasRuntimeBitsIgnoreComptime(mod));
15071517 if (func.initial_stack_value == .none) {
15081518 try func.initializeStack();
15091519 }
15101520
1511 const abi_size = std.math.cast(u32, ty.abiSize(func.target)) orelse {
1512 const module = func.bin_file.base.options.module.?;
1521 const abi_size = std.math.cast(u32, ty.abiSize(mod)) orelse {
15131522 return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1514 ty.fmt(module), ty.abiSize(func.target),
1523 ty.fmt(mod), ty.abiSize(mod),
15151524 });
15161525 };
1517 const abi_align = ty.abiAlignment(func.target);
1526 const abi_align = ty.abiAlignment(mod);
15181527
15191528 if (abi_align > func.stack_alignment) {
15201529 func.stack_alignment = abi_align;
......@@ -1531,6 +1540,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {
15311540/// This is different from allocStack where this will use the pointer's alignment
15321541/// if it is set, to ensure the stack alignment will be set correctly.
15331542fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
1543 const mod = func.bin_file.base.options.module.?;
15341544 const ptr_ty = func.air.typeOfIndex(inst);
15351545 const pointee_ty = ptr_ty.childType();
15361546
......@@ -1538,15 +1548,14 @@ fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
15381548 try func.initializeStack();
15391549 }
15401550
1541 if (!pointee_ty.hasRuntimeBitsIgnoreComptime()) {
1551 if (!pointee_ty.hasRuntimeBitsIgnoreComptime(mod)) {
15421552 return func.allocStack(Type.usize); // create a value containing just the stack pointer.
15431553 }
15441554
1545 const abi_alignment = ptr_ty.ptrAlignment(func.target);
1546 const abi_size = std.math.cast(u32, pointee_ty.abiSize(func.target)) orelse {
1547 const module = func.bin_file.base.options.module.?;
1555 const abi_alignment = ptr_ty.ptrAlignment(mod);
1556 const abi_size = std.math.cast(u32, pointee_ty.abiSize(mod)) orelse {
15481557 return func.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1549 pointee_ty.fmt(module), pointee_ty.abiSize(func.target),
1558 pointee_ty.fmt(mod), pointee_ty.abiSize(mod),
15501559 });
15511560 };
15521561 if (abi_alignment > func.stack_alignment) {
......@@ -1704,8 +1713,9 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch {
17041713
17051714/// For a given `Type`, will return true when the type will be passed
17061715/// by reference, rather than by value
1707fn isByRef(ty: Type, target: std.Target) bool {
1708 switch (ty.zigTypeTag()) {
1716fn isByRef(ty: Type, mod: *const Module) bool {
1717 const target = mod.getTarget();
1718 switch (ty.zigTypeTag(mod)) {
17091719 .Type,
17101720 .ComptimeInt,
17111721 .ComptimeFloat,
......@@ -1726,40 +1736,40 @@ fn isByRef(ty: Type, target: std.Target) bool {
17261736
17271737 .Array,
17281738 .Frame,
1729 => return ty.hasRuntimeBitsIgnoreComptime(),
1739 => return ty.hasRuntimeBitsIgnoreComptime(mod),
17301740 .Union => {
17311741 if (ty.castTag(.@"union")) |union_ty| {
17321742 if (union_ty.data.layout == .Packed) {
1733 return ty.abiSize(target) > 8;
1743 return ty.abiSize(mod) > 8;
17341744 }
17351745 }
1736 return ty.hasRuntimeBitsIgnoreComptime();
1746 return ty.hasRuntimeBitsIgnoreComptime(mod);
17371747 },
17381748 .Struct => {
17391749 if (ty.castTag(.@"struct")) |struct_ty| {
17401750 const struct_obj = struct_ty.data;
17411751 if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) {
1742 return isByRef(struct_obj.backing_int_ty, target);
1752 return isByRef(struct_obj.backing_int_ty, mod);
17431753 }
17441754 }
1745 return ty.hasRuntimeBitsIgnoreComptime();
1755 return ty.hasRuntimeBitsIgnoreComptime(mod);
17461756 },
1747 .Vector => return determineSimdStoreStrategy(ty, target) == .unrolled,
1748 .Int => return ty.intInfo(target).bits > 64,
1757 .Vector => return determineSimdStoreStrategy(ty, mod) == .unrolled,
1758 .Int => return ty.intInfo(mod).bits > 64,
17491759 .Float => return ty.floatBits(target) > 64,
17501760 .ErrorUnion => {
17511761 const pl_ty = ty.errorUnionPayload();
1752 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {
1762 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
17531763 return false;
17541764 }
17551765 return true;
17561766 },
17571767 .Optional => {
1758 if (ty.isPtrLikeOptional()) return false;
1768 if (ty.isPtrLikeOptional(mod)) return false;
17591769 var buf: Type.Payload.ElemType = undefined;
17601770 const pl_type = ty.optionalChild(&buf);
1761 if (pl_type.zigTypeTag() == .ErrorSet) return false;
1762 return pl_type.hasRuntimeBitsIgnoreComptime();
1771 if (pl_type.zigTypeTag(mod) == .ErrorSet) return false;
1772 return pl_type.hasRuntimeBitsIgnoreComptime(mod);
17631773 },
17641774 .Pointer => {
17651775 // Slices act like struct and will be passed by reference
......@@ -1778,10 +1788,11 @@ const SimdStoreStrategy = enum {
17781788/// This means when a given type is 128 bits and either the simd128 or relaxed-simd
17791789/// features are enabled, the function will return `.direct`. This would allow to store
17801790/// it using a instruction, rather than an unrolled version.
1781fn determineSimdStoreStrategy(ty: Type, target: std.Target) SimdStoreStrategy {
1782 std.debug.assert(ty.zigTypeTag() == .Vector);
1783 if (ty.bitSize(target) != 128) return .unrolled;
1791fn determineSimdStoreStrategy(ty: Type, mod: *const Module) SimdStoreStrategy {
1792 std.debug.assert(ty.zigTypeTag(mod) == .Vector);
1793 if (ty.bitSize(mod) != 128) return .unrolled;
17841794 const hasFeature = std.Target.wasm.featureSetHas;
1795 const target = mod.getTarget();
17851796 const features = target.cpu.features;
17861797 if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) {
17871798 return .direct;
......@@ -2084,32 +2095,33 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
20842095 const operand = try func.resolveInst(un_op);
20852096 const fn_info = func.decl.ty.fnInfo();
20862097 const ret_ty = fn_info.return_type;
2098 const mod = func.bin_file.base.options.module.?;
20872099
20882100 // result must be stored in the stack and we return a pointer
20892101 // to the stack instead
20902102 if (func.return_value != .none) {
20912103 try func.store(func.return_value, operand, ret_ty, 0);
2092 } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime()) {
2093 switch (ret_ty.zigTypeTag()) {
2104 } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2105 switch (ret_ty.zigTypeTag(mod)) {
20942106 // Aggregate types can be lowered as a singular value
20952107 .Struct, .Union => {
2096 const scalar_type = abi.scalarType(ret_ty, func.target);
2108 const scalar_type = abi.scalarType(ret_ty, mod);
20972109 try func.emitWValue(operand);
20982110 const opcode = buildOpcode(.{
20992111 .op = .load,
2100 .width = @intCast(u8, scalar_type.abiSize(func.target) * 8),
2101 .signedness = if (scalar_type.isSignedInt()) .signed else .unsigned,
2102 .valtype1 = typeToValtype(scalar_type, func.target),
2112 .width = @intCast(u8, scalar_type.abiSize(mod) * 8),
2113 .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,
2114 .valtype1 = typeToValtype(scalar_type, mod),
21032115 });
21042116 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{
21052117 .offset = operand.offset(),
2106 .alignment = scalar_type.abiAlignment(func.target),
2118 .alignment = scalar_type.abiAlignment(mod),
21072119 });
21082120 },
21092121 else => try func.emitWValue(operand),
21102122 }
21112123 } else {
2112 if (!ret_ty.hasRuntimeBitsIgnoreComptime() and ret_ty.isError()) {
2124 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and ret_ty.isError(mod)) {
21132125 try func.addImm32(0);
21142126 } else {
21152127 try func.emitWValue(operand);
......@@ -2123,14 +2135,15 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21232135
21242136fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21252137 const child_type = func.air.typeOfIndex(inst).childType();
2138 const mod = func.bin_file.base.options.module.?;
21262139
21272140 var result = result: {
2128 if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime()) {
2141 if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
21292142 break :result try func.allocStack(Type.usize); // create pointer to void
21302143 }
21312144
21322145 const fn_info = func.decl.ty.fnInfo();
2133 if (firstParamSRet(fn_info.cc, fn_info.return_type, func.target)) {
2146 if (firstParamSRet(fn_info.cc, fn_info.return_type, mod)) {
21342147 break :result func.return_value;
21352148 }
21362149
......@@ -2141,16 +2154,17 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21412154}
21422155
21432156fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2157 const mod = func.bin_file.base.options.module.?;
21442158 const un_op = func.air.instructions.items(.data)[inst].un_op;
21452159 const operand = try func.resolveInst(un_op);
21462160 const ret_ty = func.air.typeOf(un_op).childType();
21472161
21482162 const fn_info = func.decl.ty.fnInfo();
2149 if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {
2150 if (ret_ty.isError()) {
2163 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2164 if (ret_ty.isError(mod)) {
21512165 try func.addImm32(0);
21522166 }
2153 } else if (!firstParamSRet(fn_info.cc, fn_info.return_type, func.target)) {
2167 } else if (!firstParamSRet(fn_info.cc, fn_info.return_type, mod)) {
21542168 // leave on the stack
21552169 _ = try func.load(operand, ret_ty, 0);
21562170 }
......@@ -2167,26 +2181,26 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
21672181 const args = @ptrCast([]const Air.Inst.Ref, func.air.extra[extra.end..][0..extra.data.args_len]);
21682182 const ty = func.air.typeOf(pl_op.operand);
21692183
2170 const fn_ty = switch (ty.zigTypeTag()) {
2184 const mod = func.bin_file.base.options.module.?;
2185 const fn_ty = switch (ty.zigTypeTag(mod)) {
21712186 .Fn => ty,
21722187 .Pointer => ty.childType(),
21732188 else => unreachable,
21742189 };
21752190 const ret_ty = fn_ty.fnReturnType();
21762191 const fn_info = fn_ty.fnInfo();
2177 const first_param_sret = firstParamSRet(fn_info.cc, fn_info.return_type, func.target);
2192 const first_param_sret = firstParamSRet(fn_info.cc, fn_info.return_type, mod);
21782193
21792194 const callee: ?Decl.Index = blk: {
2180 const func_val = func.air.value(pl_op.operand) orelse break :blk null;
2181 const module = func.bin_file.base.options.module.?;
2195 const func_val = func.air.value(pl_op.operand, mod) orelse break :blk null;
21822196
21832197 if (func_val.castTag(.function)) |function| {
21842198 _ = try func.bin_file.getOrCreateAtomForDecl(function.data.owner_decl);
21852199 break :blk function.data.owner_decl;
21862200 } else if (func_val.castTag(.extern_fn)) |extern_fn| {
2187 const ext_decl = module.declPtr(extern_fn.data.owner_decl);
2201 const ext_decl = mod.declPtr(extern_fn.data.owner_decl);
21882202 const ext_info = ext_decl.ty.fnInfo();
2189 var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types, ext_info.return_type, func.target);
2203 var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types, ext_info.return_type, mod);
21902204 defer func_type.deinit(func.gpa);
21912205 const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_fn.data.owner_decl);
21922206 const atom = func.bin_file.getAtomPtr(atom_index);
......@@ -2215,7 +2229,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22152229 const arg_val = try func.resolveInst(arg);
22162230
22172231 const arg_ty = func.air.typeOf(arg);
2218 if (!arg_ty.hasRuntimeBitsIgnoreComptime()) continue;
2232 if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
22192233
22202234 try func.lowerArg(fn_ty.fnInfo().cc, arg_ty, arg_val);
22212235 }
......@@ -2226,11 +2240,11 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22262240 } else {
22272241 // in this case we call a function pointer
22282242 // so load its value onto the stack
2229 std.debug.assert(ty.zigTypeTag() == .Pointer);
2243 std.debug.assert(ty.zigTypeTag(mod) == .Pointer);
22302244 const operand = try func.resolveInst(pl_op.operand);
22312245 try func.emitWValue(operand);
22322246
2233 var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types, fn_info.return_type, func.target);
2247 var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types, fn_info.return_type, mod);
22342248 defer fn_type.deinit(func.gpa);
22352249
22362250 const fn_type_index = try func.bin_file.putOrGetFuncType(fn_type);
......@@ -2238,7 +2252,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22382252 }
22392253
22402254 const result_value = result_value: {
2241 if (!ret_ty.hasRuntimeBitsIgnoreComptime() and !ret_ty.isError()) {
2255 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {
22422256 break :result_value WValue{ .none = {} };
22432257 } else if (ret_ty.isNoReturn()) {
22442258 try func.addTag(.@"unreachable");
......@@ -2246,10 +2260,10 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22462260 } else if (first_param_sret) {
22472261 break :result_value sret;
22482262 // TODO: Make this less fragile and optimize
2249 } else if (fn_ty.fnInfo().cc == .C and ret_ty.zigTypeTag() == .Struct or ret_ty.zigTypeTag() == .Union) {
2263 } else if (fn_ty.fnInfo().cc == .C and ret_ty.zigTypeTag(mod) == .Struct or ret_ty.zigTypeTag(mod) == .Union) {
22502264 const result_local = try func.allocLocal(ret_ty);
22512265 try func.addLabel(.local_set, result_local.local.value);
2252 const scalar_type = abi.scalarType(ret_ty, func.target);
2266 const scalar_type = abi.scalarType(ret_ty, mod);
22532267 const result = try func.allocStack(scalar_type);
22542268 try func.store(result, result_local, scalar_type, 0);
22552269 break :result_value result;
......@@ -2272,6 +2286,7 @@ fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
22722286}
22732287
22742288fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
2289 const mod = func.bin_file.base.options.module.?;
22752290 if (safety) {
22762291 // TODO if the value is undef, write 0xaa bytes to dest
22772292 } else {
......@@ -2290,17 +2305,13 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
22902305 } else {
22912306 // at this point we have a non-natural alignment, we must
22922307 // load the value, and then shift+or the rhs into the result location.
2293 var int_ty_payload: Type.Payload.Bits = .{
2294 .base = .{ .tag = .int_unsigned },
2295 .data = ptr_info.host_size * 8,
2296 };
2297 const int_elem_ty = Type.initPayload(&int_ty_payload.base);
2308 const int_elem_ty = try mod.intType(.unsigned, ptr_info.host_size * 8);
22982309
2299 if (isByRef(int_elem_ty, func.target)) {
2310 if (isByRef(int_elem_ty, mod)) {
23002311 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});
23012312 }
23022313
2303 var mask = @intCast(u64, (@as(u65, 1) << @intCast(u7, ty.bitSize(func.target))) - 1);
2314 var mask = @intCast(u64, (@as(u65, 1) << @intCast(u7, ty.bitSize(mod))) - 1);
23042315 mask <<= @intCast(u6, ptr_info.bit_offset);
23052316 mask ^= ~@as(u64, 0);
23062317 const shift_val = if (ptr_info.host_size <= 4)
......@@ -2329,11 +2340,12 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
23292340
23302341fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void {
23312342 assert(!(lhs != .stack and rhs == .stack));
2332 const abi_size = ty.abiSize(func.target);
2333 switch (ty.zigTypeTag()) {
2343 const mod = func.bin_file.base.options.module.?;
2344 const abi_size = ty.abiSize(mod);
2345 switch (ty.zigTypeTag(mod)) {
23342346 .ErrorUnion => {
23352347 const pl_ty = ty.errorUnionPayload();
2336 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {
2348 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
23372349 return func.store(lhs, rhs, Type.anyerror, 0);
23382350 }
23392351
......@@ -2341,26 +2353,26 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
23412353 return func.memcpy(lhs, rhs, .{ .imm32 = len });
23422354 },
23432355 .Optional => {
2344 if (ty.isPtrLikeOptional()) {
2356 if (ty.isPtrLikeOptional(mod)) {
23452357 return func.store(lhs, rhs, Type.usize, 0);
23462358 }
23472359 var buf: Type.Payload.ElemType = undefined;
23482360 const pl_ty = ty.optionalChild(&buf);
2349 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {
2361 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
23502362 return func.store(lhs, rhs, Type.u8, 0);
23512363 }
2352 if (pl_ty.zigTypeTag() == .ErrorSet) {
2364 if (pl_ty.zigTypeTag(mod) == .ErrorSet) {
23532365 return func.store(lhs, rhs, Type.anyerror, 0);
23542366 }
23552367
23562368 const len = @intCast(u32, abi_size);
23572369 return func.memcpy(lhs, rhs, .{ .imm32 = len });
23582370 },
2359 .Struct, .Array, .Union => if (isByRef(ty, func.target)) {
2371 .Struct, .Array, .Union => if (isByRef(ty, mod)) {
23602372 const len = @intCast(u32, abi_size);
23612373 return func.memcpy(lhs, rhs, .{ .imm32 = len });
23622374 },
2363 .Vector => switch (determineSimdStoreStrategy(ty, func.target)) {
2375 .Vector => switch (determineSimdStoreStrategy(ty, mod)) {
23642376 .unrolled => {
23652377 const len = @intCast(u32, abi_size);
23662378 return func.memcpy(lhs, rhs, .{ .imm32 = len });
......@@ -2374,7 +2386,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
23742386 try func.mir_extra.appendSlice(func.gpa, &[_]u32{
23752387 std.wasm.simdOpcode(.v128_store),
23762388 offset + lhs.offset(),
2377 ty.abiAlignment(func.target),
2389 ty.abiAlignment(mod),
23782390 });
23792391 return func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
23802392 },
......@@ -2404,7 +2416,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
24042416 try func.store(.{ .stack = {} }, msb, Type.u64, 8 + lhs.offset());
24052417 return;
24062418 } else if (abi_size > 16) {
2407 try func.memcpy(lhs, rhs, .{ .imm32 = @intCast(u32, ty.abiSize(func.target)) });
2419 try func.memcpy(lhs, rhs, .{ .imm32 = @intCast(u32, ty.abiSize(mod)) });
24082420 },
24092421 else => if (abi_size > 8) {
24102422 return func.fail("TODO: `store` for type `{}` with abisize `{d}`", .{
......@@ -2418,7 +2430,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
24182430 // into lhs, so we calculate that and emit that instead
24192431 try func.lowerToStack(rhs);
24202432
2421 const valtype = typeToValtype(ty, func.target);
2433 const valtype = typeToValtype(ty, mod);
24222434 const opcode = buildOpcode(.{
24232435 .valtype1 = valtype,
24242436 .width = @intCast(u8, abi_size * 8),
......@@ -2428,21 +2440,22 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
24282440 // store rhs value at stack pointer's location in memory
24292441 try func.addMemArg(
24302442 Mir.Inst.Tag.fromOpcode(opcode),
2431 .{ .offset = offset + lhs.offset(), .alignment = ty.abiAlignment(func.target) },
2443 .{ .offset = offset + lhs.offset(), .alignment = ty.abiAlignment(mod) },
24322444 );
24332445}
24342446
24352447fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2448 const mod = func.bin_file.base.options.module.?;
24362449 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
24372450 const operand = try func.resolveInst(ty_op.operand);
24382451 const ty = func.air.getRefType(ty_op.ty);
24392452 const ptr_ty = func.air.typeOf(ty_op.operand);
24402453 const ptr_info = ptr_ty.ptrInfo().data;
24412454
2442 if (!ty.hasRuntimeBitsIgnoreComptime()) return func.finishAir(inst, .none, &.{ty_op.operand});
2455 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return func.finishAir(inst, .none, &.{ty_op.operand});
24432456
24442457 const result = result: {
2445 if (isByRef(ty, func.target)) {
2458 if (isByRef(ty, mod)) {
24462459 const new_local = try func.allocStack(ty);
24472460 try func.store(new_local, operand, ty, 0);
24482461 break :result new_local;
......@@ -2455,11 +2468,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24552468
24562469 // at this point we have a non-natural alignment, we must
24572470 // shift the value to obtain the correct bit.
2458 var int_ty_payload: Type.Payload.Bits = .{
2459 .base = .{ .tag = .int_unsigned },
2460 .data = ptr_info.host_size * 8,
2461 };
2462 const int_elem_ty = Type.initPayload(&int_ty_payload.base);
2471 const int_elem_ty = try mod.intType(.unsigned, ptr_info.host_size * 8);
24632472 const shift_val = if (ptr_info.host_size <= 4)
24642473 WValue{ .imm32 = ptr_info.bit_offset }
24652474 else if (ptr_info.host_size <= 8)
......@@ -2479,25 +2488,26 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24792488/// Loads an operand from the linear memory section.
24802489/// NOTE: Leaves the value on the stack.
24812490fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue {
2491 const mod = func.bin_file.base.options.module.?;
24822492 // load local's value from memory by its stack position
24832493 try func.emitWValue(operand);
24842494
2485 if (ty.zigTypeTag() == .Vector) {
2495 if (ty.zigTypeTag(mod) == .Vector) {
24862496 // TODO: Add helper functions for simd opcodes
24872497 const extra_index = @intCast(u32, func.mir_extra.items.len);
24882498 // stores as := opcode, offset, alignment (opcode::memarg)
24892499 try func.mir_extra.appendSlice(func.gpa, &[_]u32{
24902500 std.wasm.simdOpcode(.v128_load),
24912501 offset + operand.offset(),
2492 ty.abiAlignment(func.target),
2502 ty.abiAlignment(mod),
24932503 });
24942504 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
24952505 return WValue{ .stack = {} };
24962506 }
24972507
2498 const abi_size = @intCast(u8, ty.abiSize(func.target));
2508 const abi_size = @intCast(u8, ty.abiSize(mod));
24992509 const opcode = buildOpcode(.{
2500 .valtype1 = typeToValtype(ty, func.target),
2510 .valtype1 = typeToValtype(ty, mod),
25012511 .width = abi_size * 8,
25022512 .op = .load,
25032513 .signedness = .unsigned,
......@@ -2505,7 +2515,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
25052515
25062516 try func.addMemArg(
25072517 Mir.Inst.Tag.fromOpcode(opcode),
2508 .{ .offset = offset + operand.offset(), .alignment = ty.abiAlignment(func.target) },
2518 .{ .offset = offset + operand.offset(), .alignment = ty.abiAlignment(mod) },
25092519 );
25102520
25112521 return WValue{ .stack = {} };
......@@ -2516,8 +2526,9 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25162526 const arg = func.args[arg_index];
25172527 const cc = func.decl.ty.fnInfo().cc;
25182528 const arg_ty = func.air.typeOfIndex(inst);
2529 const mod = func.bin_file.base.options.module.?;
25192530 if (cc == .C) {
2520 const arg_classes = abi.classifyType(arg_ty, func.target);
2531 const arg_classes = abi.classifyType(arg_ty, mod);
25212532 for (arg_classes) |class| {
25222533 if (class != .none) {
25232534 func.arg_index += 1;
......@@ -2527,7 +2538,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25272538 // When we have an argument that's passed using more than a single parameter,
25282539 // we combine them into a single stack value
25292540 if (arg_classes[0] == .direct and arg_classes[1] == .direct) {
2530 if (arg_ty.zigTypeTag() != .Int and arg_ty.zigTypeTag() != .Float) {
2541 if (arg_ty.zigTypeTag(mod) != .Int and arg_ty.zigTypeTag(mod) != .Float) {
25312542 return func.fail(
25322543 "TODO: Implement C-ABI argument for type '{}'",
25332544 .{arg_ty.fmt(func.bin_file.base.options.module.?)},
......@@ -2557,6 +2568,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25572568}
25582569
25592570fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2571 const mod = func.bin_file.base.options.module.?;
25602572 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
25612573 const lhs = try func.resolveInst(bin_op.lhs);
25622574 const rhs = try func.resolveInst(bin_op.rhs);
......@@ -2570,10 +2582,10 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
25702582 // For big integers we can ignore this as we will call into compiler-rt which handles this.
25712583 const result = switch (op) {
25722584 .shr, .shl => res: {
2573 const lhs_wasm_bits = toWasmBits(@intCast(u16, lhs_ty.bitSize(func.target))) orelse {
2585 const lhs_wasm_bits = toWasmBits(@intCast(u16, lhs_ty.bitSize(mod))) orelse {
25742586 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
25752587 };
2576 const rhs_wasm_bits = toWasmBits(@intCast(u16, rhs_ty.bitSize(func.target))).?;
2588 const rhs_wasm_bits = toWasmBits(@intCast(u16, rhs_ty.bitSize(mod))).?;
25772589 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {
25782590 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);
25792591 break :blk try tmp.toLocal(func, lhs_ty);
......@@ -2593,6 +2605,7 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
25932605/// Performs a binary operation on the given `WValue`'s
25942606/// NOTE: THis leaves the value on top of the stack.
25952607fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
2608 const mod = func.bin_file.base.options.module.?;
25962609 assert(!(lhs != .stack and rhs == .stack));
25972610
25982611 if (ty.isAnyFloat()) {
......@@ -2600,8 +2613,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
26002613 return func.floatOp(float_op, ty, &.{ lhs, rhs });
26012614 }
26022615
2603 if (isByRef(ty, func.target)) {
2604 if (ty.zigTypeTag() == .Int) {
2616 if (isByRef(ty, mod)) {
2617 if (ty.zigTypeTag(mod) == .Int) {
26052618 return func.binOpBigInt(lhs, rhs, ty, op);
26062619 } else {
26072620 return func.fail(
......@@ -2613,8 +2626,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
26132626
26142627 const opcode: wasm.Opcode = buildOpcode(.{
26152628 .op = op,
2616 .valtype1 = typeToValtype(ty, func.target),
2617 .signedness = if (ty.isSignedInt()) .signed else .unsigned,
2629 .valtype1 = typeToValtype(ty, mod),
2630 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,
26182631 });
26192632 try func.emitWValue(lhs);
26202633 try func.emitWValue(rhs);
......@@ -2625,7 +2638,8 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
26252638}
26262639
26272640fn binOpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
2628 if (ty.intInfo(func.target).bits > 128) {
2641 const mod = func.bin_file.base.options.module.?;
2642 if (ty.intInfo(mod).bits > 128) {
26292643 return func.fail("TODO: Implement binary operation for big integers larger than 128 bits", .{});
26302644 }
26312645
......@@ -2763,7 +2777,8 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError
27632777}
27642778
27652779fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) InnerError!WValue {
2766 if (ty.zigTypeTag() == .Vector) {
2780 const mod = func.bin_file.base.options.module.?;
2781 if (ty.zigTypeTag(mod) == .Vector) {
27672782 return func.fail("TODO: Implement floatOps for vectors", .{});
27682783 }
27692784
......@@ -2773,7 +2788,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
27732788 for (args) |operand| {
27742789 try func.emitWValue(operand);
27752790 }
2776 const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, func.target) });
2791 const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, mod) });
27772792 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
27782793 return .stack;
27792794 }
......@@ -2827,6 +2842,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
28272842}
28282843
28292844fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2845 const mod = func.bin_file.base.options.module.?;
28302846 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
28312847
28322848 const lhs = try func.resolveInst(bin_op.lhs);
......@@ -2834,7 +2850,7 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
28342850 const lhs_ty = func.air.typeOf(bin_op.lhs);
28352851 const rhs_ty = func.air.typeOf(bin_op.rhs);
28362852
2837 if (lhs_ty.zigTypeTag() == .Vector or rhs_ty.zigTypeTag() == .Vector) {
2853 if (lhs_ty.zigTypeTag(mod) == .Vector or rhs_ty.zigTypeTag(mod) == .Vector) {
28382854 return func.fail("TODO: Implement wrapping arithmetic for vectors", .{});
28392855 }
28402856
......@@ -2845,10 +2861,10 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
28452861 // For big integers we can ignore this as we will call into compiler-rt which handles this.
28462862 const result = switch (op) {
28472863 .shr, .shl => res: {
2848 const lhs_wasm_bits = toWasmBits(@intCast(u16, lhs_ty.bitSize(func.target))) orelse {
2864 const lhs_wasm_bits = toWasmBits(@intCast(u16, lhs_ty.bitSize(mod))) orelse {
28492865 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
28502866 };
2851 const rhs_wasm_bits = toWasmBits(@intCast(u16, rhs_ty.bitSize(func.target))).?;
2867 const rhs_wasm_bits = toWasmBits(@intCast(u16, rhs_ty.bitSize(mod))).?;
28522868 const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {
28532869 const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);
28542870 break :blk try tmp.toLocal(func, lhs_ty);
......@@ -2877,8 +2893,9 @@ fn wrapBinOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr
28772893/// Asserts `Type` is <= 128 bits.
28782894/// NOTE: When the Type is <= 64 bits, leaves the value on top of the stack.
28792895fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
2880 assert(ty.abiSize(func.target) <= 16);
2881 const bitsize = @intCast(u16, ty.bitSize(func.target));
2896 const mod = func.bin_file.base.options.module.?;
2897 assert(ty.abiSize(mod) <= 16);
2898 const bitsize = @intCast(u16, ty.bitSize(mod));
28822899 const wasm_bits = toWasmBits(bitsize) orelse {
28832900 return func.fail("TODO: Implement wrapOperand for bitsize '{d}'", .{bitsize});
28842901 };
......@@ -2915,6 +2932,7 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
29152932}
29162933
29172934fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue {
2935 const mod = func.bin_file.base.options.module.?;
29182936 switch (ptr_val.tag()) {
29192937 .decl_ref_mut => {
29202938 const decl_index = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;
......@@ -2932,15 +2950,15 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue
29322950 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
29332951 const parent_ty = field_ptr.container_ty;
29342952
2935 const field_offset = switch (parent_ty.zigTypeTag()) {
2953 const field_offset = switch (parent_ty.zigTypeTag(mod)) {
29362954 .Struct => switch (parent_ty.containerLayout()) {
2937 .Packed => parent_ty.packedStructFieldByteOffset(field_ptr.field_index, func.target),
2938 else => parent_ty.structFieldOffset(field_ptr.field_index, func.target),
2955 .Packed => parent_ty.packedStructFieldByteOffset(field_ptr.field_index, mod),
2956 else => parent_ty.structFieldOffset(field_ptr.field_index, mod),
29392957 },
29402958 .Union => switch (parent_ty.containerLayout()) {
29412959 .Packed => 0,
29422960 else => blk: {
2943 const layout: Module.Union.Layout = parent_ty.unionGetLayout(func.target);
2961 const layout: Module.Union.Layout = parent_ty.unionGetLayout(mod);
29442962 if (layout.payload_size == 0) break :blk 0;
29452963 if (layout.payload_align > layout.tag_align) break :blk 0;
29462964
......@@ -2964,7 +2982,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue
29642982 .elem_ptr => {
29652983 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
29662984 const index = elem_ptr.index;
2967 const elem_offset = index * elem_ptr.elem_ty.abiSize(func.target);
2985 const elem_offset = index * elem_ptr.elem_ty.abiSize(mod);
29682986 return func.lowerParentPtr(elem_ptr.array_ptr, offset + @intCast(u32, elem_offset));
29692987 },
29702988 .opt_payload_ptr => {
......@@ -2976,9 +2994,9 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue
29762994}
29772995
29782996fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.Index, offset: u32) InnerError!WValue {
2979 const module = func.bin_file.base.options.module.?;
2980 const decl = module.declPtr(decl_index);
2981 module.markDeclAlive(decl);
2997 const mod = func.bin_file.base.options.module.?;
2998 const decl = mod.declPtr(decl_index);
2999 mod.markDeclAlive(decl);
29823000 var ptr_ty_payload: Type.Payload.ElemType = .{
29833001 .base = .{ .tag = .single_mut_pointer },
29843002 .data = decl.ty,
......@@ -2992,18 +3010,18 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Ind
29923010 return WValue{ .memory = try func.bin_file.lowerUnnamedConst(tv, decl_index) };
29933011 }
29943012
2995 const module = func.bin_file.base.options.module.?;
2996 const decl = module.declPtr(decl_index);
2997 if (decl.ty.zigTypeTag() != .Fn and !decl.ty.hasRuntimeBitsIgnoreComptime()) {
3013 const mod = func.bin_file.base.options.module.?;
3014 const decl = mod.declPtr(decl_index);
3015 if (decl.ty.zigTypeTag(mod) != .Fn and !decl.ty.hasRuntimeBitsIgnoreComptime(mod)) {
29983016 return WValue{ .imm32 = 0xaaaaaaaa };
29993017 }
30003018
3001 module.markDeclAlive(decl);
3019 mod.markDeclAlive(decl);
30023020 const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index);
30033021 const atom = func.bin_file.getAtom(atom_index);
30043022
30053023 const target_sym_index = atom.sym_index;
3006 if (decl.ty.zigTypeTag() == .Fn) {
3024 if (decl.ty.zigTypeTag(mod) == .Fn) {
30073025 try func.bin_file.addTableFunction(target_sym_index);
30083026 return WValue{ .function_index = target_sym_index };
30093027 } else if (offset == 0) {
......@@ -3041,31 +3059,31 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
30413059 const decl_index = decl_ref_mut.data.decl_index;
30423060 return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl_index, 0);
30433061 }
3044 const target = func.target;
3045 switch (ty.zigTypeTag()) {
3062 const mod = func.bin_file.base.options.module.?;
3063 switch (ty.zigTypeTag(mod)) {
30463064 .Void => return WValue{ .none = {} },
30473065 .Int => {
3048 const int_info = ty.intInfo(func.target);
3066 const int_info = ty.intInfo(mod);
30493067 switch (int_info.signedness) {
30503068 .signed => switch (int_info.bits) {
30513069 0...32 => return WValue{ .imm32 = @intCast(u32, toTwosComplement(
3052 val.toSignedInt(target),
3070 val.toSignedInt(mod),
30533071 @intCast(u6, int_info.bits),
30543072 )) },
30553073 33...64 => return WValue{ .imm64 = toTwosComplement(
3056 val.toSignedInt(target),
3074 val.toSignedInt(mod),
30573075 @intCast(u7, int_info.bits),
30583076 ) },
30593077 else => unreachable,
30603078 },
30613079 .unsigned => switch (int_info.bits) {
3062 0...32 => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
3063 33...64 => return WValue{ .imm64 = val.toUnsignedInt(target) },
3080 0...32 => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(mod)) },
3081 33...64 => return WValue{ .imm64 = val.toUnsignedInt(mod) },
30643082 else => unreachable,
30653083 },
30663084 }
30673085 },
3068 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
3086 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(mod)) },
30693087 .Float => switch (ty.floatBits(func.target)) {
30703088 16 => return WValue{ .imm32 = @bitCast(u16, val.toFloat(f16)) },
30713089 32 => return WValue{ .float32 = val.toFloat(f32) },
......@@ -3074,7 +3092,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
30743092 },
30753093 .Pointer => switch (val.tag()) {
30763094 .field_ptr, .elem_ptr, .opt_payload_ptr => return func.lowerParentPtr(val, 0),
3077 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
3095 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(mod)) },
30783096 .zero, .null_value => return WValue{ .imm32 = 0 },
30793097 else => return func.fail("Wasm TODO: lowerConstant for other const pointer tag {}", .{val.tag()}),
30803098 },
......@@ -3100,8 +3118,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
31003118 else => return func.fail("TODO: lowerConstant for enum tag: {}", .{ty.tag()}),
31013119 }
31023120 } else {
3103 var int_tag_buffer: Type.Payload.Bits = undefined;
3104 const int_tag_ty = ty.intTagType(&int_tag_buffer);
3121 const int_tag_ty = ty.intTagType();
31053122 return func.lowerConstant(val, int_tag_ty);
31063123 }
31073124 },
......@@ -3115,7 +3132,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
31153132 .ErrorUnion => {
31163133 const error_type = ty.errorUnionSet();
31173134 const payload_type = ty.errorUnionPayload();
3118 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {
3135 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
31193136 // We use the error type directly as the type.
31203137 const is_pl = val.errorUnionIsPayload();
31213138 const err_val = if (!is_pl) val else Value.initTag(.zero);
......@@ -3123,12 +3140,12 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
31233140 }
31243141 return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});
31253142 },
3126 .Optional => if (ty.optionalReprIsPayload()) {
3143 .Optional => if (ty.optionalReprIsPayload(mod)) {
31273144 var buf: Type.Payload.ElemType = undefined;
31283145 const pl_ty = ty.optionalChild(&buf);
31293146 if (val.castTag(.opt_payload)) |payload| {
31303147 return func.lowerConstant(payload.data, pl_ty);
3131 } else if (val.isNull()) {
3148 } else if (val.isNull(mod)) {
31323149 return WValue{ .imm32 = 0 };
31333150 } else {
31343151 return func.lowerConstant(val, pl_ty);
......@@ -3150,7 +3167,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
31503167 return func.lowerConstant(int_val, struct_obj.backing_int_ty);
31513168 },
31523169 .Vector => {
3153 assert(determineSimdStoreStrategy(ty, target) == .direct);
3170 assert(determineSimdStoreStrategy(ty, mod) == .direct);
31543171 var buf: [16]u8 = undefined;
31553172 val.writeToMemory(ty, func.bin_file.base.options.module.?, &buf) catch unreachable;
31563173 return func.storeSimdImmd(buf);
......@@ -3176,9 +3193,10 @@ fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue {
31763193}
31773194
31783195fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3179 switch (ty.zigTypeTag()) {
3196 const mod = func.bin_file.base.options.module.?;
3197 switch (ty.zigTypeTag(mod)) {
31803198 .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa },
3181 .Int, .Enum => switch (ty.intInfo(func.target).bits) {
3199 .Int, .Enum => switch (ty.intInfo(mod).bits) {
31823200 0...32 => return WValue{ .imm32 = 0xaaaaaaaa },
31833201 33...64 => return WValue{ .imm64 = 0xaaaaaaaaaaaaaaaa },
31843202 else => unreachable,
......@@ -3197,7 +3215,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
31973215 .Optional => {
31983216 var buf: Type.Payload.ElemType = undefined;
31993217 const pl_ty = ty.optionalChild(&buf);
3200 if (ty.optionalReprIsPayload()) {
3218 if (ty.optionalReprIsPayload(mod)) {
32013219 return func.emitUndefined(pl_ty);
32023220 }
32033221 return WValue{ .imm32 = 0xaaaaaaaa };
......@@ -3210,7 +3228,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
32103228 assert(struct_obj.layout == .Packed);
32113229 return func.emitUndefined(struct_obj.backing_int_ty);
32123230 },
3213 else => return func.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag()}),
3231 else => return func.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag(mod)}),
32143232 }
32153233}
32163234
......@@ -3218,8 +3236,8 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
32183236/// It's illegal to provide a value with a type that cannot be represented
32193237/// as an integer value.
32203238fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
3221 const target = func.target;
3222 switch (ty.zigTypeTag()) {
3239 const mod = func.bin_file.base.options.module.?;
3240 switch (ty.zigTypeTag(mod)) {
32233241 .Enum => {
32243242 if (val.castTag(.enum_field_index)) |field_index| {
32253243 switch (ty.tag()) {
......@@ -3239,35 +3257,35 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
32393257 else => unreachable,
32403258 }
32413259 } else {
3242 var int_tag_buffer: Type.Payload.Bits = undefined;
3243 const int_tag_ty = ty.intTagType(&int_tag_buffer);
3260 const int_tag_ty = ty.intTagType();
32443261 return func.valueAsI32(val, int_tag_ty);
32453262 }
32463263 },
3247 .Int => switch (ty.intInfo(func.target).signedness) {
3248 .signed => return @truncate(i32, val.toSignedInt(target)),
3249 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt(target))),
3264 .Int => switch (ty.intInfo(mod).signedness) {
3265 .signed => return @truncate(i32, val.toSignedInt(mod)),
3266 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt(mod))),
32503267 },
32513268 .ErrorSet => {
32523269 const kv = func.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function
32533270 return @bitCast(i32, kv.value);
32543271 },
3255 .Bool => return @intCast(i32, val.toSignedInt(target)),
3256 .Pointer => return @intCast(i32, val.toSignedInt(target)),
3272 .Bool => return @intCast(i32, val.toSignedInt(mod)),
3273 .Pointer => return @intCast(i32, val.toSignedInt(mod)),
32573274 else => unreachable, // Programmer called this function for an illegal type
32583275 }
32593276}
32603277
32613278fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3279 const mod = func.bin_file.base.options.module.?;
32623280 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
32633281 const block_ty = func.air.getRefType(ty_pl.ty);
3264 const wasm_block_ty = genBlockType(block_ty, func.target);
3282 const wasm_block_ty = genBlockType(block_ty, mod);
32653283 const extra = func.air.extraData(Air.Block, ty_pl.payload);
32663284 const body = func.air.extra[extra.end..][0..extra.data.body_len];
32673285
32683286 // if wasm_block_ty is non-empty, we create a register to store the temporary value
32693287 const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {
3270 const ty: Type = if (isByRef(block_ty, func.target)) Type.u32 else block_ty;
3288 const ty: Type = if (isByRef(block_ty, mod)) Type.u32 else block_ty;
32713289 break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten
32723290 } else WValue.none;
32733291
......@@ -3379,16 +3397,17 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In
33793397/// NOTE: This leaves the result on top of the stack, rather than a new local.
33803398fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOperator) InnerError!WValue {
33813399 assert(!(lhs != .stack and rhs == .stack));
3382 if (ty.zigTypeTag() == .Optional and !ty.optionalReprIsPayload()) {
3400 const mod = func.bin_file.base.options.module.?;
3401 if (ty.zigTypeTag(mod) == .Optional and !ty.optionalReprIsPayload(mod)) {
33833402 var buf: Type.Payload.ElemType = undefined;
33843403 const payload_ty = ty.optionalChild(&buf);
3385 if (payload_ty.hasRuntimeBitsIgnoreComptime()) {
3404 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
33863405 // When we hit this case, we must check the value of optionals
33873406 // that are not pointers. This means first checking against non-null for
33883407 // both lhs and rhs, as well as checking the payload are matching of lhs and rhs
33893408 return func.cmpOptionals(lhs, rhs, ty, op);
33903409 }
3391 } else if (isByRef(ty, func.target)) {
3410 } else if (isByRef(ty, mod)) {
33923411 return func.cmpBigInt(lhs, rhs, ty, op);
33933412 } else if (ty.isAnyFloat() and ty.floatBits(func.target) == 16) {
33943413 return func.cmpFloat16(lhs, rhs, op);
......@@ -3401,13 +3420,13 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
34013420
34023421 const signedness: std.builtin.Signedness = blk: {
34033422 // by default we tell the operand type is unsigned (i.e. bools and enum values)
3404 if (ty.zigTypeTag() != .Int) break :blk .unsigned;
3423 if (ty.zigTypeTag(mod) != .Int) break :blk .unsigned;
34053424
34063425 // incase of an actual integer, we emit the correct signedness
3407 break :blk ty.intInfo(func.target).signedness;
3426 break :blk ty.intInfo(mod).signedness;
34083427 };
34093428 const opcode: wasm.Opcode = buildOpcode(.{
3410 .valtype1 = typeToValtype(ty, func.target),
3429 .valtype1 = typeToValtype(ty, mod),
34113430 .op = switch (op) {
34123431 .lt => .lt,
34133432 .lte => .le,
......@@ -3464,11 +3483,12 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
34643483}
34653484
34663485fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3486 const mod = func.bin_file.base.options.module.?;
34673487 const br = func.air.instructions.items(.data)[inst].br;
34683488 const block = func.blocks.get(br.block_inst).?;
34693489
34703490 // if operand has codegen bits we should break with a value
3471 if (func.air.typeOf(br.operand).hasRuntimeBitsIgnoreComptime()) {
3491 if (func.air.typeOf(br.operand).hasRuntimeBitsIgnoreComptime(mod)) {
34723492 const operand = try func.resolveInst(br.operand);
34733493 try func.lowerToStack(operand);
34743494
......@@ -3490,16 +3510,17 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
34903510
34913511 const operand = try func.resolveInst(ty_op.operand);
34923512 const operand_ty = func.air.typeOf(ty_op.operand);
3513 const mod = func.bin_file.base.options.module.?;
34933514
34943515 const result = result: {
3495 if (operand_ty.zigTypeTag() == .Bool) {
3516 if (operand_ty.zigTypeTag(mod) == .Bool) {
34963517 try func.emitWValue(operand);
34973518 try func.addTag(.i32_eqz);
34983519 const not_tmp = try func.allocLocal(operand_ty);
34993520 try func.addLabel(.local_set, not_tmp.local.value);
35003521 break :result not_tmp;
35013522 } else {
3502 const operand_bits = operand_ty.intInfo(func.target).bits;
3523 const operand_bits = operand_ty.intInfo(mod).bits;
35033524 const wasm_bits = toWasmBits(operand_bits) orelse {
35043525 return func.fail("TODO: Implement binary NOT for integer with bitsize '{d}'", .{operand_bits});
35053526 };
......@@ -3566,16 +3587,17 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
35663587}
35673588
35683589fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue {
3590 const mod = func.bin_file.base.options.module.?;
35693591 // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction
35703592 if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand;
35713593 if (wanted_ty.tag() == .f16 or given_ty.tag() == .f16) return operand;
3572 if (wanted_ty.bitSize(func.target) > 64) return operand;
3573 assert((wanted_ty.isInt() and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt()));
3594 if (wanted_ty.bitSize(mod) > 64) return operand;
3595 assert((wanted_ty.isInt(mod) and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt(mod)));
35743596
35753597 const opcode = buildOpcode(.{
35763598 .op = .reinterpret,
3577 .valtype1 = typeToValtype(wanted_ty, func.target),
3578 .valtype2 = typeToValtype(given_ty, func.target),
3599 .valtype1 = typeToValtype(wanted_ty, mod),
3600 .valtype2 = typeToValtype(given_ty, mod),
35793601 });
35803602 try func.emitWValue(operand);
35813603 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
......@@ -3609,19 +3631,20 @@ fn structFieldPtr(
36093631 struct_ty: Type,
36103632 index: u32,
36113633) InnerError!WValue {
3634 const mod = func.bin_file.base.options.module.?;
36123635 const result_ty = func.air.typeOfIndex(inst);
36133636 const offset = switch (struct_ty.containerLayout()) {
3614 .Packed => switch (struct_ty.zigTypeTag()) {
3637 .Packed => switch (struct_ty.zigTypeTag(mod)) {
36153638 .Struct => offset: {
36163639 if (result_ty.ptrInfo().data.host_size != 0) {
36173640 break :offset @as(u32, 0);
36183641 }
3619 break :offset struct_ty.packedStructFieldByteOffset(index, func.target);
3642 break :offset struct_ty.packedStructFieldByteOffset(index, mod);
36203643 },
36213644 .Union => 0,
36223645 else => unreachable,
36233646 },
3624 else => struct_ty.structFieldOffset(index, func.target),
3647 else => struct_ty.structFieldOffset(index, mod),
36253648 };
36263649 // save a load and store when we can simply reuse the operand
36273650 if (offset == 0) {
......@@ -3636,6 +3659,7 @@ fn structFieldPtr(
36363659}
36373660
36383661fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3662 const mod = func.bin_file.base.options.module.?;
36393663 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
36403664 const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data;
36413665
......@@ -3643,15 +3667,15 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
36433667 const operand = try func.resolveInst(struct_field.struct_operand);
36443668 const field_index = struct_field.field_index;
36453669 const field_ty = struct_ty.structFieldType(field_index);
3646 if (!field_ty.hasRuntimeBitsIgnoreComptime()) return func.finishAir(inst, .none, &.{struct_field.struct_operand});
3670 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return func.finishAir(inst, .none, &.{struct_field.struct_operand});
36473671
36483672 const result = switch (struct_ty.containerLayout()) {
3649 .Packed => switch (struct_ty.zigTypeTag()) {
3673 .Packed => switch (struct_ty.zigTypeTag(mod)) {
36503674 .Struct => result: {
36513675 const struct_obj = struct_ty.castTag(.@"struct").?.data;
3652 const offset = struct_obj.packedFieldBitOffset(func.target, field_index);
3676 const offset = struct_obj.packedFieldBitOffset(mod, field_index);
36533677 const backing_ty = struct_obj.backing_int_ty;
3654 const wasm_bits = toWasmBits(backing_ty.intInfo(func.target).bits) orelse {
3678 const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse {
36553679 return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{});
36563680 };
36573681 const const_wvalue = if (wasm_bits == 32)
......@@ -3667,25 +3691,17 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
36673691 else
36683692 try func.binOp(operand, const_wvalue, backing_ty, .shr);
36693693
3670 if (field_ty.zigTypeTag() == .Float) {
3671 var payload: Type.Payload.Bits = .{
3672 .base = .{ .tag = .int_unsigned },
3673 .data = @intCast(u16, field_ty.bitSize(func.target)),
3674 };
3675 const int_type = Type.initPayload(&payload.base);
3694 if (field_ty.zigTypeTag(mod) == .Float) {
3695 const int_type = try mod.intType(.unsigned, @intCast(u16, field_ty.bitSize(mod)));
36763696 const truncated = try func.trunc(shifted_value, int_type, backing_ty);
36773697 const bitcasted = try func.bitcast(field_ty, int_type, truncated);
36783698 break :result try bitcasted.toLocal(func, field_ty);
3679 } else if (field_ty.isPtrAtRuntime() and struct_obj.fields.count() == 1) {
3699 } else if (field_ty.isPtrAtRuntime(mod) and struct_obj.fields.count() == 1) {
36803700 // In this case we do not have to perform any transformations,
36813701 // we can simply reuse the operand.
36823702 break :result func.reuseOperand(struct_field.struct_operand, operand);
3683 } else if (field_ty.isPtrAtRuntime()) {
3684 var payload: Type.Payload.Bits = .{
3685 .base = .{ .tag = .int_unsigned },
3686 .data = @intCast(u16, field_ty.bitSize(func.target)),
3687 };
3688 const int_type = Type.initPayload(&payload.base);
3703 } else if (field_ty.isPtrAtRuntime(mod)) {
3704 const int_type = try mod.intType(.unsigned, @intCast(u16, field_ty.bitSize(mod)));
36893705 const truncated = try func.trunc(shifted_value, int_type, backing_ty);
36903706 break :result try truncated.toLocal(func, field_ty);
36913707 }
......@@ -3693,8 +3709,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
36933709 break :result try truncated.toLocal(func, field_ty);
36943710 },
36953711 .Union => result: {
3696 if (isByRef(struct_ty, func.target)) {
3697 if (!isByRef(field_ty, func.target)) {
3712 if (isByRef(struct_ty, mod)) {
3713 if (!isByRef(field_ty, mod)) {
36983714 const val = try func.load(operand, field_ty, 0);
36993715 break :result try val.toLocal(func, field_ty);
37003716 } else {
......@@ -3704,26 +3720,14 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37043720 }
37053721 }
37063722
3707 var payload: Type.Payload.Bits = .{
3708 .base = .{ .tag = .int_unsigned },
3709 .data = @intCast(u16, struct_ty.bitSize(func.target)),
3710 };
3711 const union_int_type = Type.initPayload(&payload.base);
3712 if (field_ty.zigTypeTag() == .Float) {
3713 var int_payload: Type.Payload.Bits = .{
3714 .base = .{ .tag = .int_unsigned },
3715 .data = @intCast(u16, field_ty.bitSize(func.target)),
3716 };
3717 const int_type = Type.initPayload(&int_payload.base);
3723 const union_int_type = try mod.intType(.unsigned, @intCast(u16, struct_ty.bitSize(mod)));
3724 if (field_ty.zigTypeTag(mod) == .Float) {
3725 const int_type = try mod.intType(.unsigned, @intCast(u16, field_ty.bitSize(mod)));
37183726 const truncated = try func.trunc(operand, int_type, union_int_type);
37193727 const bitcasted = try func.bitcast(field_ty, int_type, truncated);
37203728 break :result try bitcasted.toLocal(func, field_ty);
3721 } else if (field_ty.isPtrAtRuntime()) {
3722 var int_payload: Type.Payload.Bits = .{
3723 .base = .{ .tag = .int_unsigned },
3724 .data = @intCast(u16, field_ty.bitSize(func.target)),
3725 };
3726 const int_type = Type.initPayload(&int_payload.base);
3729 } else if (field_ty.isPtrAtRuntime(mod)) {
3730 const int_type = try mod.intType(.unsigned, @intCast(u16, field_ty.bitSize(mod)));
37273731 const truncated = try func.trunc(operand, int_type, union_int_type);
37283732 break :result try truncated.toLocal(func, field_ty);
37293733 }
......@@ -3733,11 +3737,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37333737 else => unreachable,
37343738 },
37353739 else => result: {
3736 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, func.target)) orelse {
3737 const module = func.bin_file.base.options.module.?;
3738 return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(module)});
3740 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, mod)) orelse {
3741 return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(mod)});
37393742 };
3740 if (isByRef(field_ty, func.target)) {
3743 if (isByRef(field_ty, mod)) {
37413744 switch (operand) {
37423745 .stack_offset => |stack_offset| {
37433746 break :result WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };
......@@ -3754,6 +3757,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37543757}
37553758
37563759fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3760 const mod = func.bin_file.base.options.module.?;
37573761 // result type is always 'noreturn'
37583762 const blocktype = wasm.block_empty;
37593763 const pl_op = func.air.instructions.items(.data)[inst].pl_op;
......@@ -3787,7 +3791,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37873791 errdefer func.gpa.free(values);
37883792
37893793 for (items, 0..) |ref, i| {
3790 const item_val = func.air.value(ref).?;
3794 const item_val = func.air.value(ref, mod).?;
37913795 const int_val = func.valueAsI32(item_val, target_ty);
37923796 if (lowest_maybe == null or int_val < lowest_maybe.?) {
37933797 lowest_maybe = int_val;
......@@ -3810,7 +3814,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38103814 // When the target is an integer size larger than u32, we have no way to use the value
38113815 // as an index, therefore we also use an if/else-chain for those cases.
38123816 // TODO: Benchmark this to find a proper value, LLVM seems to draw the line at '40~45'.
3813 const is_sparse = highest - lowest > 50 or target_ty.bitSize(func.target) > 32;
3817 const is_sparse = highest - lowest > 50 or target_ty.bitSize(mod) > 32;
38143818
38153819 const else_body = func.air.extra[extra_index..][0..switch_br.data.else_body_len];
38163820 const has_else_body = else_body.len != 0;
......@@ -3855,7 +3859,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38553859 // for errors that are not present in any branch. This is fine as this default
38563860 // case will never be hit for those cases but we do save runtime cost and size
38573861 // by using a jump table for this instead of if-else chains.
3858 break :blk if (has_else_body or target_ty.zigTypeTag() == .ErrorSet) case_i else unreachable;
3862 break :blk if (has_else_body or target_ty.zigTypeTag(mod) == .ErrorSet) case_i else unreachable;
38593863 };
38603864 func.mir_extra.appendAssumeCapacity(idx);
38613865 } else if (has_else_body) {
......@@ -3866,10 +3870,10 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38663870
38673871 const signedness: std.builtin.Signedness = blk: {
38683872 // by default we tell the operand type is unsigned (i.e. bools and enum values)
3869 if (target_ty.zigTypeTag() != .Int) break :blk .unsigned;
3873 if (target_ty.zigTypeTag(mod) != .Int) break :blk .unsigned;
38703874
38713875 // incase of an actual integer, we emit the correct signedness
3872 break :blk target_ty.intInfo(func.target).signedness;
3876 break :blk target_ty.intInfo(mod).signedness;
38733877 };
38743878
38753879 try func.branches.ensureUnusedCapacity(func.gpa, case_list.items.len + @boolToInt(has_else_body));
......@@ -3882,7 +3886,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38823886 const val = try func.lowerConstant(case.values[0].value, target_ty);
38833887 try func.emitWValue(val);
38843888 const opcode = buildOpcode(.{
3885 .valtype1 = typeToValtype(target_ty, func.target),
3889 .valtype1 = typeToValtype(target_ty, mod),
38863890 .op = .ne, // not equal, because we want to jump out of this block if it does not match the condition.
38873891 .signedness = signedness,
38883892 });
......@@ -3896,7 +3900,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38963900 const val = try func.lowerConstant(value.value, target_ty);
38973901 try func.emitWValue(val);
38983902 const opcode = buildOpcode(.{
3899 .valtype1 = typeToValtype(target_ty, func.target),
3903 .valtype1 = typeToValtype(target_ty, mod),
39003904 .op = .eq,
39013905 .signedness = signedness,
39023906 });
......@@ -3933,6 +3937,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
39333937}
39343938
39353939fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void {
3940 const mod = func.bin_file.base.options.module.?;
39363941 const un_op = func.air.instructions.items(.data)[inst].un_op;
39373942 const operand = try func.resolveInst(un_op);
39383943 const err_union_ty = func.air.typeOf(un_op);
......@@ -3948,10 +3953,10 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
39483953 }
39493954
39503955 try func.emitWValue(operand);
3951 if (pl_ty.hasRuntimeBitsIgnoreComptime()) {
3956 if (pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
39523957 try func.addMemArg(.i32_load16_u, .{
3953 .offset = operand.offset() + @intCast(u32, errUnionErrorOffset(pl_ty, func.target)),
3954 .alignment = Type.anyerror.abiAlignment(func.target),
3958 .offset = operand.offset() + @intCast(u32, errUnionErrorOffset(pl_ty, mod)),
3959 .alignment = Type.anyerror.abiAlignment(mod),
39553960 });
39563961 }
39573962
......@@ -3967,6 +3972,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
39673972}
39683973
39693974fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
3975 const mod = func.bin_file.base.options.module.?;
39703976 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
39713977
39723978 const operand = try func.resolveInst(ty_op.operand);
......@@ -3975,15 +3981,15 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
39753981 const payload_ty = err_ty.errorUnionPayload();
39763982
39773983 const result = result: {
3978 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3984 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
39793985 if (op_is_ptr) {
39803986 break :result func.reuseOperand(ty_op.operand, operand);
39813987 }
39823988 break :result WValue{ .none = {} };
39833989 }
39843990
3985 const pl_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, func.target));
3986 if (op_is_ptr or isByRef(payload_ty, func.target)) {
3991 const pl_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, mod));
3992 if (op_is_ptr or isByRef(payload_ty, mod)) {
39873993 break :result try func.buildPointerOffset(operand, pl_offset, .new);
39883994 }
39893995
......@@ -3994,6 +4000,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
39944000}
39954001
39964002fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
4003 const mod = func.bin_file.base.options.module.?;
39974004 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
39984005
39994006 const operand = try func.resolveInst(ty_op.operand);
......@@ -4006,17 +4013,18 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
40064013 break :result WValue{ .imm32 = 0 };
40074014 }
40084015
4009 if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime()) {
4016 if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
40104017 break :result func.reuseOperand(ty_op.operand, operand);
40114018 }
40124019
4013 const error_val = try func.load(operand, Type.anyerror, @intCast(u32, errUnionErrorOffset(payload_ty, func.target)));
4020 const error_val = try func.load(operand, Type.anyerror, @intCast(u32, errUnionErrorOffset(payload_ty, mod)));
40144021 break :result try error_val.toLocal(func, Type.anyerror);
40154022 };
40164023 func.finishAir(inst, result, &.{ty_op.operand});
40174024}
40184025
40194026fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4027 const mod = func.bin_file.base.options.module.?;
40204028 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
40214029
40224030 const operand = try func.resolveInst(ty_op.operand);
......@@ -4024,18 +4032,18 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
40244032
40254033 const pl_ty = func.air.typeOf(ty_op.operand);
40264034 const result = result: {
4027 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {
4035 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
40284036 break :result func.reuseOperand(ty_op.operand, operand);
40294037 }
40304038
40314039 const err_union = try func.allocStack(err_ty);
4032 const payload_ptr = try func.buildPointerOffset(err_union, @intCast(u32, errUnionPayloadOffset(pl_ty, func.target)), .new);
4040 const payload_ptr = try func.buildPointerOffset(err_union, @intCast(u32, errUnionPayloadOffset(pl_ty, mod)), .new);
40334041 try func.store(payload_ptr, operand, pl_ty, 0);
40344042
40354043 // ensure we also write '0' to the error part, so any present stack value gets overwritten by it.
40364044 try func.emitWValue(err_union);
40374045 try func.addImm32(0);
4038 const err_val_offset = @intCast(u32, errUnionErrorOffset(pl_ty, func.target));
4046 const err_val_offset = @intCast(u32, errUnionErrorOffset(pl_ty, mod));
40394047 try func.addMemArg(.i32_store16, .{ .offset = err_union.offset() + err_val_offset, .alignment = 2 });
40404048 break :result err_union;
40414049 };
......@@ -4043,6 +4051,7 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
40434051}
40444052
40454053fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4054 const mod = func.bin_file.base.options.module.?;
40464055 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
40474056
40484057 const operand = try func.resolveInst(ty_op.operand);
......@@ -4050,17 +4059,17 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40504059 const pl_ty = err_ty.errorUnionPayload();
40514060
40524061 const result = result: {
4053 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) {
4062 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
40544063 break :result func.reuseOperand(ty_op.operand, operand);
40554064 }
40564065
40574066 const err_union = try func.allocStack(err_ty);
40584067 // store error value
4059 try func.store(err_union, operand, Type.anyerror, @intCast(u32, errUnionErrorOffset(pl_ty, func.target)));
4068 try func.store(err_union, operand, Type.anyerror, @intCast(u32, errUnionErrorOffset(pl_ty, mod)));
40604069
40614070 // write 'undefined' to the payload
4062 const payload_ptr = try func.buildPointerOffset(err_union, @intCast(u32, errUnionPayloadOffset(pl_ty, func.target)), .new);
4063 const len = @intCast(u32, err_ty.errorUnionPayload().abiSize(func.target));
4071 const payload_ptr = try func.buildPointerOffset(err_union, @intCast(u32, errUnionPayloadOffset(pl_ty, mod)), .new);
4072 const len = @intCast(u32, err_ty.errorUnionPayload().abiSize(mod));
40644073 try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa });
40654074
40664075 break :result err_union;
......@@ -4074,15 +4083,16 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40744083 const ty = func.air.getRefType(ty_op.ty);
40754084 const operand = try func.resolveInst(ty_op.operand);
40764085 const operand_ty = func.air.typeOf(ty_op.operand);
4077 if (ty.zigTypeTag() == .Vector or operand_ty.zigTypeTag() == .Vector) {
4086 const mod = func.bin_file.base.options.module.?;
4087 if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) {
40784088 return func.fail("todo Wasm intcast for vectors", .{});
40794089 }
4080 if (ty.abiSize(func.target) > 16 or operand_ty.abiSize(func.target) > 16) {
4090 if (ty.abiSize(mod) > 16 or operand_ty.abiSize(mod) > 16) {
40814091 return func.fail("todo Wasm intcast for bitsize > 128", .{});
40824092 }
40834093
4084 const op_bits = toWasmBits(@intCast(u16, operand_ty.bitSize(func.target))).?;
4085 const wanted_bits = toWasmBits(@intCast(u16, ty.bitSize(func.target))).?;
4094 const op_bits = toWasmBits(@intCast(u16, operand_ty.bitSize(mod))).?;
4095 const wanted_bits = toWasmBits(@intCast(u16, ty.bitSize(mod))).?;
40864096 const result = if (op_bits == wanted_bits)
40874097 func.reuseOperand(ty_op.operand, operand)
40884098 else
......@@ -4096,8 +4106,9 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40964106/// Asserts type's bitsize <= 128
40974107/// NOTE: May leave the result on the top of the stack.
40984108fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {
4099 const given_bitsize = @intCast(u16, given.bitSize(func.target));
4100 const wanted_bitsize = @intCast(u16, wanted.bitSize(func.target));
4109 const mod = func.bin_file.base.options.module.?;
4110 const given_bitsize = @intCast(u16, given.bitSize(mod));
4111 const wanted_bitsize = @intCast(u16, wanted.bitSize(mod));
41014112 assert(given_bitsize <= 128);
41024113 assert(wanted_bitsize <= 128);
41034114
......@@ -4110,7 +4121,7 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
41104121 try func.addTag(.i32_wrap_i64);
41114122 } else if (op_bits == 32 and wanted_bits > 32 and wanted_bits <= 64) {
41124123 try func.emitWValue(operand);
4113 try func.addTag(if (wanted.isSignedInt()) .i64_extend_i32_s else .i64_extend_i32_u);
4124 try func.addTag(if (wanted.isSignedInt(mod)) .i64_extend_i32_s else .i64_extend_i32_u);
41144125 } else if (wanted_bits == 128) {
41154126 // for 128bit integers we store the integer in the virtual stack, rather than a local
41164127 const stack_ptr = try func.allocStack(wanted);
......@@ -4119,14 +4130,14 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
41194130 // for 32 bit integers, we first coerce the value into a 64 bit integer before storing it
41204131 // meaning less store operations are required.
41214132 const lhs = if (op_bits == 32) blk: {
4122 break :blk try func.intcast(operand, given, if (wanted.isSignedInt()) Type.i64 else Type.u64);
4133 break :blk try func.intcast(operand, given, if (wanted.isSignedInt(mod)) Type.i64 else Type.u64);
41234134 } else operand;
41244135
41254136 // store msb first
41264137 try func.store(.{ .stack = {} }, lhs, Type.u64, 0 + stack_ptr.offset());
41274138
41284139 // For signed integers we shift msb by 63 (64bit integer - 1 sign bit) and store remaining value
4129 if (wanted.isSignedInt()) {
4140 if (wanted.isSignedInt(mod)) {
41304141 try func.emitWValue(stack_ptr);
41314142 const shr = try func.binOp(lhs, .{ .imm64 = 63 }, Type.i64, .shr);
41324143 try func.store(.{ .stack = {} }, shr, Type.u64, 8 + stack_ptr.offset());
......@@ -4154,16 +4165,16 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind:
41544165/// For a given type and operand, checks if it's considered `null`.
41554166/// NOTE: Leaves the result on the stack
41564167fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue {
4168 const mod = func.bin_file.base.options.module.?;
41574169 try func.emitWValue(operand);
41584170 var buf: Type.Payload.ElemType = undefined;
41594171 const payload_ty = optional_ty.optionalChild(&buf);
4160 if (!optional_ty.optionalReprIsPayload()) {
4172 if (!optional_ty.optionalReprIsPayload(mod)) {
41614173 // When payload is zero-bits, we can treat operand as a value, rather than
41624174 // a pointer to the stack value
4163 if (payload_ty.hasRuntimeBitsIgnoreComptime()) {
4164 const offset = std.math.cast(u32, payload_ty.abiSize(func.target)) orelse {
4165 const module = func.bin_file.base.options.module.?;
4166 return func.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(module)});
4175 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4176 const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse {
4177 return func.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(mod)});
41674178 };
41684179 try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 });
41694180 }
......@@ -4183,18 +4194,19 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod
41834194}
41844195
41854196fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4197 const mod = func.bin_file.base.options.module.?;
41864198 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
41874199 const opt_ty = func.air.typeOf(ty_op.operand);
41884200 const payload_ty = func.air.typeOfIndex(inst);
4189 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
4201 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
41904202 return func.finishAir(inst, .none, &.{ty_op.operand});
41914203 }
41924204
41934205 const result = result: {
41944206 const operand = try func.resolveInst(ty_op.operand);
4195 if (opt_ty.optionalReprIsPayload()) break :result func.reuseOperand(ty_op.operand, operand);
4207 if (opt_ty.optionalReprIsPayload(mod)) break :result func.reuseOperand(ty_op.operand, operand);
41964208
4197 if (isByRef(payload_ty, func.target)) {
4209 if (isByRef(payload_ty, mod)) {
41984210 break :result try func.buildPointerOffset(operand, 0, .new);
41994211 }
42004212
......@@ -4209,10 +4221,11 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
42094221 const operand = try func.resolveInst(ty_op.operand);
42104222 const opt_ty = func.air.typeOf(ty_op.operand).childType();
42114223
4224 const mod = func.bin_file.base.options.module.?;
42124225 const result = result: {
42134226 var buf: Type.Payload.ElemType = undefined;
42144227 const payload_ty = opt_ty.optionalChild(&buf);
4215 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or opt_ty.optionalReprIsPayload()) {
4228 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or opt_ty.optionalReprIsPayload(mod)) {
42164229 break :result func.reuseOperand(ty_op.operand, operand);
42174230 }
42184231
......@@ -4222,22 +4235,22 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
42224235}
42234236
42244237fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4238 const mod = func.bin_file.base.options.module.?;
42254239 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
42264240 const operand = try func.resolveInst(ty_op.operand);
42274241 const opt_ty = func.air.typeOf(ty_op.operand).childType();
42284242 var buf: Type.Payload.ElemType = undefined;
42294243 const payload_ty = opt_ty.optionalChild(&buf);
4230 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
4244 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
42314245 return func.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()});
42324246 }
42334247
4234 if (opt_ty.optionalReprIsPayload()) {
4248 if (opt_ty.optionalReprIsPayload(mod)) {
42354249 return func.finishAir(inst, operand, &.{ty_op.operand});
42364250 }
42374251
4238 const offset = std.math.cast(u32, payload_ty.abiSize(func.target)) orelse {
4239 const module = func.bin_file.base.options.module.?;
4240 return func.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(module)});
4252 const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse {
4253 return func.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(mod)});
42414254 };
42424255
42434256 try func.emitWValue(operand);
......@@ -4251,9 +4264,10 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
42514264fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
42524265 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
42534266 const payload_ty = func.air.typeOf(ty_op.operand);
4267 const mod = func.bin_file.base.options.module.?;
42544268
42554269 const result = result: {
4256 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
4270 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
42574271 const non_null_bit = try func.allocStack(Type.initTag(.u1));
42584272 try func.emitWValue(non_null_bit);
42594273 try func.addImm32(1);
......@@ -4263,12 +4277,11 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
42634277
42644278 const operand = try func.resolveInst(ty_op.operand);
42654279 const op_ty = func.air.typeOfIndex(inst);
4266 if (op_ty.optionalReprIsPayload()) {
4280 if (op_ty.optionalReprIsPayload(mod)) {
42674281 break :result func.reuseOperand(ty_op.operand, operand);
42684282 }
4269 const offset = std.math.cast(u32, payload_ty.abiSize(func.target)) orelse {
4270 const module = func.bin_file.base.options.module.?;
4271 return func.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(module)});
4283 const offset = std.math.cast(u32, payload_ty.abiSize(mod)) orelse {
4284 return func.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(mod)});
42724285 };
42734286
42744287 // Create optional type, set the non-null bit, and store the operand inside the optional type
......@@ -4314,7 +4327,8 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
43144327 const slice = try func.resolveInst(bin_op.lhs);
43154328 const index = try func.resolveInst(bin_op.rhs);
43164329 const elem_ty = slice_ty.childType();
4317 const elem_size = elem_ty.abiSize(func.target);
4330 const mod = func.bin_file.base.options.module.?;
4331 const elem_size = elem_ty.abiSize(mod);
43184332
43194333 // load pointer onto stack
43204334 _ = try func.load(slice, Type.usize, 0);
......@@ -4328,7 +4342,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
43284342 const result_ptr = try func.allocLocal(Type.usize);
43294343 try func.addLabel(.local_set, result_ptr.local.value);
43304344
4331 const result = if (!isByRef(elem_ty, func.target)) result: {
4345 const result = if (!isByRef(elem_ty, mod)) result: {
43324346 const elem_val = try func.load(result_ptr, elem_ty, 0);
43334347 break :result try elem_val.toLocal(func, elem_ty);
43344348 } else result_ptr;
......@@ -4341,7 +4355,8 @@ fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
43414355 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
43424356
43434357 const elem_ty = func.air.getRefType(ty_pl.ty).childType();
4344 const elem_size = elem_ty.abiSize(func.target);
4358 const mod = func.bin_file.base.options.module.?;
4359 const elem_size = elem_ty.abiSize(mod);
43454360
43464361 const slice = try func.resolveInst(bin_op.lhs);
43474362 const index = try func.resolveInst(bin_op.rhs);
......@@ -4389,13 +4404,14 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
43894404/// Truncates a given operand to a given type, discarding any overflown bits.
43904405/// NOTE: Resulting value is left on the stack.
43914406fn trunc(func: *CodeGen, operand: WValue, wanted_ty: Type, given_ty: Type) InnerError!WValue {
4392 const given_bits = @intCast(u16, given_ty.bitSize(func.target));
4407 const mod = func.bin_file.base.options.module.?;
4408 const given_bits = @intCast(u16, given_ty.bitSize(mod));
43934409 if (toWasmBits(given_bits) == null) {
43944410 return func.fail("TODO: Implement wasm integer truncation for integer bitsize: {d}", .{given_bits});
43954411 }
43964412
43974413 var result = try func.intcast(operand, given_ty, wanted_ty);
4398 const wanted_bits = @intCast(u16, wanted_ty.bitSize(func.target));
4414 const wanted_bits = @intCast(u16, wanted_ty.bitSize(mod));
43994415 const wasm_bits = toWasmBits(wanted_bits).?;
44004416 if (wasm_bits != wanted_bits) {
44014417 result = try func.wrapOperand(result, wanted_ty);
......@@ -4412,6 +4428,7 @@ fn airBoolToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44124428}
44134429
44144430fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4431 const mod = func.bin_file.base.options.module.?;
44154432 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
44164433
44174434 const operand = try func.resolveInst(ty_op.operand);
......@@ -4422,7 +4439,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44224439 const slice_local = try func.allocStack(slice_ty);
44234440
44244441 // store the array ptr in the slice
4425 if (array_ty.hasRuntimeBitsIgnoreComptime()) {
4442 if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
44264443 try func.store(slice_local, operand, Type.usize, 0);
44274444 }
44284445
......@@ -4454,7 +4471,8 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44544471 const ptr = try func.resolveInst(bin_op.lhs);
44554472 const index = try func.resolveInst(bin_op.rhs);
44564473 const elem_ty = ptr_ty.childType();
4457 const elem_size = elem_ty.abiSize(func.target);
4474 const mod = func.bin_file.base.options.module.?;
4475 const elem_size = elem_ty.abiSize(mod);
44584476
44594477 // load pointer onto the stack
44604478 if (ptr_ty.isSlice()) {
......@@ -4472,7 +4490,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44724490 const elem_result = val: {
44734491 var result = try func.allocLocal(Type.usize);
44744492 try func.addLabel(.local_set, result.local.value);
4475 if (isByRef(elem_ty, func.target)) {
4493 if (isByRef(elem_ty, mod)) {
44764494 break :val result;
44774495 }
44784496 defer result.free(func); // only free if it's not returned like above
......@@ -4489,7 +4507,8 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44894507
44904508 const ptr_ty = func.air.typeOf(bin_op.lhs);
44914509 const elem_ty = func.air.getRefType(ty_pl.ty).childType();
4492 const elem_size = elem_ty.abiSize(func.target);
4510 const mod = func.bin_file.base.options.module.?;
4511 const elem_size = elem_ty.abiSize(mod);
44934512
44944513 const ptr = try func.resolveInst(bin_op.lhs);
44954514 const index = try func.resolveInst(bin_op.rhs);
......@@ -4513,6 +4532,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
45134532}
45144533
45154534fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
4535 const mod = func.bin_file.base.options.module.?;
45164536 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
45174537 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
45184538
......@@ -4524,13 +4544,13 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
45244544 else => ptr_ty.childType(),
45254545 };
45264546
4527 const valtype = typeToValtype(Type.usize, func.target);
4547 const valtype = typeToValtype(Type.usize, mod);
45284548 const mul_opcode = buildOpcode(.{ .valtype1 = valtype, .op = .mul });
45294549 const bin_opcode = buildOpcode(.{ .valtype1 = valtype, .op = op });
45304550
45314551 try func.lowerToStack(ptr);
45324552 try func.emitWValue(offset);
4533 try func.addImm32(@bitCast(i32, @intCast(u32, pointee_ty.abiSize(func.target))));
4553 try func.addImm32(@bitCast(i32, @intCast(u32, pointee_ty.abiSize(mod))));
45344554 try func.addTag(Mir.Inst.Tag.fromOpcode(mul_opcode));
45354555 try func.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode));
45364556
......@@ -4572,7 +4592,8 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
45724592/// this to wasm's memset instruction. When the feature is not present,
45734593/// we implement it manually.
45744594fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue) InnerError!void {
4575 const abi_size = @intCast(u32, elem_ty.abiSize(func.target));
4595 const mod = func.bin_file.base.options.module.?;
4596 const abi_size = @intCast(u32, elem_ty.abiSize(mod));
45764597
45774598 // When bulk_memory is enabled, we lower it to wasm's memset instruction.
45784599 // If not, we lower it ourselves.
......@@ -4666,24 +4687,25 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46664687 const array = try func.resolveInst(bin_op.lhs);
46674688 const index = try func.resolveInst(bin_op.rhs);
46684689 const elem_ty = array_ty.childType();
4669 const elem_size = elem_ty.abiSize(func.target);
4690 const mod = func.bin_file.base.options.module.?;
4691 const elem_size = elem_ty.abiSize(mod);
46704692
4671 if (isByRef(array_ty, func.target)) {
4693 if (isByRef(array_ty, mod)) {
46724694 try func.lowerToStack(array);
46734695 try func.emitWValue(index);
46744696 try func.addImm32(@bitCast(i32, @intCast(u32, elem_size)));
46754697 try func.addTag(.i32_mul);
46764698 try func.addTag(.i32_add);
46774699 } else {
4678 std.debug.assert(array_ty.zigTypeTag() == .Vector);
4700 std.debug.assert(array_ty.zigTypeTag(mod) == .Vector);
46794701
46804702 switch (index) {
46814703 inline .imm32, .imm64 => |lane| {
4682 const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(func.target)) {
4683 8 => if (elem_ty.isSignedInt()) .i8x16_extract_lane_s else .i8x16_extract_lane_u,
4684 16 => if (elem_ty.isSignedInt()) .i16x8_extract_lane_s else .i16x8_extract_lane_u,
4685 32 => if (elem_ty.isInt()) .i32x4_extract_lane else .f32x4_extract_lane,
4686 64 => if (elem_ty.isInt()) .i64x2_extract_lane else .f64x2_extract_lane,
4704 const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(mod)) {
4705 8 => if (elem_ty.isSignedInt(mod)) .i8x16_extract_lane_s else .i8x16_extract_lane_u,
4706 16 => if (elem_ty.isSignedInt(mod)) .i16x8_extract_lane_s else .i16x8_extract_lane_u,
4707 32 => if (elem_ty.isInt(mod)) .i32x4_extract_lane else .f32x4_extract_lane,
4708 64 => if (elem_ty.isInt(mod)) .i64x2_extract_lane else .f64x2_extract_lane,
46874709 else => unreachable,
46884710 };
46894711
......@@ -4715,7 +4737,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47154737 var result = try func.allocLocal(Type.usize);
47164738 try func.addLabel(.local_set, result.local.value);
47174739
4718 if (isByRef(elem_ty, func.target)) {
4740 if (isByRef(elem_ty, mod)) {
47194741 break :val result;
47204742 }
47214743 defer result.free(func); // only free if no longer needed and not returned like above
......@@ -4733,17 +4755,18 @@ fn airFloatToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47334755 const operand = try func.resolveInst(ty_op.operand);
47344756 const dest_ty = func.air.typeOfIndex(inst);
47354757 const op_ty = func.air.typeOf(ty_op.operand);
4758 const mod = func.bin_file.base.options.module.?;
47364759
4737 if (op_ty.abiSize(func.target) > 8) {
4760 if (op_ty.abiSize(mod) > 8) {
47384761 return func.fail("TODO: floatToInt for integers/floats with bitsize larger than 64 bits", .{});
47394762 }
47404763
47414764 try func.emitWValue(operand);
47424765 const op = buildOpcode(.{
47434766 .op = .trunc,
4744 .valtype1 = typeToValtype(dest_ty, func.target),
4745 .valtype2 = typeToValtype(op_ty, func.target),
4746 .signedness = if (dest_ty.isSignedInt()) .signed else .unsigned,
4767 .valtype1 = typeToValtype(dest_ty, mod),
4768 .valtype2 = typeToValtype(op_ty, mod),
4769 .signedness = if (dest_ty.isSignedInt(mod)) .signed else .unsigned,
47474770 });
47484771 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
47494772 const wrapped = try func.wrapOperand(.{ .stack = {} }, dest_ty);
......@@ -4757,17 +4780,18 @@ fn airIntToFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47574780 const operand = try func.resolveInst(ty_op.operand);
47584781 const dest_ty = func.air.typeOfIndex(inst);
47594782 const op_ty = func.air.typeOf(ty_op.operand);
4783 const mod = func.bin_file.base.options.module.?;
47604784
4761 if (op_ty.abiSize(func.target) > 8) {
4785 if (op_ty.abiSize(mod) > 8) {
47624786 return func.fail("TODO: intToFloat for integers/floats with bitsize larger than 64 bits", .{});
47634787 }
47644788
47654789 try func.emitWValue(operand);
47664790 const op = buildOpcode(.{
47674791 .op = .convert,
4768 .valtype1 = typeToValtype(dest_ty, func.target),
4769 .valtype2 = typeToValtype(op_ty, func.target),
4770 .signedness = if (op_ty.isSignedInt()) .signed else .unsigned,
4792 .valtype1 = typeToValtype(dest_ty, mod),
4793 .valtype2 = typeToValtype(op_ty, mod),
4794 .signedness = if (op_ty.isSignedInt(mod)) .signed else .unsigned,
47714795 });
47724796 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
47734797
......@@ -4777,18 +4801,19 @@ fn airIntToFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47774801}
47784802
47794803fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4804 const mod = func.bin_file.base.options.module.?;
47804805 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
47814806 const operand = try func.resolveInst(ty_op.operand);
47824807 const ty = func.air.typeOfIndex(inst);
47834808 const elem_ty = ty.childType();
47844809
4785 if (determineSimdStoreStrategy(ty, func.target) == .direct) blk: {
4810 if (determineSimdStoreStrategy(ty, mod) == .direct) blk: {
47864811 switch (operand) {
47874812 // when the operand lives in the linear memory section, we can directly
47884813 // load and splat the value at once. Meaning we do not first have to load
47894814 // the scalar value onto the stack.
47904815 .stack_offset, .memory, .memory_offset => {
4791 const opcode = switch (elem_ty.bitSize(func.target)) {
4816 const opcode = switch (elem_ty.bitSize(mod)) {
47924817 8 => std.wasm.simdOpcode(.v128_load8_splat),
47934818 16 => std.wasm.simdOpcode(.v128_load16_splat),
47944819 32 => std.wasm.simdOpcode(.v128_load32_splat),
......@@ -4803,18 +4828,18 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48034828 try func.mir_extra.appendSlice(func.gpa, &[_]u32{
48044829 opcode,
48054830 operand.offset(),
4806 elem_ty.abiAlignment(func.target),
4831 elem_ty.abiAlignment(mod),
48074832 });
48084833 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
48094834 try func.addLabel(.local_set, result.local.value);
48104835 return func.finishAir(inst, result, &.{ty_op.operand});
48114836 },
48124837 .local => {
4813 const opcode = switch (elem_ty.bitSize(func.target)) {
4838 const opcode = switch (elem_ty.bitSize(mod)) {
48144839 8 => std.wasm.simdOpcode(.i8x16_splat),
48154840 16 => std.wasm.simdOpcode(.i16x8_splat),
4816 32 => if (elem_ty.isInt()) std.wasm.simdOpcode(.i32x4_splat) else std.wasm.simdOpcode(.f32x4_splat),
4817 64 => if (elem_ty.isInt()) std.wasm.simdOpcode(.i64x2_splat) else std.wasm.simdOpcode(.f64x2_splat),
4841 32 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i32x4_splat) else std.wasm.simdOpcode(.f32x4_splat),
4842 64 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i64x2_splat) else std.wasm.simdOpcode(.f64x2_splat),
48184843 else => break :blk, // Cannot make use of simd-instructions
48194844 };
48204845 const result = try func.allocLocal(ty);
......@@ -4828,14 +4853,14 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48284853 else => unreachable,
48294854 }
48304855 }
4831 const elem_size = elem_ty.bitSize(func.target);
4856 const elem_size = elem_ty.bitSize(mod);
48324857 const vector_len = @intCast(usize, ty.vectorLen());
48334858 if ((!std.math.isPowerOfTwo(elem_size) or elem_size % 8 != 0) and vector_len > 1) {
48344859 return func.fail("TODO: WebAssembly `@splat` for arbitrary element bitsize {d}", .{elem_size});
48354860 }
48364861
48374862 const result = try func.allocStack(ty);
4838 const elem_byte_size = @intCast(u32, elem_ty.abiSize(func.target));
4863 const elem_byte_size = @intCast(u32, elem_ty.abiSize(mod));
48394864 var index: usize = 0;
48404865 var offset: u32 = 0;
48414866 while (index < vector_len) : (index += 1) {
......@@ -4855,6 +4880,7 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48554880}
48564881
48574882fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4883 const mod = func.bin_file.base.options.module.?;
48584884 const inst_ty = func.air.typeOfIndex(inst);
48594885 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
48604886 const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data;
......@@ -4865,16 +4891,15 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48654891 const mask_len = extra.mask_len;
48664892
48674893 const child_ty = inst_ty.childType();
4868 const elem_size = child_ty.abiSize(func.target);
4894 const elem_size = child_ty.abiSize(mod);
48694895
4870 const module = func.bin_file.base.options.module.?;
48714896 // TODO: One of them could be by ref; handle in loop
4872 if (isByRef(func.air.typeOf(extra.a), func.target) or isByRef(inst_ty, func.target)) {
4897 if (isByRef(func.air.typeOf(extra.a), mod) or isByRef(inst_ty, mod)) {
48734898 const result = try func.allocStack(inst_ty);
48744899
48754900 for (0..mask_len) |index| {
48764901 var buf: Value.ElemValueBuffer = undefined;
4877 const value = mask.elemValueBuffer(module, index, &buf).toSignedInt(func.target);
4902 const value = mask.elemValueBuffer(mod, index, &buf).toSignedInt(mod);
48784903
48794904 try func.emitWValue(result);
48804905
......@@ -4895,7 +4920,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48954920 var lanes = std.mem.asBytes(operands[1..]);
48964921 for (0..@intCast(usize, mask_len)) |index| {
48974922 var buf: Value.ElemValueBuffer = undefined;
4898 const mask_elem = mask.elemValueBuffer(module, index, &buf).toSignedInt(func.target);
4923 const mask_elem = mask.elemValueBuffer(mod, index, &buf).toSignedInt(mod);
48994924 const base_index = if (mask_elem >= 0)
49004925 @intCast(u8, @intCast(i64, elem_size) * mask_elem)
49014926 else
......@@ -4930,13 +4955,14 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
49304955 const result_ty = func.air.typeOfIndex(inst);
49314956 const len = @intCast(usize, result_ty.arrayLen());
49324957 const elements = @ptrCast([]const Air.Inst.Ref, func.air.extra[ty_pl.payload..][0..len]);
4958 const mod = func.bin_file.base.options.module.?;
49334959
49344960 const result: WValue = result_value: {
4935 switch (result_ty.zigTypeTag()) {
4961 switch (result_ty.zigTypeTag(mod)) {
49364962 .Array => {
49374963 const result = try func.allocStack(result_ty);
49384964 const elem_ty = result_ty.childType();
4939 const elem_size = @intCast(u32, elem_ty.abiSize(func.target));
4965 const elem_size = @intCast(u32, elem_ty.abiSize(mod));
49404966 const sentinel = if (result_ty.sentinel()) |sent| blk: {
49414967 break :blk try func.lowerConstant(sent, elem_ty);
49424968 } else null;
......@@ -4944,7 +4970,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
49444970 // When the element type is by reference, we must copy the entire
49454971 // value. It is therefore safer to move the offset pointer and store
49464972 // each value individually, instead of using store offsets.
4947 if (isByRef(elem_ty, func.target)) {
4973 if (isByRef(elem_ty, mod)) {
49484974 // copy stack pointer into a temporary local, which is
49494975 // moved for each element to store each value in the right position.
49504976 const offset = try func.buildPointerOffset(result, 0, .new);
......@@ -4974,7 +5000,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
49745000 },
49755001 .Struct => switch (result_ty.containerLayout()) {
49765002 .Packed => {
4977 if (isByRef(result_ty, func.target)) {
5003 if (isByRef(result_ty, mod)) {
49785004 return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{});
49795005 }
49805006 const struct_obj = result_ty.castTag(.@"struct").?.data;
......@@ -4983,7 +5009,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
49835009
49845010 // ensure the result is zero'd
49855011 const result = try func.allocLocal(backing_type);
4986 if (struct_obj.backing_int_ty.bitSize(func.target) <= 32)
5012 if (struct_obj.backing_int_ty.bitSize(mod) <= 32)
49875013 try func.addImm32(0)
49885014 else
49895015 try func.addImm64(0);
......@@ -4992,20 +5018,16 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
49925018 var current_bit: u16 = 0;
49935019 for (elements, 0..) |elem, elem_index| {
49945020 const field = fields[elem_index];
4995 if (!field.ty.hasRuntimeBitsIgnoreComptime()) continue;
5021 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
49965022
4997 const shift_val = if (struct_obj.backing_int_ty.bitSize(func.target) <= 32)
5023 const shift_val = if (struct_obj.backing_int_ty.bitSize(mod) <= 32)
49985024 WValue{ .imm32 = current_bit }
49995025 else
50005026 WValue{ .imm64 = current_bit };
50015027
50025028 const value = try func.resolveInst(elem);
5003 const value_bit_size = @intCast(u16, field.ty.bitSize(func.target));
5004 var int_ty_payload: Type.Payload.Bits = .{
5005 .base = .{ .tag = .int_unsigned },
5006 .data = value_bit_size,
5007 };
5008 const int_ty = Type.initPayload(&int_ty_payload.base);
5029 const value_bit_size = @intCast(u16, field.ty.bitSize(mod));
5030 const int_ty = try mod.intType(.unsigned, value_bit_size);
50095031
50105032 // load our current result on stack so we can perform all transformations
50115033 // using only stack values. Saving the cost of loads and stores.
......@@ -5027,10 +5049,10 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50275049 const result = try func.allocStack(result_ty);
50285050 const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset
50295051 for (elements, 0..) |elem, elem_index| {
5030 if (result_ty.structFieldValueComptime(elem_index) != null) continue;
5052 if (result_ty.structFieldValueComptime(mod, elem_index) != null) continue;
50315053
50325054 const elem_ty = result_ty.structFieldType(elem_index);
5033 const elem_size = @intCast(u32, elem_ty.abiSize(func.target));
5055 const elem_size = @intCast(u32, elem_ty.abiSize(mod));
50345056 const value = try func.resolveInst(elem);
50355057 try func.store(offset, value, elem_ty, 0);
50365058
......@@ -5058,12 +5080,13 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50585080}
50595081
50605082fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5083 const mod = func.bin_file.base.options.module.?;
50615084 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
50625085 const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data;
50635086
50645087 const result = result: {
50655088 const union_ty = func.air.typeOfIndex(inst);
5066 const layout = union_ty.unionGetLayout(func.target);
5089 const layout = union_ty.unionGetLayout(mod);
50675090 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
50685091 const field = union_obj.fields.values()[extra.field_index];
50695092 const field_name = union_obj.fields.keys()[extra.field_index];
......@@ -5082,15 +5105,15 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50825105 if (layout.tag_size == 0) {
50835106 break :result WValue{ .none = {} };
50845107 }
5085 assert(!isByRef(union_ty, func.target));
5108 assert(!isByRef(union_ty, mod));
50865109 break :result tag_int;
50875110 }
50885111
5089 if (isByRef(union_ty, func.target)) {
5112 if (isByRef(union_ty, mod)) {
50905113 const result_ptr = try func.allocStack(union_ty);
50915114 const payload = try func.resolveInst(extra.init);
50925115 if (layout.tag_align >= layout.payload_align) {
5093 if (isByRef(field.ty, func.target)) {
5116 if (isByRef(field.ty, mod)) {
50945117 const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new);
50955118 try func.store(payload_ptr, payload, field.ty, 0);
50965119 } else {
......@@ -5114,26 +5137,14 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51145137 break :result result_ptr;
51155138 } else {
51165139 const operand = try func.resolveInst(extra.init);
5117 var payload: Type.Payload.Bits = .{
5118 .base = .{ .tag = .int_unsigned },
5119 .data = @intCast(u16, union_ty.bitSize(func.target)),
5120 };
5121 const union_int_type = Type.initPayload(&payload.base);
5122 if (field.ty.zigTypeTag() == .Float) {
5123 var int_payload: Type.Payload.Bits = .{
5124 .base = .{ .tag = .int_unsigned },
5125 .data = @intCast(u16, field.ty.bitSize(func.target)),
5126 };
5127 const int_type = Type.initPayload(&int_payload.base);
5140 const union_int_type = try mod.intType(.unsigned, @intCast(u16, union_ty.bitSize(mod)));
5141 if (field.ty.zigTypeTag(mod) == .Float) {
5142 const int_type = try mod.intType(.unsigned, @intCast(u16, field.ty.bitSize(mod)));
51285143 const bitcasted = try func.bitcast(field.ty, int_type, operand);
51295144 const casted = try func.trunc(bitcasted, int_type, union_int_type);
51305145 break :result try casted.toLocal(func, field.ty);
5131 } else if (field.ty.isPtrAtRuntime()) {
5132 var int_payload: Type.Payload.Bits = .{
5133 .base = .{ .tag = .int_unsigned },
5134 .data = @intCast(u16, field.ty.bitSize(func.target)),
5135 };
5136 const int_type = Type.initPayload(&int_payload.base);
5146 } else if (field.ty.isPtrAtRuntime(mod)) {
5147 const int_type = try mod.intType(.unsigned, @intCast(u16, field.ty.bitSize(mod)));
51375148 const casted = try func.intcast(operand, int_type, union_int_type);
51385149 break :result try casted.toLocal(func, field.ty);
51395150 }
......@@ -5171,7 +5182,8 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {
51715182}
51725183
51735184fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
5174 assert(operand_ty.hasRuntimeBitsIgnoreComptime());
5185 const mod = func.bin_file.base.options.module.?;
5186 assert(operand_ty.hasRuntimeBitsIgnoreComptime(mod));
51755187 assert(op == .eq or op == .neq);
51765188 var buf: Type.Payload.ElemType = undefined;
51775189 const payload_ty = operand_ty.optionalChild(&buf);
......@@ -5189,7 +5201,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
51895201
51905202 _ = try func.load(lhs, payload_ty, 0);
51915203 _ = try func.load(rhs, payload_ty, 0);
5192 const opcode = buildOpcode(.{ .op = .ne, .valtype1 = typeToValtype(payload_ty, func.target) });
5204 const opcode = buildOpcode(.{ .op = .ne, .valtype1 = typeToValtype(payload_ty, mod) });
51935205 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
51945206 try func.addLabel(.br_if, 0);
51955207
......@@ -5207,10 +5219,11 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
52075219/// NOTE: Leaves the result of the comparison on top of the stack.
52085220/// TODO: Lower this to compiler_rt call when bitsize > 128
52095221fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
5210 assert(operand_ty.abiSize(func.target) >= 16);
5222 const mod = func.bin_file.base.options.module.?;
5223 assert(operand_ty.abiSize(mod) >= 16);
52115224 assert(!(lhs != .stack and rhs == .stack));
5212 if (operand_ty.bitSize(func.target) > 128) {
5213 return func.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.bitSize(func.target)});
5225 if (operand_ty.bitSize(mod) > 128) {
5226 return func.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.bitSize(mod)});
52145227 }
52155228
52165229 var lhs_high_bit = try (try func.load(lhs, Type.u64, 0)).toLocal(func, Type.u64);
......@@ -5233,7 +5246,7 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
52335246 }
52345247 },
52355248 else => {
5236 const ty = if (operand_ty.isSignedInt()) Type.i64 else Type.u64;
5249 const ty = if (operand_ty.isSignedInt(mod)) Type.i64 else Type.u64;
52375250 // leave those value on top of the stack for '.select'
52385251 const lhs_low_bit = try func.load(lhs, Type.u64, 8);
52395252 const rhs_low_bit = try func.load(rhs, Type.u64, 8);
......@@ -5248,10 +5261,11 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
52485261}
52495262
52505263fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5264 const mod = func.bin_file.base.options.module.?;
52515265 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
52525266 const un_ty = func.air.typeOf(bin_op.lhs).childType();
52535267 const tag_ty = func.air.typeOf(bin_op.rhs);
5254 const layout = un_ty.unionGetLayout(func.target);
5268 const layout = un_ty.unionGetLayout(mod);
52555269 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
52565270
52575271 const union_ptr = try func.resolveInst(bin_op.lhs);
......@@ -5271,11 +5285,12 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52715285}
52725286
52735287fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5288 const mod = func.bin_file.base.options.module.?;
52745289 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
52755290
52765291 const un_ty = func.air.typeOf(ty_op.operand);
52775292 const tag_ty = func.air.typeOfIndex(inst);
5278 const layout = un_ty.unionGetLayout(func.target);
5293 const layout = un_ty.unionGetLayout(mod);
52795294 if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ty_op.operand});
52805295
52815296 const operand = try func.resolveInst(ty_op.operand);
......@@ -5375,6 +5390,7 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
53755390}
53765391
53775392fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5393 const mod = func.bin_file.base.options.module.?;
53785394 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
53795395
53805396 const err_set_ty = func.air.typeOf(ty_op.operand).childType();
......@@ -5386,26 +5402,27 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
53865402 operand,
53875403 .{ .imm32 = 0 },
53885404 Type.anyerror,
5389 @intCast(u32, errUnionErrorOffset(payload_ty, func.target)),
5405 @intCast(u32, errUnionErrorOffset(payload_ty, mod)),
53905406 );
53915407
53925408 const result = result: {
5393 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
5409 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
53945410 break :result func.reuseOperand(ty_op.operand, operand);
53955411 }
53965412
5397 break :result try func.buildPointerOffset(operand, @intCast(u32, errUnionPayloadOffset(payload_ty, func.target)), .new);
5413 break :result try func.buildPointerOffset(operand, @intCast(u32, errUnionPayloadOffset(payload_ty, mod)), .new);
53985414 };
53995415 func.finishAir(inst, result, &.{ty_op.operand});
54005416}
54015417
54025418fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5419 const mod = func.bin_file.base.options.module.?;
54035420 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
54045421 const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
54055422
54065423 const field_ptr = try func.resolveInst(extra.field_ptr);
54075424 const parent_ty = func.air.getRefType(ty_pl.ty).childType();
5408 const field_offset = parent_ty.structFieldOffset(extra.field_index, func.target);
5425 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);
54095426
54105427 const result = if (field_offset != 0) result: {
54115428 const base = try func.buildPointerOffset(field_ptr, 0, .new);
......@@ -5428,6 +5445,7 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue
54285445}
54295446
54305447fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5448 const mod = func.bin_file.base.options.module.?;
54315449 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
54325450 const dst = try func.resolveInst(bin_op.lhs);
54335451 const dst_ty = func.air.typeOf(bin_op.lhs);
......@@ -5437,16 +5455,16 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
54375455 const len = switch (dst_ty.ptrSize()) {
54385456 .Slice => blk: {
54395457 const slice_len = try func.sliceLen(dst);
5440 if (ptr_elem_ty.abiSize(func.target) != 1) {
5458 if (ptr_elem_ty.abiSize(mod) != 1) {
54415459 try func.emitWValue(slice_len);
5442 try func.emitWValue(.{ .imm32 = @intCast(u32, ptr_elem_ty.abiSize(func.target)) });
5460 try func.emitWValue(.{ .imm32 = @intCast(u32, ptr_elem_ty.abiSize(mod)) });
54435461 try func.addTag(.i32_mul);
54445462 try func.addLabel(.local_set, slice_len.local.value);
54455463 }
54465464 break :blk slice_len;
54475465 },
54485466 .One => @as(WValue, .{
5449 .imm32 = @intCast(u32, ptr_elem_ty.arrayLen() * ptr_elem_ty.childType().abiSize(func.target)),
5467 .imm32 = @intCast(u32, ptr_elem_ty.arrayLen() * ptr_elem_ty.childType().abiSize(mod)),
54505468 }),
54515469 .C, .Many => unreachable,
54525470 };
......@@ -5472,12 +5490,13 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
54725490 const operand = try func.resolveInst(ty_op.operand);
54735491 const op_ty = func.air.typeOf(ty_op.operand);
54745492 const result_ty = func.air.typeOfIndex(inst);
5493 const mod = func.bin_file.base.options.module.?;
54755494
5476 if (op_ty.zigTypeTag() == .Vector) {
5495 if (op_ty.zigTypeTag(mod) == .Vector) {
54775496 return func.fail("TODO: Implement @popCount for vectors", .{});
54785497 }
54795498
5480 const int_info = op_ty.intInfo(func.target);
5499 const int_info = op_ty.intInfo(mod);
54815500 const bits = int_info.bits;
54825501 const wasm_bits = toWasmBits(bits) orelse {
54835502 return func.fail("TODO: Implement @popCount for integers with bitsize '{d}'", .{bits});
......@@ -5527,7 +5546,8 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
55275546 // to make a copy of the ptr+value but can point towards them directly.
55285547 const error_table_symbol = try func.bin_file.getErrorTableSymbol();
55295548 const name_ty = Type.initTag(.const_slice_u8_sentinel_0);
5530 const abi_size = name_ty.abiSize(func.target);
5549 const mod = func.bin_file.base.options.module.?;
5550 const abi_size = name_ty.abiSize(mod);
55315551
55325552 const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation
55335553 try func.emitWValue(error_name_value);
......@@ -5566,12 +5586,13 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
55665586 const lhs_op = try func.resolveInst(extra.lhs);
55675587 const rhs_op = try func.resolveInst(extra.rhs);
55685588 const lhs_ty = func.air.typeOf(extra.lhs);
5589 const mod = func.bin_file.base.options.module.?;
55695590
5570 if (lhs_ty.zigTypeTag() == .Vector) {
5591 if (lhs_ty.zigTypeTag(mod) == .Vector) {
55715592 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
55725593 }
55735594
5574 const int_info = lhs_ty.intInfo(func.target);
5595 const int_info = lhs_ty.intInfo(mod);
55755596 const is_signed = int_info.signedness == .signed;
55765597 const wasm_bits = toWasmBits(int_info.bits) orelse {
55775598 return func.fail("TODO: Implement {{add/sub}}_with_overflow for integer bitsize: {d}", .{int_info.bits});
......@@ -5630,15 +5651,16 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
56305651
56315652 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));
56325653 try func.store(result_ptr, result, lhs_ty, 0);
5633 const offset = @intCast(u32, lhs_ty.abiSize(func.target));
5654 const offset = @intCast(u32, lhs_ty.abiSize(mod));
56345655 try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);
56355656
56365657 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
56375658}
56385659
56395660fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, result_ty: Type, op: Op) InnerError!WValue {
5661 const mod = func.bin_file.base.options.module.?;
56405662 assert(op == .add or op == .sub);
5641 const int_info = ty.intInfo(func.target);
5663 const int_info = ty.intInfo(mod);
56425664 const is_signed = int_info.signedness == .signed;
56435665 if (int_info.bits != 128) {
56445666 return func.fail("TODO: Implement @{{add/sub}}WithOverflow for integer bitsize '{d}'", .{int_info.bits});
......@@ -5701,6 +5723,7 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type,
57015723}
57025724
57035725fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5726 const mod = func.bin_file.base.options.module.?;
57045727 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
57055728 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;
57065729
......@@ -5709,11 +5732,11 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57095732 const lhs_ty = func.air.typeOf(extra.lhs);
57105733 const rhs_ty = func.air.typeOf(extra.rhs);
57115734
5712 if (lhs_ty.zigTypeTag() == .Vector) {
5735 if (lhs_ty.zigTypeTag(mod) == .Vector) {
57135736 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
57145737 }
57155738
5716 const int_info = lhs_ty.intInfo(func.target);
5739 const int_info = lhs_ty.intInfo(mod);
57175740 const is_signed = int_info.signedness == .signed;
57185741 const wasm_bits = toWasmBits(int_info.bits) orelse {
57195742 return func.fail("TODO: Implement shl_with_overflow for integer bitsize: {d}", .{int_info.bits});
......@@ -5721,7 +5744,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57215744
57225745 // Ensure rhs is coerced to lhs as they must have the same WebAssembly types
57235746 // before we can perform any binary operation.
5724 const rhs_wasm_bits = toWasmBits(rhs_ty.intInfo(func.target).bits).?;
5747 const rhs_wasm_bits = toWasmBits(rhs_ty.intInfo(mod).bits).?;
57255748 const rhs_final = if (wasm_bits != rhs_wasm_bits) blk: {
57265749 const rhs_casted = try func.intcast(rhs, rhs_ty, lhs_ty);
57275750 break :blk try rhs_casted.toLocal(func, lhs_ty);
......@@ -5750,7 +5773,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57505773
57515774 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));
57525775 try func.store(result_ptr, result, lhs_ty, 0);
5753 const offset = @intCast(u32, lhs_ty.abiSize(func.target));
5776 const offset = @intCast(u32, lhs_ty.abiSize(mod));
57545777 try func.store(result_ptr, overflow_local, Type.initTag(.u1), offset);
57555778
57565779 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
......@@ -5763,8 +5786,9 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57635786 const lhs = try func.resolveInst(extra.lhs);
57645787 const rhs = try func.resolveInst(extra.rhs);
57655788 const lhs_ty = func.air.typeOf(extra.lhs);
5789 const mod = func.bin_file.base.options.module.?;
57665790
5767 if (lhs_ty.zigTypeTag() == .Vector) {
5791 if (lhs_ty.zigTypeTag(mod) == .Vector) {
57685792 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
57695793 }
57705794
......@@ -5773,7 +5797,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57735797 var overflow_bit = try func.ensureAllocLocal(Type.initTag(.u1));
57745798 defer overflow_bit.free(func);
57755799
5776 const int_info = lhs_ty.intInfo(func.target);
5800 const int_info = lhs_ty.intInfo(mod);
57775801 const wasm_bits = toWasmBits(int_info.bits) orelse {
57785802 return func.fail("TODO: Implement `@mulWithOverflow` for integer bitsize: {d}", .{int_info.bits});
57795803 };
......@@ -5924,7 +5948,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59245948
59255949 const result_ptr = try func.allocStack(func.air.typeOfIndex(inst));
59265950 try func.store(result_ptr, bin_op_local, lhs_ty, 0);
5927 const offset = @intCast(u32, lhs_ty.abiSize(func.target));
5951 const offset = @intCast(u32, lhs_ty.abiSize(mod));
59285952 try func.store(result_ptr, overflow_bit, Type.initTag(.u1), offset);
59295953
59305954 func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
......@@ -5934,11 +5958,12 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerE
59345958 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
59355959
59365960 const ty = func.air.typeOfIndex(inst);
5937 if (ty.zigTypeTag() == .Vector) {
5961 const mod = func.bin_file.base.options.module.?;
5962 if (ty.zigTypeTag(mod) == .Vector) {
59385963 return func.fail("TODO: `@maximum` and `@minimum` for vectors", .{});
59395964 }
59405965
5941 if (ty.abiSize(func.target) > 16) {
5966 if (ty.abiSize(mod) > 16) {
59425967 return func.fail("TODO: `@maximum` and `@minimum` for types larger than 16 bytes", .{});
59435968 }
59445969
......@@ -5954,7 +5979,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: enum { max, min }) InnerE
59545979 try func.addTag(.select);
59555980
59565981 // store result in local
5957 const result_ty = if (isByRef(ty, func.target)) Type.u32 else ty;
5982 const result_ty = if (isByRef(ty, mod)) Type.u32 else ty;
59585983 const result = try func.allocLocal(result_ty);
59595984 try func.addLabel(.local_set, result.local.value);
59605985 func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
......@@ -5965,7 +5990,8 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59655990 const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;
59665991
59675992 const ty = func.air.typeOfIndex(inst);
5968 if (ty.zigTypeTag() == .Vector) {
5993 const mod = func.bin_file.base.options.module.?;
5994 if (ty.zigTypeTag(mod) == .Vector) {
59695995 return func.fail("TODO: `@mulAdd` for vectors", .{});
59705996 }
59715997
......@@ -5998,12 +6024,13 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
59986024
59996025 const ty = func.air.typeOf(ty_op.operand);
60006026 const result_ty = func.air.typeOfIndex(inst);
6001 if (ty.zigTypeTag() == .Vector) {
6027 const mod = func.bin_file.base.options.module.?;
6028 if (ty.zigTypeTag(mod) == .Vector) {
60026029 return func.fail("TODO: `@clz` for vectors", .{});
60036030 }
60046031
60056032 const operand = try func.resolveInst(ty_op.operand);
6006 const int_info = ty.intInfo(func.target);
6033 const int_info = ty.intInfo(mod);
60076034 const wasm_bits = toWasmBits(int_info.bits) orelse {
60086035 return func.fail("TODO: `@clz` for integers with bitsize '{d}'", .{int_info.bits});
60096036 };
......@@ -6051,12 +6078,13 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
60516078 const ty = func.air.typeOf(ty_op.operand);
60526079 const result_ty = func.air.typeOfIndex(inst);
60536080
6054 if (ty.zigTypeTag() == .Vector) {
6081 const mod = func.bin_file.base.options.module.?;
6082 if (ty.zigTypeTag(mod) == .Vector) {
60556083 return func.fail("TODO: `@ctz` for vectors", .{});
60566084 }
60576085
60586086 const operand = try func.resolveInst(ty_op.operand);
6059 const int_info = ty.intInfo(func.target);
6087 const int_info = ty.intInfo(mod);
60606088 const wasm_bits = toWasmBits(int_info.bits) orelse {
60616089 return func.fail("TODO: `@clz` for integers with bitsize '{d}'", .{int_info.bits});
60626090 };
......@@ -6174,12 +6202,13 @@ fn lowerTry(
61746202 err_union_ty: Type,
61756203 operand_is_ptr: bool,
61766204) InnerError!WValue {
6205 const mod = func.bin_file.base.options.module.?;
61776206 if (operand_is_ptr) {
61786207 return func.fail("TODO: lowerTry for pointers", .{});
61796208 }
61806209
61816210 const pl_ty = err_union_ty.errorUnionPayload();
6182 const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime();
6211 const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(mod);
61836212
61846213 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
61856214 // Block we can jump out of when error is not set
......@@ -6188,10 +6217,10 @@ fn lowerTry(
61886217 // check if the error tag is set for the error union.
61896218 try func.emitWValue(err_union);
61906219 if (pl_has_bits) {
6191 const err_offset = @intCast(u32, errUnionErrorOffset(pl_ty, func.target));
6220 const err_offset = @intCast(u32, errUnionErrorOffset(pl_ty, mod));
61926221 try func.addMemArg(.i32_load16_u, .{
61936222 .offset = err_union.offset() + err_offset,
6194 .alignment = Type.anyerror.abiAlignment(func.target),
6223 .alignment = Type.anyerror.abiAlignment(mod),
61956224 });
61966225 }
61976226 try func.addTag(.i32_eqz);
......@@ -6213,8 +6242,8 @@ fn lowerTry(
62136242 return WValue{ .none = {} };
62146243 }
62156244
6216 const pl_offset = @intCast(u32, errUnionPayloadOffset(pl_ty, func.target));
6217 if (isByRef(pl_ty, func.target)) {
6245 const pl_offset = @intCast(u32, errUnionPayloadOffset(pl_ty, mod));
6246 if (isByRef(pl_ty, mod)) {
62186247 return buildPointerOffset(func, err_union, pl_offset, .new);
62196248 }
62206249 const payload = try func.load(err_union, pl_ty, pl_offset);
......@@ -6226,11 +6255,12 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
62266255
62276256 const ty = func.air.typeOfIndex(inst);
62286257 const operand = try func.resolveInst(ty_op.operand);
6258 const mod = func.bin_file.base.options.module.?;
62296259
6230 if (ty.zigTypeTag() == .Vector) {
6260 if (ty.zigTypeTag(mod) == .Vector) {
62316261 return func.fail("TODO: @byteSwap for vectors", .{});
62326262 }
6233 const int_info = ty.intInfo(func.target);
6263 const int_info = ty.intInfo(mod);
62346264
62356265 // bytes are no-op
62366266 if (int_info.bits == 8) {
......@@ -6292,13 +6322,14 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
62926322}
62936323
62946324fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6325 const mod = func.bin_file.base.options.module.?;
62956326 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
62966327
62976328 const ty = func.air.typeOfIndex(inst);
62986329 const lhs = try func.resolveInst(bin_op.lhs);
62996330 const rhs = try func.resolveInst(bin_op.rhs);
63006331
6301 const result = if (ty.isSignedInt())
6332 const result = if (ty.isSignedInt(mod))
63026333 try func.divSigned(lhs, rhs, ty)
63036334 else
63046335 try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
......@@ -6306,13 +6337,14 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
63066337}
63076338
63086339fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6340 const mod = func.bin_file.base.options.module.?;
63096341 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
63106342
63116343 const ty = func.air.typeOfIndex(inst);
63126344 const lhs = try func.resolveInst(bin_op.lhs);
63136345 const rhs = try func.resolveInst(bin_op.rhs);
63146346
6315 const div_result = if (ty.isSignedInt())
6347 const div_result = if (ty.isSignedInt(mod))
63166348 try func.divSigned(lhs, rhs, ty)
63176349 else
63186350 try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
......@@ -6328,15 +6360,16 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
63286360fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
63296361 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
63306362
6363 const mod = func.bin_file.base.options.module.?;
63316364 const ty = func.air.typeOfIndex(inst);
63326365 const lhs = try func.resolveInst(bin_op.lhs);
63336366 const rhs = try func.resolveInst(bin_op.rhs);
63346367
6335 if (ty.isUnsignedInt()) {
6368 if (ty.isUnsignedInt(mod)) {
63366369 const result = try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
63376370 return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
6338 } else if (ty.isSignedInt()) {
6339 const int_bits = ty.intInfo(func.target).bits;
6371 } else if (ty.isSignedInt(mod)) {
6372 const int_bits = ty.intInfo(mod).bits;
63406373 const wasm_bits = toWasmBits(int_bits) orelse {
63416374 return func.fail("TODO: `@divFloor` for signed integers larger than '{d}' bits", .{int_bits});
63426375 };
......@@ -6414,7 +6447,8 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
64146447}
64156448
64166449fn divSigned(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type) InnerError!WValue {
6417 const int_bits = ty.intInfo(func.target).bits;
6450 const mod = func.bin_file.base.options.module.?;
6451 const int_bits = ty.intInfo(mod).bits;
64186452 const wasm_bits = toWasmBits(int_bits) orelse {
64196453 return func.fail("TODO: Implement signed division for integers with bitsize '{d}'", .{int_bits});
64206454 };
......@@ -6441,7 +6475,8 @@ fn divSigned(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type) InnerError!WVal
64416475/// Retrieves the absolute value of a signed integer
64426476/// NOTE: Leaves the result value on the stack.
64436477fn signAbsValue(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
6444 const int_bits = ty.intInfo(func.target).bits;
6478 const mod = func.bin_file.base.options.module.?;
6479 const int_bits = ty.intInfo(mod).bits;
64456480 const wasm_bits = toWasmBits(int_bits) orelse {
64466481 return func.fail("TODO: signAbsValue for signed integers larger than '{d}' bits", .{int_bits});
64476482 };
......@@ -6476,11 +6511,12 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
64766511 assert(op == .add or op == .sub);
64776512 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
64786513
6514 const mod = func.bin_file.base.options.module.?;
64796515 const ty = func.air.typeOfIndex(inst);
64806516 const lhs = try func.resolveInst(bin_op.lhs);
64816517 const rhs = try func.resolveInst(bin_op.rhs);
64826518
6483 const int_info = ty.intInfo(func.target);
6519 const int_info = ty.intInfo(mod);
64846520 const is_signed = int_info.signedness == .signed;
64856521
64866522 if (int_info.bits > 64) {
......@@ -6523,7 +6559,8 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
65236559}
65246560
65256561fn signedSat(func: *CodeGen, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op: Op) InnerError!WValue {
6526 const int_info = ty.intInfo(func.target);
6562 const mod = func.bin_file.base.options.module.?;
6563 const int_info = ty.intInfo(mod);
65276564 const wasm_bits = toWasmBits(int_info.bits).?;
65286565 const is_wasm_bits = wasm_bits == int_info.bits;
65296566
......@@ -6588,8 +6625,9 @@ fn signedSat(func: *CodeGen, lhs_operand: WValue, rhs_operand: WValue, ty: Type,
65886625fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
65896626 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
65906627
6628 const mod = func.bin_file.base.options.module.?;
65916629 const ty = func.air.typeOfIndex(inst);
6592 const int_info = ty.intInfo(func.target);
6630 const int_info = ty.intInfo(mod);
65936631 const is_signed = int_info.signedness == .signed;
65946632 if (int_info.bits > 64) {
65956633 return func.fail("TODO: Saturating shifting left for integers with bitsize '{d}'", .{int_info.bits});
......@@ -6707,12 +6745,13 @@ fn callIntrinsic(
67076745 };
67086746
67096747 // Always pass over C-ABI
6710 var func_type = try genFunctype(func.gpa, .C, param_types, return_type, func.target);
6748 const mod = func.bin_file.base.options.module.?;
6749 var func_type = try genFunctype(func.gpa, .C, param_types, return_type, mod);
67116750 defer func_type.deinit(func.gpa);
67126751 const func_type_index = try func.bin_file.putOrGetFuncType(func_type);
67136752 try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index);
67146753
6715 const want_sret_param = firstParamSRet(.C, return_type, func.target);
6754 const want_sret_param = firstParamSRet(.C, return_type, mod);
67166755 // if we want return as first param, we allocate a pointer to stack,
67176756 // and emit it as our first argument
67186757 const sret = if (want_sret_param) blk: {
......@@ -6724,14 +6763,14 @@ fn callIntrinsic(
67246763 // Lower all arguments to the stack before we call our function
67256764 for (args, 0..) |arg, arg_i| {
67266765 assert(!(want_sret_param and arg == .stack));
6727 assert(param_types[arg_i].hasRuntimeBitsIgnoreComptime());
6766 assert(param_types[arg_i].hasRuntimeBitsIgnoreComptime(mod));
67286767 try func.lowerArg(.C, param_types[arg_i], arg);
67296768 }
67306769
67316770 // Actually call our intrinsic
67326771 try func.addLabel(.call, symbol_index);
67336772
6734 if (!return_type.hasRuntimeBitsIgnoreComptime()) {
6773 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {
67356774 return WValue.none;
67366775 } else if (return_type.isNoReturn()) {
67376776 try func.addTag(.@"unreachable");
......@@ -6759,15 +6798,15 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
67596798}
67606799
67616800fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6801 const mod = func.bin_file.base.options.module.?;
67626802 const enum_decl_index = enum_ty.getOwnerDecl();
6763 const module = func.bin_file.base.options.module.?;
67646803
67656804 var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);
67666805 defer arena_allocator.deinit();
67676806 const arena = arena_allocator.allocator();
67686807
6769 const fqn = try module.declPtr(enum_decl_index).getFullyQualifiedName(module);
6770 defer module.gpa.free(fqn);
6808 const fqn = try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod);
6809 defer mod.gpa.free(fqn);
67716810 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
67726811
67736812 // check if we already generated code for this.
......@@ -6775,10 +6814,9 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
67756814 return loc.index;
67766815 }
67776816
6778 var int_tag_type_buffer: Type.Payload.Bits = undefined;
6779 const int_tag_ty = enum_ty.intTagType(&int_tag_type_buffer);
6817 const int_tag_ty = enum_ty.intTagType();
67806818
6781 if (int_tag_ty.bitSize(func.target) > 64) {
6819 if (int_tag_ty.bitSize(mod) > 64) {
67826820 return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{});
67836821 }
67846822
......@@ -6806,9 +6844,9 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
68066844 .data = @intCast(u64, tag_name.len),
68076845 };
68086846 const name_ty = Type.initPayload(&name_ty_payload.base);
6809 const string_bytes = &module.string_literal_bytes;
6810 try string_bytes.ensureUnusedCapacity(module.gpa, tag_name.len);
6811 const gop = try module.string_literal_table.getOrPutContextAdapted(module.gpa, tag_name, Module.StringLiteralAdapter{
6847 const string_bytes = &mod.string_literal_bytes;
6848 try string_bytes.ensureUnusedCapacity(mod.gpa, tag_name.len);
6849 const gop = try mod.string_literal_table.getOrPutContextAdapted(mod.gpa, tag_name, Module.StringLiteralAdapter{
68126850 .bytes = string_bytes,
68136851 }, Module.StringLiteralContext{
68146852 .bytes = string_bytes,
......@@ -6929,7 +6967,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
69296967 try writer.writeByte(std.wasm.opcode(.end));
69306968
69316969 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
6932 const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty}, slice_ty, func.target);
6970 const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty}, slice_ty, mod);
69336971 return func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);
69346972}
69356973
......@@ -6944,11 +6982,11 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
69446982 var values = try std.ArrayList(u32).initCapacity(func.gpa, names.len);
69456983 defer values.deinit();
69466984
6947 const module = func.bin_file.base.options.module.?;
6985 const mod = func.bin_file.base.options.module.?;
69486986 var lowest: ?u32 = null;
69496987 var highest: ?u32 = null;
69506988 for (names) |name| {
6951 const err_int = module.global_error_set.get(name).?;
6989 const err_int = mod.global_error_set.get(name).?;
69526990 if (lowest) |*l| {
69536991 if (err_int < l.*) {
69546992 l.* = err_int;
......@@ -7019,6 +7057,7 @@ inline fn useAtomicFeature(func: *const CodeGen) bool {
70197057}
70207058
70217059fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7060 const mod = func.bin_file.base.options.module.?;
70227061 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
70237062 const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
70247063
......@@ -7037,7 +7076,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
70377076 try func.emitWValue(ptr_operand);
70387077 try func.lowerToStack(expected_val);
70397078 try func.lowerToStack(new_val);
7040 try func.addAtomicMemArg(switch (ty.abiSize(func.target)) {
7079 try func.addAtomicMemArg(switch (ty.abiSize(mod)) {
70417080 1 => .i32_atomic_rmw8_cmpxchg_u,
70427081 2 => .i32_atomic_rmw16_cmpxchg_u,
70437082 4 => .i32_atomic_rmw_cmpxchg,
......@@ -7045,14 +7084,14 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
70457084 else => |size| return func.fail("TODO: implement `@cmpxchg` for types with abi size '{d}'", .{size}),
70467085 }, .{
70477086 .offset = ptr_operand.offset(),
7048 .alignment = ty.abiAlignment(func.target),
7087 .alignment = ty.abiAlignment(mod),
70497088 });
70507089 try func.addLabel(.local_tee, val_local.local.value);
70517090 _ = try func.cmp(.stack, expected_val, ty, .eq);
70527091 try func.addLabel(.local_set, cmp_result.local.value);
70537092 break :val val_local;
70547093 } else val: {
7055 if (ty.abiSize(func.target) > 8) {
7094 if (ty.abiSize(mod) > 8) {
70567095 return func.fail("TODO: Implement `@cmpxchg` for types larger than abi size of 8 bytes", .{});
70577096 }
70587097 const ptr_val = try WValue.toLocal(try func.load(ptr_operand, ty, 0), func, ty);
......@@ -7068,7 +7107,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
70687107 break :val ptr_val;
70697108 };
70707109
7071 const result_ptr = if (isByRef(result_ty, func.target)) val: {
7110 const result_ptr = if (isByRef(result_ty, mod)) val: {
70727111 try func.emitWValue(cmp_result);
70737112 try func.addImm32(-1);
70747113 try func.addTag(.i32_xor);
......@@ -7076,7 +7115,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
70767115 try func.addTag(.i32_and);
70777116 const and_result = try WValue.toLocal(.stack, func, Type.bool);
70787117 const result_ptr = try func.allocStack(result_ty);
7079 try func.store(result_ptr, and_result, Type.bool, @intCast(u32, ty.abiSize(func.target)));
7118 try func.store(result_ptr, and_result, Type.bool, @intCast(u32, ty.abiSize(mod)));
70807119 try func.store(result_ptr, ptr_val, ty, 0);
70817120 break :val result_ptr;
70827121 } else val: {
......@@ -7091,12 +7130,13 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
70917130}
70927131
70937132fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7133 const mod = func.bin_file.base.options.module.?;
70947134 const atomic_load = func.air.instructions.items(.data)[inst].atomic_load;
70957135 const ptr = try func.resolveInst(atomic_load.ptr);
70967136 const ty = func.air.typeOfIndex(inst);
70977137
70987138 if (func.useAtomicFeature()) {
7099 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(func.target)) {
7139 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {
71007140 1 => .i32_atomic_load8_u,
71017141 2 => .i32_atomic_load16_u,
71027142 4 => .i32_atomic_load,
......@@ -7106,7 +7146,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
71067146 try func.emitWValue(ptr);
71077147 try func.addAtomicMemArg(tag, .{
71087148 .offset = ptr.offset(),
7109 .alignment = ty.abiAlignment(func.target),
7149 .alignment = ty.abiAlignment(mod),
71107150 });
71117151 } else {
71127152 _ = try func.load(ptr, ty, 0);
......@@ -7117,6 +7157,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
71177157}
71187158
71197159fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7160 const mod = func.bin_file.base.options.module.?;
71207161 const pl_op = func.air.instructions.items(.data)[inst].pl_op;
71217162 const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data;
71227163
......@@ -7140,7 +7181,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
71407181 try func.emitWValue(ptr);
71417182 try func.emitWValue(value);
71427183 if (op == .Nand) {
7143 const wasm_bits = toWasmBits(@intCast(u16, ty.bitSize(func.target))).?;
7184 const wasm_bits = toWasmBits(@intCast(u16, ty.bitSize(mod))).?;
71447185
71457186 const and_res = try func.binOp(value, operand, ty, .@"and");
71467187 if (wasm_bits == 32)
......@@ -7157,7 +7198,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
71577198 try func.addTag(.select);
71587199 }
71597200 try func.addAtomicMemArg(
7160 switch (ty.abiSize(func.target)) {
7201 switch (ty.abiSize(mod)) {
71617202 1 => .i32_atomic_rmw8_cmpxchg_u,
71627203 2 => .i32_atomic_rmw16_cmpxchg_u,
71637204 4 => .i32_atomic_rmw_cmpxchg,
......@@ -7166,7 +7207,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
71667207 },
71677208 .{
71687209 .offset = ptr.offset(),
7169 .alignment = ty.abiAlignment(func.target),
7210 .alignment = ty.abiAlignment(mod),
71707211 },
71717212 );
71727213 const select_res = try func.allocLocal(ty);
......@@ -7185,7 +7226,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
71857226 else => {
71867227 try func.emitWValue(ptr);
71877228 try func.emitWValue(operand);
7188 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(func.target)) {
7229 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {
71897230 1 => switch (op) {
71907231 .Xchg => .i32_atomic_rmw8_xchg_u,
71917232 .Add => .i32_atomic_rmw8_add_u,
......@@ -7226,7 +7267,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
72267267 };
72277268 try func.addAtomicMemArg(tag, .{
72287269 .offset = ptr.offset(),
7229 .alignment = ty.abiAlignment(func.target),
7270 .alignment = ty.abiAlignment(mod),
72307271 });
72317272 const result = try WValue.toLocal(.stack, func, ty);
72327273 return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand });
......@@ -7255,7 +7296,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
72557296 .Xor => .xor,
72567297 else => unreachable,
72577298 });
7258 if (ty.isInt() and (op == .Add or op == .Sub)) {
7299 if (ty.isInt(mod) and (op == .Add or op == .Sub)) {
72597300 _ = try func.wrapOperand(.stack, ty);
72607301 }
72617302 try func.store(.stack, .stack, ty, ptr.offset());
......@@ -7271,7 +7312,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
72717312 try func.store(.stack, .stack, ty, ptr.offset());
72727313 },
72737314 .Nand => {
7274 const wasm_bits = toWasmBits(@intCast(u16, ty.bitSize(func.target))).?;
7315 const wasm_bits = toWasmBits(@intCast(u16, ty.bitSize(mod))).?;
72757316
72767317 try func.emitWValue(ptr);
72777318 const and_res = try func.binOp(result, operand, ty, .@"and");
......@@ -7302,6 +7343,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
73027343}
73037344
73047345fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7346 const mod = func.bin_file.base.options.module.?;
73057347 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
73067348
73077349 const ptr = try func.resolveInst(bin_op.lhs);
......@@ -7310,7 +7352,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
73107352 const ty = ptr_ty.childType();
73117353
73127354 if (func.useAtomicFeature()) {
7313 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(func.target)) {
7355 const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) {
73147356 1 => .i32_atomic_store8,
73157357 2 => .i32_atomic_store16,
73167358 4 => .i32_atomic_store,
......@@ -7321,7 +7363,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
73217363 try func.lowerToStack(operand);
73227364 try func.addAtomicMemArg(tag, .{
73237365 .offset = ptr.offset(),
7324 .alignment = ty.abiAlignment(func.target),
7366 .alignment = ty.abiAlignment(mod),
73257367 });
73267368 } else {
73277369 try func.store(ptr, operand, ty, 0);
src/arch/wasm/abi.zig+22-19
......@@ -5,9 +5,11 @@
55//! Note: Above mentioned document is not an official specification, therefore called a convention.
66
77const std = @import("std");
8const Type = @import("../../type.zig").Type;
98const Target = std.Target;
109
10const Type = @import("../../type.zig").Type;
11const Module = @import("../../Module.zig");
12
1113/// Defines how to pass a type as part of a function signature,
1214/// both for parameters as well as return values.
1315pub const Class = enum { direct, indirect, none };
......@@ -19,12 +21,13 @@ const direct: [2]Class = .{ .direct, .none };
1921/// Classifies a given Zig type to determine how they must be passed
2022/// or returned as value within a wasm function.
2123/// When all elements result in `.none`, no value must be passed in or returned.
22pub fn classifyType(ty: Type, target: Target) [2]Class {
23 if (!ty.hasRuntimeBitsIgnoreComptime()) return none;
24 switch (ty.zigTypeTag()) {
24pub fn classifyType(ty: Type, mod: *const Module) [2]Class {
25 const target = mod.getTarget();
26 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return none;
27 switch (ty.zigTypeTag(mod)) {
2528 .Struct => {
2629 if (ty.containerLayout() == .Packed) {
27 if (ty.bitSize(target) <= 64) return direct;
30 if (ty.bitSize(mod) <= 64) return direct;
2831 return .{ .direct, .direct };
2932 }
3033 // When the struct type is non-scalar
......@@ -32,14 +35,14 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {
3235 // When the struct's alignment is non-natural
3336 const field = ty.structFields().values()[0];
3437 if (field.abi_align != 0) {
35 if (field.abi_align > field.ty.abiAlignment(target)) {
38 if (field.abi_align > field.ty.abiAlignment(mod)) {
3639 return memory;
3740 }
3841 }
39 return classifyType(field.ty, target);
42 return classifyType(field.ty, mod);
4043 },
4144 .Int, .Enum, .ErrorSet, .Vector => {
42 const int_bits = ty.intInfo(target).bits;
45 const int_bits = ty.intInfo(mod).bits;
4346 if (int_bits <= 64) return direct;
4447 if (int_bits <= 128) return .{ .direct, .direct };
4548 return memory;
......@@ -53,7 +56,7 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {
5356 .Bool => return direct,
5457 .Array => return memory,
5558 .Optional => {
56 std.debug.assert(ty.isPtrLikeOptional());
59 std.debug.assert(ty.isPtrLikeOptional(mod));
5760 return direct;
5861 },
5962 .Pointer => {
......@@ -62,13 +65,13 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {
6265 },
6366 .Union => {
6467 if (ty.containerLayout() == .Packed) {
65 if (ty.bitSize(target) <= 64) return direct;
68 if (ty.bitSize(mod) <= 64) return direct;
6669 return .{ .direct, .direct };
6770 }
68 const layout = ty.unionGetLayout(target);
71 const layout = ty.unionGetLayout(mod);
6972 std.debug.assert(layout.tag_size == 0);
7073 if (ty.unionFields().count() > 1) return memory;
71 return classifyType(ty.unionFields().values()[0].ty, target);
74 return classifyType(ty.unionFields().values()[0].ty, mod);
7275 },
7376 .ErrorUnion,
7477 .Frame,
......@@ -90,29 +93,29 @@ pub fn classifyType(ty: Type, target: Target) [2]Class {
9093/// Returns the scalar type a given type can represent.
9194/// Asserts given type can be represented as scalar, such as
9295/// a struct with a single scalar field.
93pub fn scalarType(ty: Type, target: std.Target) Type {
94 switch (ty.zigTypeTag()) {
96pub fn scalarType(ty: Type, mod: *const Module) Type {
97 switch (ty.zigTypeTag(mod)) {
9598 .Struct => {
9699 switch (ty.containerLayout()) {
97100 .Packed => {
98101 const struct_obj = ty.castTag(.@"struct").?.data;
99 return scalarType(struct_obj.backing_int_ty, target);
102 return scalarType(struct_obj.backing_int_ty, mod);
100103 },
101104 else => {
102105 std.debug.assert(ty.structFieldCount() == 1);
103 return scalarType(ty.structFieldType(0), target);
106 return scalarType(ty.structFieldType(0), mod);
104107 },
105108 }
106109 },
107110 .Union => {
108111 if (ty.containerLayout() != .Packed) {
109 const layout = ty.unionGetLayout(target);
112 const layout = ty.unionGetLayout(mod);
110113 if (layout.payload_size == 0 and layout.tag_size != 0) {
111 return scalarType(ty.unionTagTypeSafety().?, target);
114 return scalarType(ty.unionTagTypeSafety().?, mod);
112115 }
113116 std.debug.assert(ty.unionFields().count() == 1);
114117 }
115 return scalarType(ty.unionFields().values()[0].ty, target);
118 return scalarType(ty.unionFields().values()[0].ty, mod);
116119 },
117120 else => return ty,
118121 }
src/arch/x86_64/CodeGen.zig+407-367
......@@ -605,14 +605,14 @@ const FrameAlloc = struct {
605605 .ref_count = 0,
606606 };
607607 }
608 fn initType(ty: Type, target: Target) FrameAlloc {
609 return init(.{ .size = ty.abiSize(target), .alignment = ty.abiAlignment(target) });
608 fn initType(ty: Type, mod: *const Module) FrameAlloc {
609 return init(.{ .size = ty.abiSize(mod), .alignment = ty.abiAlignment(mod) });
610610 }
611611};
612612
613613const StackAllocation = struct {
614614 inst: ?Air.Inst.Index,
615 /// TODO do we need size? should be determined by inst.ty.abiSize(self.target.*)
615 /// TODO do we need size? should be determined by inst.ty.abiSize(mod)
616616 size: u32,
617617};
618618
......@@ -714,12 +714,12 @@ pub fn generate(
714714 function.args = call_info.args;
715715 function.ret_mcv = call_info.return_value;
716716 function.frame_allocs.set(@enumToInt(FrameIndex.ret_addr), FrameAlloc.init(.{
717 .size = Type.usize.abiSize(function.target.*),
718 .alignment = @min(Type.usize.abiAlignment(function.target.*), call_info.stack_align),
717 .size = Type.usize.abiSize(mod),
718 .alignment = @min(Type.usize.abiAlignment(mod), call_info.stack_align),
719719 }));
720720 function.frame_allocs.set(@enumToInt(FrameIndex.base_ptr), FrameAlloc.init(.{
721 .size = Type.usize.abiSize(function.target.*),
722 .alignment = @min(Type.usize.abiAlignment(function.target.*) * 2, call_info.stack_align),
721 .size = Type.usize.abiSize(mod),
722 .alignment = @min(Type.usize.abiAlignment(mod) * 2, call_info.stack_align),
723723 }));
724724 function.frame_allocs.set(
725725 @enumToInt(FrameIndex.args_frame),
......@@ -1565,6 +1565,7 @@ fn asmMemoryRegisterImmediate(
15651565}
15661566
15671567fn gen(self: *Self) InnerError!void {
1568 const mod = self.bin_file.options.module.?;
15681569 const cc = self.fn_type.fnCallingConvention();
15691570 if (cc != .Naked) {
15701571 try self.asmRegister(.{ ._, .push }, .rbp);
......@@ -1582,7 +1583,7 @@ fn gen(self: *Self) InnerError!void {
15821583 // register which the callee is free to clobber. Therefore, we purposely
15831584 // spill it to stack immediately.
15841585 const frame_index =
1585 try self.allocFrameIndex(FrameAlloc.initType(Type.usize, self.target.*));
1586 try self.allocFrameIndex(FrameAlloc.initType(Type.usize, mod));
15861587 try self.genSetMem(
15871588 .{ .frame = frame_index },
15881589 0,
......@@ -1999,7 +2000,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
19992000}
20002001
20012002fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
2002 switch (lazy_sym.ty.zigTypeTag()) {
2003 const mod = self.bin_file.options.module.?;
2004 switch (lazy_sym.ty.zigTypeTag(mod)) {
20032005 .Enum => {
20042006 const enum_ty = lazy_sym.ty;
20052007 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(self.bin_file.options.module.?)});
......@@ -2127,8 +2129,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
21272129 tomb_bits >>= 1;
21282130 if (!dies) continue;
21292131 const op_int = @enumToInt(op);
2130 if (op_int < Air.Inst.Ref.typed_value_map.len) continue;
2131 const op_index = @intCast(Air.Inst.Index, op_int - Air.Inst.Ref.typed_value_map.len);
2132 if (op_int < Air.ref_start_index) continue;
2133 const op_index = @intCast(Air.Inst.Index, op_int - Air.ref_start_index);
21322134 self.processDeath(op_index);
21332135 }
21342136 self.finishAirResult(inst, result);
......@@ -2252,14 +2254,14 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {
22522254
22532255/// Use a pointer instruction as the basis for allocating stack memory.
22542256fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {
2257 const mod = self.bin_file.options.module.?;
22552258 const ptr_ty = self.air.typeOfIndex(inst);
22562259 const val_ty = ptr_ty.childType();
22572260 return self.allocFrameIndex(FrameAlloc.init(.{
2258 .size = math.cast(u32, val_ty.abiSize(self.target.*)) orelse {
2259 const mod = self.bin_file.options.module.?;
2261 .size = math.cast(u32, val_ty.abiSize(mod)) orelse {
22602262 return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(mod)});
22612263 },
2262 .alignment = @max(ptr_ty.ptrAlignment(self.target.*), 1),
2264 .alignment = @max(ptr_ty.ptrAlignment(mod), 1),
22632265 }));
22642266}
22652267
......@@ -2272,19 +2274,19 @@ fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue {
22722274}
22732275
22742276fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue {
2275 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) orelse {
2276 const mod = self.bin_file.options.module.?;
2277 const mod = self.bin_file.options.module.?;
2278 const abi_size = math.cast(u32, ty.abiSize(mod)) orelse {
22772279 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});
22782280 };
22792281
22802282 if (reg_ok) need_mem: {
2281 if (abi_size <= @as(u32, switch (ty.zigTypeTag()) {
2283 if (abi_size <= @as(u32, switch (ty.zigTypeTag(mod)) {
22822284 .Float => switch (ty.floatBits(self.target.*)) {
22832285 16, 32, 64, 128 => 16,
22842286 80 => break :need_mem,
22852287 else => unreachable,
22862288 },
2287 .Vector => switch (ty.childType().zigTypeTag()) {
2289 .Vector => switch (ty.childType().zigTypeTag(mod)) {
22882290 .Float => switch (ty.childType().floatBits(self.target.*)) {
22892291 16, 32, 64, 128 => if (self.hasFeature(.avx)) 32 else 16,
22902292 80 => break :need_mem,
......@@ -2294,18 +2296,18 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b
22942296 },
22952297 else => 8,
22962298 })) {
2297 if (self.register_manager.tryAllocReg(inst, regClassForType(ty))) |reg| {
2299 if (self.register_manager.tryAllocReg(inst, regClassForType(ty, mod))) |reg| {
22982300 return MCValue{ .register = registerAlias(reg, abi_size) };
22992301 }
23002302 }
23012303 }
23022304
2303 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(ty, self.target.*));
2305 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(ty, mod));
23042306 return .{ .load_frame = .{ .index = frame_index } };
23052307}
23062308
2307fn regClassForType(ty: Type) RegisterManager.RegisterBitSet {
2308 return switch (ty.zigTypeTag()) {
2309fn regClassForType(ty: Type, mod: *const Module) RegisterManager.RegisterBitSet {
2310 return switch (ty.zigTypeTag(mod)) {
23092311 .Float, .Vector => sse,
23102312 else => gp,
23112313 };
......@@ -2449,7 +2451,8 @@ pub fn spillRegisters(self: *Self, registers: []const Register) !void {
24492451/// allocated. A second call to `copyToTmpRegister` may return the same register.
24502452/// This can have a side effect of spilling instructions to the stack to free up a register.
24512453fn copyToTmpRegister(self: *Self, ty: Type, mcv: MCValue) !Register {
2452 const reg = try self.register_manager.allocReg(null, regClassForType(ty));
2454 const mod = self.bin_file.options.module.?;
2455 const reg = try self.register_manager.allocReg(null, regClassForType(ty, mod));
24532456 try self.genSetReg(reg, ty, mcv);
24542457 return reg;
24552458}
......@@ -2464,7 +2467,8 @@ fn copyToRegisterWithInstTracking(
24642467 ty: Type,
24652468 mcv: MCValue,
24662469) !MCValue {
2467 const reg: Register = try self.register_manager.allocReg(reg_owner, regClassForType(ty));
2470 const mod = self.bin_file.options.module.?;
2471 const reg: Register = try self.register_manager.allocReg(reg_owner, regClassForType(ty, mod));
24682472 try self.genSetReg(reg, ty, mcv);
24692473 return MCValue{ .register = reg };
24702474}
......@@ -2618,14 +2622,15 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
26182622}
26192623
26202624fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
2625 const mod = self.bin_file.options.module.?;
26212626 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
26222627 const result: MCValue = result: {
26232628 const src_ty = self.air.typeOf(ty_op.operand);
2624 const src_int_info = src_ty.intInfo(self.target.*);
2629 const src_int_info = src_ty.intInfo(mod);
26252630
26262631 const dst_ty = self.air.typeOfIndex(inst);
2627 const dst_int_info = dst_ty.intInfo(self.target.*);
2628 const abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
2632 const dst_int_info = dst_ty.intInfo(mod);
2633 const abi_size = @intCast(u32, dst_ty.abiSize(mod));
26292634
26302635 const min_ty = if (dst_int_info.bits < src_int_info.bits) dst_ty else src_ty;
26312636 const extend = switch (src_int_info.signedness) {
......@@ -2670,14 +2675,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
26702675
26712676 const high_bits = src_int_info.bits % 64;
26722677 if (high_bits > 0) {
2673 var high_pl = Type.Payload.Bits{
2674 .base = .{ .tag = switch (extend) {
2675 .signed => .int_signed,
2676 .unsigned => .int_unsigned,
2677 } },
2678 .data = high_bits,
2679 };
2680 const high_ty = Type.initPayload(&high_pl.base);
2678 const high_ty = try mod.intType(extend, high_bits);
26812679 try self.truncateRegister(high_ty, high_reg);
26822680 try self.genCopy(Type.usize, high_mcv, .{ .register = high_reg });
26832681 }
......@@ -2706,12 +2704,13 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
27062704}
27072705
27082706fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2707 const mod = self.bin_file.options.module.?;
27092708 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27102709
27112710 const dst_ty = self.air.typeOfIndex(inst);
2712 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
2711 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
27132712 const src_ty = self.air.typeOf(ty_op.operand);
2714 const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*));
2713 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
27152714
27162715 const result = result: {
27172716 const src_mcv = try self.resolveInst(ty_op.operand);
......@@ -2724,10 +2723,10 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
27242723 else
27252724 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
27262725
2727 if (dst_ty.zigTypeTag() == .Vector) {
2728 assert(src_ty.zigTypeTag() == .Vector and dst_ty.vectorLen() == src_ty.vectorLen());
2729 const dst_info = dst_ty.childType().intInfo(self.target.*);
2730 const src_info = src_ty.childType().intInfo(self.target.*);
2726 if (dst_ty.zigTypeTag(mod) == .Vector) {
2727 assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen() == src_ty.vectorLen());
2728 const dst_info = dst_ty.childType().intInfo(mod);
2729 const src_info = src_ty.childType().intInfo(mod);
27312730 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (dst_info.bits) {
27322731 8 => switch (src_info.bits) {
27332732 16 => switch (dst_ty.vectorLen()) {
......@@ -2775,7 +2774,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
27752774 },
27762775 };
27772776 const full_ty = Type.initPayload(&full_pl.base);
2778 const full_abi_size = @intCast(u32, full_ty.abiSize(self.target.*));
2777 const full_abi_size = @intCast(u32, full_ty.abiSize(mod));
27792778
27802779 const splat_mcv = try self.genTypedValue(.{ .ty = full_ty, .val = splat_val });
27812780 const splat_addr_mcv: MCValue = switch (splat_mcv) {
......@@ -2831,6 +2830,7 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {
28312830}
28322831
28332832fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
2833 const mod = self.bin_file.options.module.?;
28342834 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
28352835 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
28362836
......@@ -2840,11 +2840,11 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
28402840 const len = try self.resolveInst(bin_op.rhs);
28412841 const len_ty = self.air.typeOf(bin_op.rhs);
28422842
2843 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(slice_ty, self.target.*));
2843 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(slice_ty, mod));
28442844 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
28452845 try self.genSetMem(
28462846 .{ .frame = frame_index },
2847 @intCast(i32, ptr_ty.abiSize(self.target.*)),
2847 @intCast(i32, ptr_ty.abiSize(mod)),
28482848 len_ty,
28492849 len,
28502850 );
......@@ -2873,23 +2873,24 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
28732873}
28742874
28752875fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
2876 const mod = self.bin_file.options.module.?;
28762877 const air_tag = self.air.instructions.items(.tag);
28772878 const air_data = self.air.instructions.items(.data);
28782879
28792880 const dst_ty = self.air.typeOf(dst_air);
2880 const dst_info = dst_ty.intInfo(self.target.*);
2881 const dst_info = dst_ty.intInfo(mod);
28812882 if (Air.refToIndex(dst_air)) |inst| {
28822883 switch (air_tag[inst]) {
28832884 .constant => {
28842885 const src_val = self.air.values[air_data[inst].ty_pl.payload];
28852886 var space: Value.BigIntSpace = undefined;
2886 const src_int = src_val.toBigInt(&space, self.target.*);
2887 const src_int = src_val.toBigInt(&space, mod);
28872888 return @intCast(u16, src_int.bitCountTwosComp()) +
28882889 @boolToInt(src_int.positive and dst_info.signedness == .signed);
28892890 },
28902891 .intcast => {
28912892 const src_ty = self.air.typeOf(air_data[inst].ty_op.operand);
2892 const src_info = src_ty.intInfo(self.target.*);
2893 const src_info = src_ty.intInfo(mod);
28932894 return @min(switch (src_info.signedness) {
28942895 .signed => switch (dst_info.signedness) {
28952896 .signed => src_info.bits,
......@@ -2908,20 +2909,18 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
29082909}
29092910
29102911fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
2912 const mod = self.bin_file.options.module.?;
29112913 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
29122914 const result = result: {
29132915 const tag = self.air.instructions.items(.tag)[inst];
29142916 const dst_ty = self.air.typeOfIndex(inst);
2915 switch (dst_ty.zigTypeTag()) {
2917 switch (dst_ty.zigTypeTag(mod)) {
29162918 .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs),
29172919 else => {},
29182920 }
29192921
2920 const dst_info = dst_ty.intInfo(self.target.*);
2921 var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) {
2922 .signed => .int_signed,
2923 .unsigned => .int_unsigned,
2924 } }, .data = switch (tag) {
2922 const dst_info = dst_ty.intInfo(mod);
2923 const src_ty = try mod.intType(dst_info.signedness, switch (tag) {
29252924 else => unreachable,
29262925 .mul, .mulwrap => math.max3(
29272926 self.activeIntBits(bin_op.lhs),
......@@ -2929,8 +2928,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
29292928 dst_info.bits / 2,
29302929 ),
29312930 .div_trunc, .div_floor, .div_exact, .rem, .mod => dst_info.bits,
2932 } };
2933 const src_ty = Type.initPayload(&src_pl.base);
2931 });
29342932
29352933 try self.spillEflagsIfOccupied();
29362934 try self.spillRegisters(&.{ .rax, .rdx });
......@@ -2942,6 +2940,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
29422940}
29432941
29442942fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
2943 const mod = self.bin_file.options.module.?;
29452944 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
29462945 const ty = self.air.typeOf(bin_op.lhs);
29472946
......@@ -2968,7 +2967,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
29682967
29692968 const reg_bits = self.regBitSize(ty);
29702969 const reg_extra_bits = self.regExtraBits(ty);
2971 const cc: Condition = if (ty.isSignedInt()) cc: {
2970 const cc: Condition = if (ty.isSignedInt(mod)) cc: {
29722971 if (reg_extra_bits > 0) {
29732972 try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });
29742973 }
......@@ -2994,7 +2993,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
29942993 break :cc .o;
29952994 } else cc: {
29962995 try self.genSetReg(limit_reg, ty, .{
2997 .immediate = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - ty.bitSize(self.target.*)),
2996 .immediate = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - ty.bitSize(mod)),
29982997 });
29992998
30002999 try self.genBinOpMir(.{ ._, .add }, ty, dst_mcv, rhs_mcv);
......@@ -3005,14 +3004,14 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
30053004 break :cc .c;
30063005 };
30073006
3008 const cmov_abi_size = @max(@intCast(u32, ty.abiSize(self.target.*)), 2);
3007 const cmov_abi_size = @max(@intCast(u32, ty.abiSize(mod)), 2);
30093008 try self.asmCmovccRegisterRegister(
30103009 registerAlias(dst_reg, cmov_abi_size),
30113010 registerAlias(limit_reg, cmov_abi_size),
30123011 cc,
30133012 );
30143013
3015 if (reg_extra_bits > 0 and ty.isSignedInt()) {
3014 if (reg_extra_bits > 0 and ty.isSignedInt(mod)) {
30163015 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });
30173016 }
30183017
......@@ -3020,6 +3019,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
30203019}
30213020
30223021fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3022 const mod = self.bin_file.options.module.?;
30233023 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
30243024 const ty = self.air.typeOf(bin_op.lhs);
30253025
......@@ -3046,7 +3046,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
30463046
30473047 const reg_bits = self.regBitSize(ty);
30483048 const reg_extra_bits = self.regExtraBits(ty);
3049 const cc: Condition = if (ty.isSignedInt()) cc: {
3049 const cc: Condition = if (ty.isSignedInt(mod)) cc: {
30503050 if (reg_extra_bits > 0) {
30513051 try self.genShiftBinOpMir(.{ ._l, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });
30523052 }
......@@ -3076,14 +3076,14 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
30763076 break :cc .c;
30773077 };
30783078
3079 const cmov_abi_size = @max(@intCast(u32, ty.abiSize(self.target.*)), 2);
3079 const cmov_abi_size = @max(@intCast(u32, ty.abiSize(mod)), 2);
30803080 try self.asmCmovccRegisterRegister(
30813081 registerAlias(dst_reg, cmov_abi_size),
30823082 registerAlias(limit_reg, cmov_abi_size),
30833083 cc,
30843084 );
30853085
3086 if (reg_extra_bits > 0 and ty.isSignedInt()) {
3086 if (reg_extra_bits > 0 and ty.isSignedInt(mod)) {
30873087 try self.genShiftBinOpMir(.{ ._r, .sa }, ty, dst_mcv, .{ .immediate = reg_extra_bits });
30883088 }
30893089
......@@ -3091,6 +3091,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
30913091}
30923092
30933093fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
3094 const mod = self.bin_file.options.module.?;
30943095 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
30953096 const ty = self.air.typeOf(bin_op.lhs);
30963097
......@@ -3118,7 +3119,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
31183119 defer self.register_manager.unlockReg(limit_lock);
31193120
31203121 const reg_bits = self.regBitSize(ty);
3121 const cc: Condition = if (ty.isSignedInt()) cc: {
3122 const cc: Condition = if (ty.isSignedInt(mod)) cc: {
31223123 try self.genSetReg(limit_reg, ty, lhs_mcv);
31233124 try self.genBinOpMir(.{ ._, .xor }, ty, limit_mcv, rhs_mcv);
31243125 try self.genShiftBinOpMir(.{ ._, .sa }, ty, limit_mcv, .{ .immediate = reg_bits - 1 });
......@@ -3134,7 +3135,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
31343135 };
31353136
31363137 const dst_mcv = try self.genMulDivBinOp(.mul, inst, ty, ty, lhs_mcv, rhs_mcv);
3137 const cmov_abi_size = @max(@intCast(u32, ty.abiSize(self.target.*)), 2);
3138 const cmov_abi_size = @max(@intCast(u32, ty.abiSize(mod)), 2);
31383139 try self.asmCmovccRegisterRegister(
31393140 registerAlias(dst_mcv.register, cmov_abi_size),
31403141 registerAlias(limit_reg, cmov_abi_size),
......@@ -3145,12 +3146,13 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
31453146}
31463147
31473148fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3149 const mod = self.bin_file.options.module.?;
31483150 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
31493151 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
31503152 const result: MCValue = result: {
31513153 const tag = self.air.instructions.items(.tag)[inst];
31523154 const ty = self.air.typeOf(bin_op.lhs);
3153 switch (ty.zigTypeTag()) {
3155 switch (ty.zigTypeTag(mod)) {
31543156 .Vector => return self.fail("TODO implement add/sub with overflow for Vector type", .{}),
31553157 .Int => {
31563158 try self.spillEflagsIfOccupied();
......@@ -3160,7 +3162,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
31603162 .sub_with_overflow => .sub,
31613163 else => unreachable,
31623164 }, bin_op.lhs, bin_op.rhs);
3163 const int_info = ty.intInfo(self.target.*);
3165 const int_info = ty.intInfo(mod);
31643166 const cc: Condition = switch (int_info.signedness) {
31653167 .unsigned => .c,
31663168 .signed => .o,
......@@ -3177,16 +3179,16 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
31773179 }
31783180
31793181 const frame_index =
3180 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));
3182 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
31813183 try self.genSetMem(
31823184 .{ .frame = frame_index },
3183 @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)),
3185 @intCast(i32, tuple_ty.structFieldOffset(1, mod)),
31843186 Type.u1,
31853187 .{ .eflags = cc },
31863188 );
31873189 try self.genSetMem(
31883190 .{ .frame = frame_index },
3189 @intCast(i32, tuple_ty.structFieldOffset(0, self.target.*)),
3191 @intCast(i32, tuple_ty.structFieldOffset(0, mod)),
31903192 ty,
31913193 partial_mcv,
31923194 );
......@@ -3194,7 +3196,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
31943196 }
31953197
31963198 const frame_index =
3197 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));
3199 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
31983200 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
31993201 break :result .{ .load_frame = .{ .index = frame_index } };
32003202 },
......@@ -3205,12 +3207,13 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
32053207}
32063208
32073209fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3210 const mod = self.bin_file.options.module.?;
32083211 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
32093212 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
32103213 const result: MCValue = result: {
32113214 const lhs_ty = self.air.typeOf(bin_op.lhs);
32123215 const rhs_ty = self.air.typeOf(bin_op.rhs);
3213 switch (lhs_ty.zigTypeTag()) {
3216 switch (lhs_ty.zigTypeTag(mod)) {
32143217 .Vector => return self.fail("TODO implement shl with overflow for Vector type", .{}),
32153218 .Int => {
32163219 try self.spillEflagsIfOccupied();
......@@ -3219,7 +3222,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
32193222 const lhs = try self.resolveInst(bin_op.lhs);
32203223 const rhs = try self.resolveInst(bin_op.rhs);
32213224
3222 const int_info = lhs_ty.intInfo(self.target.*);
3225 const int_info = lhs_ty.intInfo(mod);
32233226
32243227 const partial_mcv = try self.genShiftBinOp(.shl, null, lhs, rhs, lhs_ty, rhs_ty);
32253228 const partial_lock = switch (partial_mcv) {
......@@ -3249,16 +3252,16 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
32493252 }
32503253
32513254 const frame_index =
3252 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));
3255 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
32533256 try self.genSetMem(
32543257 .{ .frame = frame_index },
3255 @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)),
3258 @intCast(i32, tuple_ty.structFieldOffset(1, mod)),
32563259 tuple_ty.structFieldType(1),
32573260 .{ .eflags = cc },
32583261 );
32593262 try self.genSetMem(
32603263 .{ .frame = frame_index },
3261 @intCast(i32, tuple_ty.structFieldOffset(0, self.target.*)),
3264 @intCast(i32, tuple_ty.structFieldOffset(0, mod)),
32623265 tuple_ty.structFieldType(0),
32633266 partial_mcv,
32643267 );
......@@ -3266,7 +3269,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
32663269 }
32673270
32683271 const frame_index =
3269 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));
3272 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
32703273 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
32713274 break :result .{ .load_frame = .{ .index = frame_index } };
32723275 },
......@@ -3283,6 +3286,7 @@ fn genSetFrameTruncatedOverflowCompare(
32833286 src_mcv: MCValue,
32843287 overflow_cc: ?Condition,
32853288) !void {
3289 const mod = self.bin_file.options.module.?;
32863290 const src_lock = switch (src_mcv) {
32873291 .register => |reg| self.register_manager.lockReg(reg),
32883292 else => null,
......@@ -3290,22 +3294,12 @@ fn genSetFrameTruncatedOverflowCompare(
32903294 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
32913295
32923296 const ty = tuple_ty.structFieldType(0);
3293 const int_info = ty.intInfo(self.target.*);
3297 const int_info = ty.intInfo(mod);
32943298
3295 var hi_limb_pl = Type.Payload.Bits{
3296 .base = .{ .tag = switch (int_info.signedness) {
3297 .signed => .int_signed,
3298 .unsigned => .int_unsigned,
3299 } },
3300 .data = (int_info.bits - 1) % 64 + 1,
3301 };
3302 const hi_limb_ty = Type.initPayload(&hi_limb_pl.base);
3299 const hi_limb_bits = (int_info.bits - 1) % 64 + 1;
3300 const hi_limb_ty = try mod.intType(int_info.signedness, hi_limb_bits);
33033301
3304 var rest_pl = Type.Payload.Bits{
3305 .base = .{ .tag = .int_unsigned },
3306 .data = int_info.bits - hi_limb_pl.data,
3307 };
3308 const rest_ty = Type.initPayload(&rest_pl.base);
3302 const rest_ty = try mod.intType(.unsigned, int_info.bits - hi_limb_bits);
33093303
33103304 const temp_regs = try self.register_manager.allocRegs(3, .{ null, null, null }, gp);
33113305 const temp_locks = self.register_manager.lockRegsAssumeUnused(3, temp_regs);
......@@ -3335,7 +3329,7 @@ fn genSetFrameTruncatedOverflowCompare(
33353329 );
33363330 }
33373331
3338 const payload_off = @intCast(i32, tuple_ty.structFieldOffset(0, self.target.*));
3332 const payload_off = @intCast(i32, tuple_ty.structFieldOffset(0, mod));
33393333 if (hi_limb_off > 0) try self.genSetMem(.{ .frame = frame_index }, payload_off, rest_ty, src_mcv);
33403334 try self.genSetMem(
33413335 .{ .frame = frame_index },
......@@ -3345,23 +3339,24 @@ fn genSetFrameTruncatedOverflowCompare(
33453339 );
33463340 try self.genSetMem(
33473341 .{ .frame = frame_index },
3348 @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)),
3342 @intCast(i32, tuple_ty.structFieldOffset(1, mod)),
33493343 tuple_ty.structFieldType(1),
33503344 if (overflow_cc) |_| .{ .register = overflow_reg.to8() } else .{ .eflags = .ne },
33513345 );
33523346}
33533347
33543348fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3349 const mod = self.bin_file.options.module.?;
33553350 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
33563351 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
33573352 const dst_ty = self.air.typeOf(bin_op.lhs);
3358 const result: MCValue = switch (dst_ty.zigTypeTag()) {
3353 const result: MCValue = switch (dst_ty.zigTypeTag(mod)) {
33593354 .Vector => return self.fail("TODO implement mul_with_overflow for Vector type", .{}),
33603355 .Int => result: {
33613356 try self.spillEflagsIfOccupied();
33623357 try self.spillRegisters(&.{ .rax, .rdx });
33633358
3364 const dst_info = dst_ty.intInfo(self.target.*);
3359 const dst_info = dst_ty.intInfo(mod);
33653360 const cc: Condition = switch (dst_info.signedness) {
33663361 .unsigned => .c,
33673362 .signed => .o,
......@@ -3369,11 +3364,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
33693364
33703365 const lhs_active_bits = self.activeIntBits(bin_op.lhs);
33713366 const rhs_active_bits = self.activeIntBits(bin_op.rhs);
3372 var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) {
3373 .signed => .int_signed,
3374 .unsigned => .int_unsigned,
3375 } }, .data = math.max3(lhs_active_bits, rhs_active_bits, dst_info.bits / 2) };
3376 const src_ty = Type.initPayload(&src_pl.base);
3367 const src_bits = math.max3(lhs_active_bits, rhs_active_bits, dst_info.bits / 2);
3368 const src_ty = try mod.intType(dst_info.signedness, src_bits);
33773369
33783370 const lhs = try self.resolveInst(bin_op.lhs);
33793371 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -3391,26 +3383,26 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
33913383 break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } };
33923384 } else {
33933385 const frame_index =
3394 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));
3386 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
33953387 try self.genSetFrameTruncatedOverflowCompare(tuple_ty, frame_index, partial_mcv, cc);
33963388 break :result .{ .load_frame = .{ .index = frame_index } };
33973389 },
33983390 else => {
33993391 // For now, this is the only supported multiply that doesn't fit in a register.
3400 assert(dst_info.bits <= 128 and src_pl.data == 64);
3392 assert(dst_info.bits <= 128 and src_bits == 64);
34013393
34023394 const frame_index =
3403 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, self.target.*));
3395 try self.allocFrameIndex(FrameAlloc.initType(tuple_ty, mod));
34043396 if (dst_info.bits >= lhs_active_bits + rhs_active_bits) {
34053397 try self.genSetMem(
34063398 .{ .frame = frame_index },
3407 @intCast(i32, tuple_ty.structFieldOffset(0, self.target.*)),
3399 @intCast(i32, tuple_ty.structFieldOffset(0, mod)),
34083400 tuple_ty.structFieldType(0),
34093401 partial_mcv,
34103402 );
34113403 try self.genSetMem(
34123404 .{ .frame = frame_index },
3413 @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)),
3405 @intCast(i32, tuple_ty.structFieldOffset(1, mod)),
34143406 tuple_ty.structFieldType(1),
34153407 .{ .immediate = 0 }, // cc being set is impossible
34163408 );
......@@ -3433,7 +3425,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
34333425/// Clobbers .rax and .rdx registers.
34343426/// Quotient is saved in .rax and remainder in .rdx.
34353427fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void {
3436 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
3428 const mod = self.bin_file.options.module.?;
3429 const abi_size = @intCast(u32, ty.abiSize(mod));
34373430 if (abi_size > 8) {
34383431 return self.fail("TODO implement genIntMulDivOpMir for ABI size larger than 8", .{});
34393432 }
......@@ -3472,8 +3465,9 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue
34723465/// Always returns a register.
34733466/// Clobbers .rax and .rdx registers.
34743467fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue {
3475 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
3476 const int_info = ty.intInfo(self.target.*);
3468 const mod = self.bin_file.options.module.?;
3469 const abi_size = @intCast(u32, ty.abiSize(mod));
3470 const int_info = ty.intInfo(mod);
34773471 const dividend: Register = switch (lhs) {
34783472 .register => |reg| reg,
34793473 else => try self.copyToTmpRegister(ty, lhs),
......@@ -3585,6 +3579,7 @@ fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
35853579}
35863580
35873581fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3582 const mod = self.bin_file.options.module.?;
35883583 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
35893584 const result = result: {
35903585 const dst_ty = self.air.typeOfIndex(inst);
......@@ -3592,7 +3587,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
35923587 const opt_ty = src_ty.childType();
35933588 const src_mcv = try self.resolveInst(ty_op.operand);
35943589
3595 if (opt_ty.optionalReprIsPayload()) {
3590 if (opt_ty.optionalReprIsPayload(mod)) {
35963591 break :result if (self.liveness.isUnused(inst))
35973592 .unreach
35983593 else if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
......@@ -3610,7 +3605,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
36103605 try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
36113606
36123607 const pl_ty = dst_ty.childType();
3613 const pl_abi_size = @intCast(i32, pl_ty.abiSize(self.target.*));
3608 const pl_abi_size = @intCast(i32, pl_ty.abiSize(mod));
36143609 try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 });
36153610 break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv;
36163611 };
......@@ -3618,6 +3613,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
36183613}
36193614
36203615fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3616 const mod = self.bin_file.options.module.?;
36213617 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
36223618 const err_union_ty = self.air.typeOf(ty_op.operand);
36233619 const err_ty = err_union_ty.errorUnionSet();
......@@ -3629,11 +3625,11 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
36293625 break :result MCValue{ .immediate = 0 };
36303626 }
36313627
3632 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3628 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
36333629 break :result operand;
36343630 }
36353631
3636 const err_off = errUnionErrorOffset(payload_ty, self.target.*);
3632 const err_off = errUnionErrorOffset(payload_ty, mod);
36373633 switch (operand) {
36383634 .register => |reg| {
36393635 // TODO reuse operand
......@@ -3678,12 +3674,13 @@ fn genUnwrapErrorUnionPayloadMir(
36783674 err_union_ty: Type,
36793675 err_union: MCValue,
36803676) !MCValue {
3677 const mod = self.bin_file.options.module.?;
36813678 const payload_ty = err_union_ty.errorUnionPayload();
36823679
36833680 const result: MCValue = result: {
3684 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result .none;
3681 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
36853682
3686 const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);
3683 const payload_off = errUnionPayloadOffset(payload_ty, mod);
36873684 switch (err_union) {
36883685 .load_frame => |frame_addr| break :result .{ .load_frame = .{
36893686 .index = frame_addr.index,
......@@ -3720,6 +3717,7 @@ fn genUnwrapErrorUnionPayloadMir(
37203717
37213718// *(E!T) -> E
37223719fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
3720 const mod = self.bin_file.options.module.?;
37233721 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
37243722
37253723 const src_ty = self.air.typeOf(ty_op.operand);
......@@ -3739,8 +3737,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
37393737 const eu_ty = src_ty.childType();
37403738 const pl_ty = eu_ty.errorUnionPayload();
37413739 const err_ty = eu_ty.errorUnionSet();
3742 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));
3743 const err_abi_size = @intCast(u32, err_ty.abiSize(self.target.*));
3740 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
3741 const err_abi_size = @intCast(u32, err_ty.abiSize(mod));
37443742 try self.asmRegisterMemory(
37453743 .{ ._, .mov },
37463744 registerAlias(dst_reg, err_abi_size),
......@@ -3755,6 +3753,7 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
37553753
37563754// *(E!T) -> *T
37573755fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
3756 const mod = self.bin_file.options.module.?;
37583757 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
37593758
37603759 const src_ty = self.air.typeOf(ty_op.operand);
......@@ -3777,8 +3776,8 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
37773776
37783777 const eu_ty = src_ty.childType();
37793778 const pl_ty = eu_ty.errorUnionPayload();
3780 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*));
3781 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
3779 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));
3780 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
37823781 try self.asmRegisterMemory(
37833782 .{ ._, .lea },
37843783 registerAlias(dst_reg, dst_abi_size),
......@@ -3789,6 +3788,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
37893788}
37903789
37913790fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3791 const mod = self.bin_file.options.module.?;
37923792 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
37933793 const result: MCValue = result: {
37943794 const src_ty = self.air.typeOf(ty_op.operand);
......@@ -3803,8 +3803,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
38033803 const eu_ty = src_ty.childType();
38043804 const pl_ty = eu_ty.errorUnionPayload();
38053805 const err_ty = eu_ty.errorUnionSet();
3806 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));
3807 const err_abi_size = @intCast(u32, err_ty.abiSize(self.target.*));
3806 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
3807 const err_abi_size = @intCast(u32, err_ty.abiSize(mod));
38083808 try self.asmMemoryImmediate(
38093809 .{ ._, .mov },
38103810 Memory.sib(Memory.PtrSize.fromSize(err_abi_size), .{
......@@ -3824,8 +3824,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
38243824 const dst_lock = self.register_manager.lockReg(dst_reg);
38253825 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
38263826
3827 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*));
3828 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
3827 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));
3828 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
38293829 try self.asmRegisterMemory(
38303830 .{ ._, .lea },
38313831 registerAlias(dst_reg, dst_abi_size),
......@@ -3853,14 +3853,15 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
38533853}
38543854
38553855fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3856 const mod = self.bin_file.options.module.?;
38563857 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
38573858 const result: MCValue = result: {
38583859 const pl_ty = self.air.typeOf(ty_op.operand);
3859 if (!pl_ty.hasRuntimeBits()) break :result .{ .immediate = 1 };
3860 if (!pl_ty.hasRuntimeBits(mod)) break :result .{ .immediate = 1 };
38603861
38613862 const opt_ty = self.air.typeOfIndex(inst);
38623863 const pl_mcv = try self.resolveInst(ty_op.operand);
3863 const same_repr = opt_ty.optionalReprIsPayload();
3864 const same_repr = opt_ty.optionalReprIsPayload(mod);
38643865 if (same_repr and self.reuseOperand(inst, ty_op.operand, 0, pl_mcv)) break :result pl_mcv;
38653866
38663867 const pl_lock: ?RegisterLock = switch (pl_mcv) {
......@@ -3873,7 +3874,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
38733874 try self.genCopy(pl_ty, opt_mcv, pl_mcv);
38743875
38753876 if (!same_repr) {
3876 const pl_abi_size = @intCast(i32, pl_ty.abiSize(self.target.*));
3877 const pl_abi_size = @intCast(i32, pl_ty.abiSize(mod));
38773878 switch (opt_mcv) {
38783879 else => unreachable,
38793880
......@@ -3900,6 +3901,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
39003901
39013902/// T to E!T
39023903fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3904 const mod = self.bin_file.options.module.?;
39033905 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39043906
39053907 const eu_ty = self.air.getRefType(ty_op.ty);
......@@ -3908,11 +3910,11 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
39083910 const operand = try self.resolveInst(ty_op.operand);
39093911
39103912 const result: MCValue = result: {
3911 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) break :result .{ .immediate = 0 };
3913 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .{ .immediate = 0 };
39123914
3913 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, self.target.*));
3914 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*));
3915 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));
3915 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, mod));
3916 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));
3917 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
39163918 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, operand);
39173919 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, .{ .immediate = 0 });
39183920 break :result .{ .load_frame = .{ .index = frame_index } };
......@@ -3922,6 +3924,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
39223924
39233925/// E to E!T
39243926fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3927 const mod = self.bin_file.options.module.?;
39253928 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39263929
39273930 const eu_ty = self.air.getRefType(ty_op.ty);
......@@ -3929,11 +3932,11 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
39293932 const err_ty = eu_ty.errorUnionSet();
39303933
39313934 const result: MCValue = result: {
3932 if (!pl_ty.hasRuntimeBitsIgnoreComptime()) break :result try self.resolveInst(ty_op.operand);
3935 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result try self.resolveInst(ty_op.operand);
39333936
3934 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, self.target.*));
3935 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, self.target.*));
3936 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));
3937 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(eu_ty, mod));
3938 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));
3939 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
39373940 try self.genSetMem(.{ .frame = frame_index }, pl_off, pl_ty, .undef);
39383941 const operand = try self.resolveInst(ty_op.operand);
39393942 try self.genSetMem(.{ .frame = frame_index }, err_off, err_ty, operand);
......@@ -3974,6 +3977,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
39743977}
39753978
39763979fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
3980 const mod = self.bin_file.options.module.?;
39773981 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39783982
39793983 const src_ty = self.air.typeOf(ty_op.operand);
......@@ -3994,7 +3998,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
39943998 const dst_lock = self.register_manager.lockReg(dst_reg);
39953999 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
39964000
3997 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
4001 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
39984002 try self.asmRegisterMemory(
39994003 .{ ._, .lea },
40004004 registerAlias(dst_reg, dst_abi_size),
......@@ -4041,6 +4045,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi
40414045}
40424046
40434047fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
4048 const mod = self.bin_file.options.module.?;
40444049 const slice_ty = self.air.typeOf(lhs);
40454050 const slice_mcv = try self.resolveInst(lhs);
40464051 const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {
......@@ -4050,7 +4055,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
40504055 defer if (slice_mcv_lock) |lock| self.register_manager.unlockReg(lock);
40514056
40524057 const elem_ty = slice_ty.childType();
4053 const elem_size = elem_ty.abiSize(self.target.*);
4058 const elem_size = elem_ty.abiSize(mod);
40544059 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
40554060 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
40564061
......@@ -4097,6 +4102,7 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
40974102}
40984103
40994104fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
4105 const mod = self.bin_file.options.module.?;
41004106 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
41014107
41024108 const array_ty = self.air.typeOf(bin_op.lhs);
......@@ -4108,7 +4114,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
41084114 defer if (array_lock) |lock| self.register_manager.unlockReg(lock);
41094115
41104116 const elem_ty = array_ty.childType();
4111 const elem_abi_size = elem_ty.abiSize(self.target.*);
4117 const elem_abi_size = elem_ty.abiSize(mod);
41124118
41134119 const index_ty = self.air.typeOf(bin_op.rhs);
41144120 const index = try self.resolveInst(bin_op.rhs);
......@@ -4125,7 +4131,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
41254131 const addr_reg = try self.register_manager.allocReg(null, gp);
41264132 switch (array) {
41274133 .register => {
4128 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, self.target.*));
4134 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(array_ty, mod));
41294135 try self.genSetMem(.{ .frame = frame_index }, 0, array_ty, array);
41304136 try self.asmRegisterMemory(
41314137 .{ ._, .lea },
......@@ -4162,14 +4168,15 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
41624168}
41634169
41644170fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
4171 const mod = self.bin_file.options.module.?;
41654172 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
41664173 const ptr_ty = self.air.typeOf(bin_op.lhs);
41674174
41684175 // this is identical to the `airPtrElemPtr` codegen expect here an
41694176 // additional `mov` is needed at the end to get the actual value
41704177
4171 const elem_ty = ptr_ty.elemType2();
4172 const elem_abi_size = @intCast(u32, elem_ty.abiSize(self.target.*));
4178 const elem_ty = ptr_ty.elemType2(mod);
4179 const elem_abi_size = @intCast(u32, elem_ty.abiSize(mod));
41734180 const index_ty = self.air.typeOf(bin_op.rhs);
41744181 const index_mcv = try self.resolveInst(bin_op.rhs);
41754182 const index_lock = switch (index_mcv) {
......@@ -4207,6 +4214,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
42074214}
42084215
42094216fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
4217 const mod = self.bin_file.options.module.?;
42104218 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
42114219 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
42124220
......@@ -4218,8 +4226,8 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
42184226 };
42194227 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);
42204228
4221 const elem_ty = ptr_ty.elemType2();
4222 const elem_abi_size = elem_ty.abiSize(self.target.*);
4229 const elem_ty = ptr_ty.elemType2(mod);
4230 const elem_abi_size = elem_ty.abiSize(mod);
42234231 const index_ty = self.air.typeOf(extra.rhs);
42244232 const index = try self.resolveInst(extra.rhs);
42254233 const index_lock: ?RegisterLock = switch (index) {
......@@ -4239,11 +4247,12 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
42394247}
42404248
42414249fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4250 const mod = self.bin_file.options.module.?;
42424251 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
42434252 const ptr_union_ty = self.air.typeOf(bin_op.lhs);
42444253 const union_ty = ptr_union_ty.childType();
42454254 const tag_ty = self.air.typeOf(bin_op.rhs);
4246 const layout = union_ty.unionGetLayout(self.target.*);
4255 const layout = union_ty.unionGetLayout(mod);
42474256
42484257 if (layout.tag_size == 0) {
42494258 return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none });
......@@ -4284,11 +4293,12 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
42844293}
42854294
42864295fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
4296 const mod = self.bin_file.options.module.?;
42874297 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
42884298
42894299 const tag_ty = self.air.typeOfIndex(inst);
42904300 const union_ty = self.air.typeOf(ty_op.operand);
4291 const layout = union_ty.unionGetLayout(self.target.*);
4301 const layout = union_ty.unionGetLayout(mod);
42924302
42934303 if (layout.tag_size == 0) {
42944304 return self.finishAir(inst, .none, .{ ty_op.operand, .none, .none });
......@@ -4302,7 +4312,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
43024312 };
43034313 defer if (operand_lock) |lock| self.register_manager.unlockReg(lock);
43044314
4305 const tag_abi_size = tag_ty.abiSize(self.target.*);
4315 const tag_abi_size = tag_ty.abiSize(mod);
43064316 const dst_mcv: MCValue = blk: {
43074317 switch (operand) {
43084318 .load_frame => |frame_addr| {
......@@ -4337,6 +4347,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
43374347}
43384348
43394349fn airClz(self: *Self, inst: Air.Inst.Index) !void {
4350 const mod = self.bin_file.options.module.?;
43404351 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
43414352 const result = result: {
43424353 const dst_ty = self.air.typeOfIndex(inst);
......@@ -4358,7 +4369,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
43584369 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
43594370 defer self.register_manager.unlockReg(dst_lock);
43604371
4361 const src_bits = src_ty.bitSize(self.target.*);
4372 const src_bits = src_ty.bitSize(mod);
43624373 if (self.hasFeature(.lzcnt)) {
43634374 if (src_bits <= 8) {
43644375 const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv);
......@@ -4405,7 +4416,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
44054416 }
44064417
44074418 if (src_bits > 64)
4408 return self.fail("TODO airClz of {}", .{src_ty.fmt(self.bin_file.options.module.?)});
4419 return self.fail("TODO airClz of {}", .{src_ty.fmt(mod)});
44094420 if (math.isPowerOfTwo(src_bits)) {
44104421 const imm_reg = try self.copyToTmpRegister(dst_ty, .{
44114422 .immediate = src_bits ^ (src_bits - 1),
......@@ -4422,7 +4433,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
44224433 try self.genBinOpMir(.{ ._, .bsr }, Type.u16, dst_mcv, .{ .register = wide_reg });
44234434 } else try self.genBinOpMir(.{ ._, .bsr }, src_ty, dst_mcv, mat_src_mcv);
44244435
4425 const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(self.target.*)), 2);
4436 const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(mod)), 2);
44264437 try self.asmCmovccRegisterRegister(
44274438 registerAlias(dst_reg, cmov_abi_size),
44284439 registerAlias(imm_reg, cmov_abi_size),
......@@ -4449,7 +4460,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
44494460 .{ .register = wide_reg },
44504461 );
44514462
4452 const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(self.target.*)), 2);
4463 const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(mod)), 2);
44534464 try self.asmCmovccRegisterRegister(
44544465 registerAlias(imm_reg, cmov_abi_size),
44554466 registerAlias(dst_reg, cmov_abi_size),
......@@ -4465,11 +4476,12 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
44654476}
44664477
44674478fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
4479 const mod = self.bin_file.options.module.?;
44684480 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
44694481 const result = result: {
44704482 const dst_ty = self.air.typeOfIndex(inst);
44714483 const src_ty = self.air.typeOf(ty_op.operand);
4472 const src_bits = src_ty.bitSize(self.target.*);
4484 const src_bits = src_ty.bitSize(mod);
44734485
44744486 const src_mcv = try self.resolveInst(ty_op.operand);
44754487 const mat_src_mcv = switch (src_mcv) {
......@@ -4548,7 +4560,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
45484560 try self.genBinOpMir(.{ ._, .bsf }, Type.u16, dst_mcv, .{ .register = wide_reg });
45494561 } else try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv);
45504562
4551 const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(self.target.*)), 2);
4563 const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(mod)), 2);
45524564 try self.asmCmovccRegisterRegister(
45534565 registerAlias(dst_reg, cmov_abi_size),
45544566 registerAlias(width_reg, cmov_abi_size),
......@@ -4560,10 +4572,11 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
45604572}
45614573
45624574fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
4575 const mod = self.bin_file.options.module.?;
45634576 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
45644577 const result: MCValue = result: {
45654578 const src_ty = self.air.typeOf(ty_op.operand);
4566 const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*));
4579 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
45674580 const src_mcv = try self.resolveInst(ty_op.operand);
45684581
45694582 if (self.hasFeature(.popcnt)) {
......@@ -4729,6 +4742,7 @@ fn byteSwap(self: *Self, inst: Air.Inst.Index, src_ty: Type, src_mcv: MCValue, m
47294742}
47304743
47314744fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
4745 const mod = self.bin_file.options.module.?;
47324746 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
47334747
47344748 const src_ty = self.air.typeOf(ty_op.operand);
......@@ -4738,7 +4752,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
47384752 switch (self.regExtraBits(src_ty)) {
47394753 0 => {},
47404754 else => |extra| try self.genBinOpMir(
4741 if (src_ty.isSignedInt()) .{ ._r, .sa } else .{ ._r, .sh },
4755 if (src_ty.isSignedInt(mod)) .{ ._r, .sa } else .{ ._r, .sh },
47424756 src_ty,
47434757 dst_mcv,
47444758 .{ .immediate = extra },
......@@ -4749,10 +4763,11 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
47494763}
47504764
47514765fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
4766 const mod = self.bin_file.options.module.?;
47524767 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
47534768
47544769 const src_ty = self.air.typeOf(ty_op.operand);
4755 const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*));
4770 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
47564771 const src_mcv = try self.resolveInst(ty_op.operand);
47574772
47584773 const dst_mcv = try self.byteSwap(inst, src_ty, src_mcv, false);
......@@ -4847,7 +4862,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
48474862 switch (self.regExtraBits(src_ty)) {
48484863 0 => {},
48494864 else => |extra| try self.genBinOpMir(
4850 if (src_ty.isSignedInt()) .{ ._r, .sa } else .{ ._r, .sh },
4865 if (src_ty.isSignedInt(mod)) .{ ._r, .sa } else .{ ._r, .sh },
48514866 src_ty,
48524867 dst_mcv,
48534868 .{ .immediate = extra },
......@@ -4858,17 +4873,18 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
48584873}
48594874
48604875fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
4876 const mod = self.bin_file.options.module.?;
48614877 const tag = self.air.instructions.items(.tag)[inst];
48624878 const un_op = self.air.instructions.items(.data)[inst].un_op;
48634879 const ty = self.air.typeOf(un_op);
4864 const abi_size: u32 = switch (ty.abiSize(self.target.*)) {
4880 const abi_size: u32 = switch (ty.abiSize(mod)) {
48654881 1...16 => 16,
48664882 17...32 => 32,
48674883 else => return self.fail("TODO implement airFloatSign for {}", .{
48684884 ty.fmt(self.bin_file.options.module.?),
48694885 }),
48704886 };
4871 const scalar_bits = ty.scalarType().floatBits(self.target.*);
4887 const scalar_bits = ty.scalarType(mod).floatBits(self.target.*);
48724888
48734889 const src_mcv = try self.resolveInst(un_op);
48744890 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
......@@ -4905,21 +4921,17 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
49054921 var stack align(@alignOf(ExpectedContents)) =
49064922 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
49074923
4908 var int_pl = Type.Payload.Bits{
4909 .base = .{ .tag = .int_signed },
4910 .data = scalar_bits,
4911 };
49124924 var vec_pl = Type.Payload.Array{
49134925 .base = .{ .tag = .vector },
49144926 .data = .{
49154927 .len = @divExact(abi_size * 8, scalar_bits),
4916 .elem_type = Type.initPayload(&int_pl.base),
4928 .elem_type = try mod.intType(.signed, scalar_bits),
49174929 },
49184930 };
49194931 const vec_ty = Type.initPayload(&vec_pl.base);
49204932 const sign_val = switch (tag) {
4921 .neg => try vec_ty.minInt(stack.get(), self.target.*),
4922 .fabs => try vec_ty.maxInt(stack.get(), self.target.*),
4933 .neg => try vec_ty.minInt(stack.get(), mod),
4934 .fabs => try vec_ty.maxInt(stack.get(), mod),
49234935 else => unreachable,
49244936 };
49254937
......@@ -5008,17 +5020,18 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: u4) !void {
50085020}
50095021
50105022fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4) !void {
5023 const mod = self.bin_file.options.module.?;
50115024 if (!self.hasFeature(.sse4_1))
50125025 return self.fail("TODO implement genRound without sse4_1 feature", .{});
50135026
5014 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag()) {
5027 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) {
50155028 .Float => switch (ty.floatBits(self.target.*)) {
50165029 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },
50175030 64 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round },
50185031 16, 80, 128 => null,
50195032 else => unreachable,
50205033 },
5021 .Vector => switch (ty.childType().zigTypeTag()) {
5034 .Vector => switch (ty.childType().zigTypeTag(mod)) {
50225035 .Float => switch (ty.childType().floatBits(self.target.*)) {
50235036 32 => switch (ty.vectorLen()) {
50245037 1 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },
......@@ -5041,7 +5054,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4
50415054 })) |tag| tag else return self.fail("TODO implement genRound for {}", .{
50425055 ty.fmt(self.bin_file.options.module.?),
50435056 });
5044 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
5057 const abi_size = @intCast(u32, ty.abiSize(mod));
50455058 const dst_alias = registerAlias(dst_reg, abi_size);
50465059 switch (mir_tag[0]) {
50475060 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate(
......@@ -5078,9 +5091,10 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4
50785091}
50795092
50805093fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
5094 const mod = self.bin_file.options.module.?;
50815095 const un_op = self.air.instructions.items(.data)[inst].un_op;
50825096 const ty = self.air.typeOf(un_op);
5083 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
5097 const abi_size = @intCast(u32, ty.abiSize(mod));
50845098
50855099 const src_mcv = try self.resolveInst(un_op);
50865100 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv))
......@@ -5092,7 +5106,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
50925106 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
50935107
50945108 const result: MCValue = result: {
5095 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag()) {
5109 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) {
50965110 .Float => switch (ty.floatBits(self.target.*)) {
50975111 16 => if (self.hasFeature(.f16c)) {
50985112 const mat_src_reg = if (src_mcv.isRegister())
......@@ -5114,7 +5128,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
51145128 80, 128 => null,
51155129 else => unreachable,
51165130 },
5117 .Vector => switch (ty.childType().zigTypeTag()) {
5131 .Vector => switch (ty.childType().zigTypeTag(mod)) {
51185132 .Float => switch (ty.childType().floatBits(self.target.*)) {
51195133 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen()) {
51205134 1 => {
......@@ -5186,7 +5200,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
51865200 },
51875201 else => unreachable,
51885202 })) |tag| tag else return self.fail("TODO implement airSqrt for {}", .{
5189 ty.fmt(self.bin_file.options.module.?),
5203 ty.fmt(mod),
51905204 });
51915205 switch (mir_tag[0]) {
51925206 .v_ss, .v_sd => if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory(
......@@ -5274,10 +5288,11 @@ fn reuseOperandAdvanced(
52745288}
52755289
52765290fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void {
5291 const mod = self.bin_file.options.module.?;
52775292 const ptr_info = ptr_ty.ptrInfo().data;
52785293
52795294 const val_ty = ptr_info.pointee_type;
5280 const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*));
5295 const val_abi_size = @intCast(u32, val_ty.abiSize(mod));
52815296 const limb_abi_size: u32 = @min(val_abi_size, 8);
52825297 const limb_abi_bits = limb_abi_size * 8;
52835298 const val_byte_off = @intCast(i32, ptr_info.bit_offset / limb_abi_bits * limb_abi_size);
......@@ -5382,20 +5397,21 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
53825397}
53835398
53845399fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
5400 const mod = self.bin_file.options.module.?;
53855401 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
53865402 const elem_ty = self.air.typeOfIndex(inst);
53875403 const result: MCValue = result: {
5388 if (!elem_ty.hasRuntimeBitsIgnoreComptime()) break :result .none;
5404 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
53895405
53905406 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });
53915407 const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });
53925408 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
53935409
53945410 const ptr_ty = self.air.typeOf(ty_op.operand);
5395 const elem_size = elem_ty.abiSize(self.target.*);
5411 const elem_size = elem_ty.abiSize(mod);
53965412
5397 const elem_rc = regClassForType(elem_ty);
5398 const ptr_rc = regClassForType(ptr_ty);
5413 const elem_rc = regClassForType(elem_ty, mod);
5414 const ptr_rc = regClassForType(ptr_ty, mod);
53995415
54005416 const ptr_mcv = try self.resolveInst(ty_op.operand);
54015417 const dst_mcv = if (elem_size <= 8 and elem_rc.supersetOf(ptr_rc) and
......@@ -5416,13 +5432,14 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
54165432}
54175433
54185434fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void {
5435 const mod = self.bin_file.options.module.?;
54195436 const ptr_info = ptr_ty.ptrInfo().data;
54205437 const src_ty = ptr_ty.childType();
54215438
54225439 const limb_abi_size: u16 = @min(ptr_info.host_size, 8);
54235440 const limb_abi_bits = limb_abi_size * 8;
54245441
5425 const src_bit_size = src_ty.bitSize(self.target.*);
5442 const src_bit_size = src_ty.bitSize(mod);
54265443 const src_byte_off = @intCast(i32, ptr_info.bit_offset / limb_abi_bits * limb_abi_size);
54275444 const src_bit_off = ptr_info.bit_offset % limb_abi_bits;
54285445
......@@ -5555,14 +5572,15 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
55555572}
55565573
55575574fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
5575 const mod = self.bin_file.options.module.?;
55585576 const ptr_field_ty = self.air.typeOfIndex(inst);
55595577 const ptr_container_ty = self.air.typeOf(operand);
55605578 const container_ty = ptr_container_ty.childType();
55615579 const field_offset = @intCast(i32, switch (container_ty.containerLayout()) {
5562 .Auto, .Extern => container_ty.structFieldOffset(index, self.target.*),
5563 .Packed => if (container_ty.zigTypeTag() == .Struct and
5580 .Auto, .Extern => container_ty.structFieldOffset(index, mod),
5581 .Packed => if (container_ty.zigTypeTag(mod) == .Struct and
55645582 ptr_field_ty.ptrInfo().data.host_size == 0)
5565 container_ty.packedStructFieldByteOffset(index, self.target.*)
5583 container_ty.packedStructFieldByteOffset(index, mod)
55665584 else
55675585 0,
55685586 });
......@@ -5577,6 +5595,7 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32
55775595}
55785596
55795597fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
5598 const mod = self.bin_file.options.module.?;
55805599 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
55815600 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
55825601 const result: MCValue = result: {
......@@ -5584,17 +5603,17 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
55845603 const index = extra.field_index;
55855604
55865605 const container_ty = self.air.typeOf(operand);
5587 const container_rc = regClassForType(container_ty);
5606 const container_rc = regClassForType(container_ty, mod);
55885607 const field_ty = container_ty.structFieldType(index);
5589 if (!field_ty.hasRuntimeBitsIgnoreComptime()) break :result .none;
5590 const field_rc = regClassForType(field_ty);
5608 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
5609 const field_rc = regClassForType(field_ty, mod);
55915610 const field_is_gp = field_rc.supersetOf(gp);
55925611
55935612 const src_mcv = try self.resolveInst(operand);
55945613 const field_off = switch (container_ty.containerLayout()) {
5595 .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, self.target.*) * 8),
5614 .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, mod) * 8),
55965615 .Packed => if (container_ty.castTag(.@"struct")) |struct_obj|
5597 struct_obj.data.packedFieldBitOffset(self.target.*, index)
5616 struct_obj.data.packedFieldBitOffset(mod, index)
55985617 else
55995618 0,
56005619 };
......@@ -5611,7 +5630,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
56115630 break :result dst_mcv;
56125631 }
56135632
5614 const field_abi_size = @intCast(u32, field_ty.abiSize(self.target.*));
5633 const field_abi_size = @intCast(u32, field_ty.abiSize(mod));
56155634 const limb_abi_size: u32 = @min(field_abi_size, 8);
56165635 const limb_abi_bits = limb_abi_size * 8;
56175636 const field_byte_off = @intCast(i32, field_off / limb_abi_bits * limb_abi_size);
......@@ -5733,12 +5752,13 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
57335752}
57345753
57355754fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
5755 const mod = self.bin_file.options.module.?;
57365756 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
57375757 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
57385758
57395759 const inst_ty = self.air.typeOfIndex(inst);
57405760 const parent_ty = inst_ty.childType();
5741 const field_offset = @intCast(i32, parent_ty.structFieldOffset(extra.field_index, self.target.*));
5761 const field_offset = @intCast(i32, parent_ty.structFieldOffset(extra.field_index, mod));
57425762
57435763 const src_mcv = try self.resolveInst(extra.field_ptr);
57445764 const dst_mcv = if (src_mcv.isRegisterOffset() and
......@@ -5751,9 +5771,10 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
57515771}
57525772
57535773fn 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.?;
57545775 const src_ty = self.air.typeOf(src_air);
57555776 const src_mcv = try self.resolveInst(src_air);
5756 if (src_ty.zigTypeTag() == .Vector) {
5777 if (src_ty.zigTypeTag(mod) == .Vector) {
57575778 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)});
57585779 }
57595780
......@@ -5786,28 +5807,22 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
57865807
57875808 switch (tag) {
57885809 .not => {
5789 const limb_abi_size = @intCast(u16, @min(src_ty.abiSize(self.target.*), 8));
5810 const limb_abi_size = @intCast(u16, @min(src_ty.abiSize(mod), 8));
57905811 const int_info = if (src_ty.tag() == .bool)
57915812 std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 }
57925813 else
5793 src_ty.intInfo(self.target.*);
5814 src_ty.intInfo(mod);
57945815 var byte_off: i32 = 0;
57955816 while (byte_off * 8 < int_info.bits) : (byte_off += limb_abi_size) {
5796 var limb_pl = Type.Payload.Bits{
5797 .base = .{ .tag = switch (int_info.signedness) {
5798 .signed => .int_signed,
5799 .unsigned => .int_unsigned,
5800 } },
5801 .data = @intCast(u16, @min(int_info.bits - byte_off * 8, limb_abi_size * 8)),
5802 };
5803 const limb_ty = Type.initPayload(&limb_pl.base);
5817 const limb_bits = @intCast(u16, @min(int_info.bits - byte_off * 8, limb_abi_size * 8));
5818 const limb_ty = try mod.intType(int_info.signedness, limb_bits);
58045819 const limb_mcv = switch (byte_off) {
58055820 0 => dst_mcv,
58065821 else => dst_mcv.address().offset(byte_off).deref(),
58075822 };
58085823
5809 if (limb_pl.base.tag == .int_unsigned and self.regExtraBits(limb_ty) > 0) {
5810 const mask = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - limb_pl.data);
5824 if (int_info.signedness == .unsigned and self.regExtraBits(limb_ty) > 0) {
5825 const mask = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - limb_bits);
58115826 try self.genBinOpMir(.{ ._, .xor }, limb_ty, limb_mcv, .{ .immediate = mask });
58125827 } else try self.genUnOpMir(.{ ._, .not }, limb_ty, limb_mcv);
58135828 }
......@@ -5819,7 +5834,8 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
58195834}
58205835
58215836fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void {
5822 const abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
5837 const mod = self.bin_file.options.module.?;
5838 const abi_size = @intCast(u32, dst_ty.abiSize(mod));
58235839 if (abi_size > 8) return self.fail("TODO implement {} for {}", .{
58245840 mir_tag,
58255841 dst_ty.fmt(self.bin_file.options.module.?),
......@@ -5866,6 +5882,7 @@ fn genShiftBinOpMir(
58665882 lhs_mcv: MCValue,
58675883 shift_mcv: MCValue,
58685884) !void {
5885 const mod = self.bin_file.options.module.?;
58695886 const rhs_mcv: MCValue = rhs: {
58705887 switch (shift_mcv) {
58715888 .immediate => |imm| switch (imm) {
......@@ -5880,7 +5897,7 @@ fn genShiftBinOpMir(
58805897 break :rhs .{ .register = .rcx };
58815898 };
58825899
5883 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
5900 const abi_size = @intCast(u32, ty.abiSize(mod));
58845901 if (abi_size <= 8) {
58855902 switch (lhs_mcv) {
58865903 .register => |lhs_reg| switch (rhs_mcv) {
......@@ -6099,13 +6116,14 @@ fn genShiftBinOp(
60996116 lhs_ty: Type,
61006117 rhs_ty: Type,
61016118) !MCValue {
6102 if (lhs_ty.zigTypeTag() == .Vector) {
6119 const mod = self.bin_file.options.module.?;
6120 if (lhs_ty.zigTypeTag(mod) == .Vector) {
61036121 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});
61046122 }
61056123
6106 assert(rhs_ty.abiSize(self.target.*) == 1);
6124 assert(rhs_ty.abiSize(mod) == 1);
61076125
6108 const lhs_abi_size = lhs_ty.abiSize(self.target.*);
6126 const lhs_abi_size = lhs_ty.abiSize(mod);
61096127 if (lhs_abi_size > 16) {
61106128 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});
61116129 }
......@@ -6136,7 +6154,7 @@ fn genShiftBinOp(
61366154 break :dst dst_mcv;
61376155 };
61386156
6139 const signedness = lhs_ty.intInfo(self.target.*).signedness;
6157 const signedness = lhs_ty.intInfo(mod).signedness;
61406158 try self.genShiftBinOpMir(switch (air_tag) {
61416159 .shl, .shl_exact => switch (signedness) {
61426160 .signed => .{ ._l, .sa },
......@@ -6163,11 +6181,12 @@ fn genMulDivBinOp(
61636181 lhs: MCValue,
61646182 rhs: MCValue,
61656183) !MCValue {
6166 if (dst_ty.zigTypeTag() == .Vector or dst_ty.zigTypeTag() == .Float) {
6184 const mod = self.bin_file.options.module.?;
6185 if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) {
61676186 return self.fail("TODO implement genMulDivBinOp for {}", .{dst_ty.fmtDebug()});
61686187 }
6169 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
6170 const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*));
6188 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
6189 const src_abi_size = @intCast(u32, src_ty.abiSize(mod));
61716190 if (switch (tag) {
61726191 else => unreachable,
61736192 .mul, .mulwrap => dst_abi_size != src_abi_size and dst_abi_size != src_abi_size * 2,
......@@ -6184,7 +6203,7 @@ fn genMulDivBinOp(
61846203 const reg_locks = self.register_manager.lockRegs(2, .{ .rax, .rdx });
61856204 defer for (reg_locks) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock);
61866205
6187 const signedness = ty.intInfo(self.target.*).signedness;
6206 const signedness = ty.intInfo(mod).signedness;
61886207 switch (tag) {
61896208 .mul,
61906209 .mulwrap,
......@@ -6338,13 +6357,14 @@ fn genBinOp(
63386357 lhs_air: Air.Inst.Ref,
63396358 rhs_air: Air.Inst.Ref,
63406359) !MCValue {
6360 const mod = self.bin_file.options.module.?;
63416361 const lhs_ty = self.air.typeOf(lhs_air);
63426362 const rhs_ty = self.air.typeOf(rhs_air);
6343 const abi_size = @intCast(u32, lhs_ty.abiSize(self.target.*));
6363 const abi_size = @intCast(u32, lhs_ty.abiSize(mod));
63446364
63456365 const maybe_mask_reg = switch (air_tag) {
63466366 else => null,
6347 .max, .min => if (lhs_ty.scalarType().isRuntimeFloat()) registerAlias(
6367 .max, .min => if (lhs_ty.scalarType(mod).isRuntimeFloat()) registerAlias(
63486368 if (!self.hasFeature(.avx) and self.hasFeature(.sse4_1)) mask: {
63496369 try self.register_manager.getReg(.xmm0, null);
63506370 break :mask .xmm0;
......@@ -6384,7 +6404,7 @@ fn genBinOp(
63846404
63856405 else => false,
63866406 };
6387 const vec_op = switch (lhs_ty.zigTypeTag()) {
6407 const vec_op = switch (lhs_ty.zigTypeTag(mod)) {
63886408 else => false,
63896409 .Float, .Vector => true,
63906410 };
......@@ -6456,7 +6476,7 @@ fn genBinOp(
64566476 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
64576477 defer self.register_manager.unlockReg(tmp_lock);
64586478
6459 const elem_size = lhs_ty.elemType2().abiSize(self.target.*);
6479 const elem_size = lhs_ty.elemType2(mod).abiSize(mod);
64606480 try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size });
64616481 try self.genBinOpMir(
64626482 switch (air_tag) {
......@@ -6506,7 +6526,7 @@ fn genBinOp(
65066526
65076527 try self.genBinOpMir(.{ ._, .cmp }, lhs_ty, dst_mcv, mat_src_mcv);
65086528
6509 const int_info = lhs_ty.intInfo(self.target.*);
6529 const int_info = lhs_ty.intInfo(mod);
65106530 const cc: Condition = switch (int_info.signedness) {
65116531 .unsigned => switch (air_tag) {
65126532 .min => .a,
......@@ -6520,7 +6540,7 @@ fn genBinOp(
65206540 },
65216541 };
65226542
6523 const cmov_abi_size = @max(@intCast(u32, lhs_ty.abiSize(self.target.*)), 2);
6543 const cmov_abi_size = @max(@intCast(u32, lhs_ty.abiSize(mod)), 2);
65246544 const tmp_reg = switch (dst_mcv) {
65256545 .register => |reg| reg,
65266546 else => try self.copyToTmpRegister(lhs_ty, dst_mcv),
......@@ -6581,7 +6601,7 @@ fn genBinOp(
65816601 }
65826602
65836603 const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size);
6584 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {
6604 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
65856605 else => unreachable,
65866606 .Float => switch (lhs_ty.floatBits(self.target.*)) {
65876607 16 => if (self.hasFeature(.f16c)) {
......@@ -6657,9 +6677,9 @@ fn genBinOp(
66576677 80, 128 => null,
66586678 else => unreachable,
66596679 },
6660 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
6680 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
66616681 else => null,
6662 .Int => switch (lhs_ty.childType().intInfo(self.target.*).bits) {
6682 .Int => switch (lhs_ty.childType().intInfo(mod).bits) {
66636683 8 => switch (lhs_ty.vectorLen()) {
66646684 1...16 => switch (air_tag) {
66656685 .add,
......@@ -6671,7 +6691,7 @@ fn genBinOp(
66716691 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },
66726692 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
66736693 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },
6674 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6694 .min => switch (lhs_ty.childType().intInfo(mod).signedness) {
66756695 .signed => if (self.hasFeature(.avx))
66766696 .{ .vp_b, .mins }
66776697 else if (self.hasFeature(.sse4_1))
......@@ -6685,7 +6705,7 @@ fn genBinOp(
66856705 else
66866706 null,
66876707 },
6688 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6708 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
66896709 .signed => if (self.hasFeature(.avx))
66906710 .{ .vp_b, .maxs }
66916711 else if (self.hasFeature(.sse4_1))
......@@ -6711,11 +6731,11 @@ fn genBinOp(
67116731 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
67126732 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
67136733 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,
6714 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6734 .min => switch (lhs_ty.childType().intInfo(mod).signedness) {
67156735 .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .mins } else null,
67166736 .unsigned => if (self.hasFeature(.avx)) .{ .vp_b, .minu } else null,
67176737 },
6718 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6738 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
67196739 .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .maxs } else null,
67206740 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_b, .maxu } else null,
67216741 },
......@@ -6737,7 +6757,7 @@ fn genBinOp(
67376757 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },
67386758 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
67396759 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },
6740 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6760 .min => switch (lhs_ty.childType().intInfo(mod).signedness) {
67416761 .signed => if (self.hasFeature(.avx))
67426762 .{ .vp_w, .mins }
67436763 else
......@@ -6747,7 +6767,7 @@ fn genBinOp(
67476767 else
67486768 .{ .p_w, .minu },
67496769 },
6750 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6770 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
67516771 .signed => if (self.hasFeature(.avx))
67526772 .{ .vp_w, .maxs }
67536773 else
......@@ -6772,11 +6792,11 @@ fn genBinOp(
67726792 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
67736793 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
67746794 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,
6775 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6795 .min => switch (lhs_ty.childType().intInfo(mod).signedness) {
67766796 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .mins } else null,
67776797 .unsigned => if (self.hasFeature(.avx)) .{ .vp_w, .minu } else null,
67786798 },
6779 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6799 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
67806800 .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .maxs } else null,
67816801 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_w, .maxu } else null,
67826802 },
......@@ -6803,7 +6823,7 @@ fn genBinOp(
68036823 .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" },
68046824 .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" },
68056825 .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor },
6806 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6826 .min => switch (lhs_ty.childType().intInfo(mod).signedness) {
68076827 .signed => if (self.hasFeature(.avx))
68086828 .{ .vp_d, .mins }
68096829 else if (self.hasFeature(.sse4_1))
......@@ -6817,7 +6837,7 @@ fn genBinOp(
68176837 else
68186838 null,
68196839 },
6820 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6840 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
68216841 .signed => if (self.hasFeature(.avx))
68226842 .{ .vp_d, .maxs }
68236843 else if (self.hasFeature(.sse4_1))
......@@ -6846,11 +6866,11 @@ fn genBinOp(
68466866 .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null,
68476867 .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null,
68486868 .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null,
6849 .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6869 .min => switch (lhs_ty.childType().intInfo(mod).signedness) {
68506870 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .mins } else null,
68516871 .unsigned => if (self.hasFeature(.avx)) .{ .vp_d, .minu } else null,
68526872 },
6853 .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) {
6873 .max => switch (lhs_ty.childType().intInfo(mod).signedness) {
68546874 .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .maxs } else null,
68556875 .unsigned => if (self.hasFeature(.avx2)) .{ .vp_d, .maxu } else null,
68566876 },
......@@ -7206,14 +7226,14 @@ fn genBinOp(
72067226 const rhs_copy_reg = registerAlias(src_mcv.getReg().?, abi_size);
72077227
72087228 try self.asmRegisterRegisterRegisterImmediate(
7209 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {
7229 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
72107230 .Float => switch (lhs_ty.floatBits(self.target.*)) {
72117231 32 => .{ .v_ss, .cmp },
72127232 64 => .{ .v_sd, .cmp },
72137233 16, 80, 128 => null,
72147234 else => unreachable,
72157235 },
7216 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
7236 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
72177237 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
72187238 32 => switch (lhs_ty.vectorLen()) {
72197239 1 => .{ .v_ss, .cmp },
......@@ -7240,14 +7260,14 @@ fn genBinOp(
72407260 Immediate.u(3), // unord
72417261 );
72427262 try self.asmRegisterRegisterRegisterRegister(
7243 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {
7263 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
72447264 .Float => switch (lhs_ty.floatBits(self.target.*)) {
72457265 32 => .{ .v_ps, .blendv },
72467266 64 => .{ .v_pd, .blendv },
72477267 16, 80, 128 => null,
72487268 else => unreachable,
72497269 },
7250 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
7270 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
72517271 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
72527272 32 => switch (lhs_ty.vectorLen()) {
72537273 1...8 => .{ .v_ps, .blendv },
......@@ -7274,14 +7294,14 @@ fn genBinOp(
72747294 } else {
72757295 const has_blend = self.hasFeature(.sse4_1);
72767296 try self.asmRegisterRegisterImmediate(
7277 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {
7297 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
72787298 .Float => switch (lhs_ty.floatBits(self.target.*)) {
72797299 32 => .{ ._ss, .cmp },
72807300 64 => .{ ._sd, .cmp },
72817301 16, 80, 128 => null,
72827302 else => unreachable,
72837303 },
7284 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
7304 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
72857305 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
72867306 32 => switch (lhs_ty.vectorLen()) {
72877307 1 => .{ ._ss, .cmp },
......@@ -7307,14 +7327,14 @@ fn genBinOp(
73077327 Immediate.u(if (has_blend) 3 else 7), // unord, ord
73087328 );
73097329 if (has_blend) try self.asmRegisterRegisterRegister(
7310 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {
7330 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
73117331 .Float => switch (lhs_ty.floatBits(self.target.*)) {
73127332 32 => .{ ._ps, .blendv },
73137333 64 => .{ ._pd, .blendv },
73147334 16, 80, 128 => null,
73157335 else => unreachable,
73167336 },
7317 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
7337 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
73187338 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
73197339 32 => switch (lhs_ty.vectorLen()) {
73207340 1...4 => .{ ._ps, .blendv },
......@@ -7338,14 +7358,14 @@ fn genBinOp(
73387358 mask_reg,
73397359 ) else {
73407360 try self.asmRegisterRegister(
7341 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {
7361 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
73427362 .Float => switch (lhs_ty.floatBits(self.target.*)) {
73437363 32 => .{ ._ps, .@"and" },
73447364 64 => .{ ._pd, .@"and" },
73457365 16, 80, 128 => null,
73467366 else => unreachable,
73477367 },
7348 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
7368 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
73497369 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
73507370 32 => switch (lhs_ty.vectorLen()) {
73517371 1...4 => .{ ._ps, .@"and" },
......@@ -7368,14 +7388,14 @@ fn genBinOp(
73687388 mask_reg,
73697389 );
73707390 try self.asmRegisterRegister(
7371 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {
7391 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
73727392 .Float => switch (lhs_ty.floatBits(self.target.*)) {
73737393 32 => .{ ._ps, .andn },
73747394 64 => .{ ._pd, .andn },
73757395 16, 80, 128 => null,
73767396 else => unreachable,
73777397 },
7378 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
7398 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
73797399 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
73807400 32 => switch (lhs_ty.vectorLen()) {
73817401 1...4 => .{ ._ps, .andn },
......@@ -7398,14 +7418,14 @@ fn genBinOp(
73987418 lhs_copy_reg.?,
73997419 );
74007420 try self.asmRegisterRegister(
7401 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag()) {
7421 if (@as(?Mir.Inst.FixedTag, switch (lhs_ty.zigTypeTag(mod)) {
74027422 .Float => switch (lhs_ty.floatBits(self.target.*)) {
74037423 32 => .{ ._ps, .@"or" },
74047424 64 => .{ ._pd, .@"or" },
74057425 16, 80, 128 => null,
74067426 else => unreachable,
74077427 },
7408 .Vector => switch (lhs_ty.childType().zigTypeTag()) {
7428 .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) {
74097429 .Float => switch (lhs_ty.childType().floatBits(self.target.*)) {
74107430 32 => switch (lhs_ty.vectorLen()) {
74117431 1...4 => .{ ._ps, .@"or" },
......@@ -7442,7 +7462,8 @@ fn genBinOpMir(
74427462 dst_mcv: MCValue,
74437463 src_mcv: MCValue,
74447464) !void {
7445 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
7465 const mod = self.bin_file.options.module.?;
7466 const abi_size = @intCast(u32, ty.abiSize(mod));
74467467 switch (dst_mcv) {
74477468 .none,
74487469 .unreach,
......@@ -7640,7 +7661,7 @@ fn genBinOpMir(
76407661 defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock);
76417662
76427663 const ty_signedness =
7643 if (ty.isAbiInt()) ty.intInfo(self.target.*).signedness else .unsigned;
7664 if (ty.isAbiInt(mod)) ty.intInfo(mod).signedness else .unsigned;
76447665 const limb_ty = if (abi_size <= 8) ty else switch (ty_signedness) {
76457666 .signed => Type.usize,
76467667 .unsigned => Type.isize,
......@@ -7796,7 +7817,8 @@ fn genBinOpMir(
77967817/// Performs multi-operand integer multiplication between dst_mcv and src_mcv, storing the result in dst_mcv.
77977818/// Does not support byte-size operands.
77987819fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {
7799 const abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
7820 const mod = self.bin_file.options.module.?;
7821 const abi_size = @intCast(u32, dst_ty.abiSize(mod));
78007822 switch (dst_mcv) {
78017823 .none,
78027824 .unreach,
......@@ -8022,6 +8044,7 @@ fn airFence(self: *Self, inst: Air.Inst.Index) !void {
80228044}
80238045
80248046fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
8047 const mod = self.bin_file.options.module.?;
80258048 if (modifier == .always_tail) return self.fail("TODO implement tail calls for x86_64", .{});
80268049 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
80278050 const callee = pl_op.operand;
......@@ -8029,7 +8052,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
80298052 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
80308053 const ty = self.air.typeOf(callee);
80318054
8032 const fn_ty = switch (ty.zigTypeTag()) {
8055 const fn_ty = switch (ty.zigTypeTag(mod)) {
80338056 .Fn => ty,
80348057 .Pointer => ty.childType(),
80358058 else => unreachable,
......@@ -8077,7 +8100,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
80778100 .none, .unreach => null,
80788101 .indirect => |reg_off| lock: {
80798102 const ret_ty = fn_ty.fnReturnType();
8080 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(ret_ty, self.target.*));
8103 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(ret_ty, mod));
80818104 try self.genSetReg(reg_off.reg, Type.usize, .{
80828105 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
80838106 });
......@@ -8100,8 +8123,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
81008123
81018124 // Due to incremental compilation, how function calls are generated depends
81028125 // on linking.
8103 const mod = self.bin_file.options.module.?;
8104 if (self.air.value(callee)) |func_value| {
8126 if (self.air.value(callee, mod)) |func_value| {
81058127 if (if (func_value.castTag(.function)) |func_payload|
81068128 func_payload.data.owner_decl
81078129 else if (func_value.castTag(.decl_ref)) |decl_ref_payload|
......@@ -8178,7 +8200,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
81788200 return self.fail("TODO implement calling bitcasted functions", .{});
81798201 }
81808202 } else {
8181 assert(ty.zigTypeTag() == .Pointer);
8203 assert(ty.zigTypeTag(mod) == .Pointer);
81828204 const mcv = try self.resolveInst(callee);
81838205 try self.genSetReg(.rax, Type.usize, mcv);
81848206 try self.asmRegister(.{ ._, .call }, .rax);
......@@ -8234,6 +8256,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
82348256}
82358257
82368258fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
8259 const mod = self.bin_file.options.module.?;
82378260 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
82388261 const ty = self.air.typeOf(bin_op.lhs);
82398262
......@@ -8255,9 +8278,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
82558278 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
82568279
82578280 const result = MCValue{
8258 .eflags = switch (ty.zigTypeTag()) {
8281 .eflags = switch (ty.zigTypeTag(mod)) {
82598282 else => result: {
8260 const abi_size = @intCast(u16, ty.abiSize(self.target.*));
8283 const abi_size = @intCast(u16, ty.abiSize(mod));
82618284 const may_flip: enum {
82628285 may_flip,
82638286 must_flip,
......@@ -8290,7 +8313,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
82908313 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
82918314
82928315 break :result Condition.fromCompareOperator(
8293 if (ty.isAbiInt()) ty.intInfo(self.target.*).signedness else .unsigned,
8316 if (ty.isAbiInt(mod)) ty.intInfo(mod).signedness else .unsigned,
82948317 result_op: {
82958318 const flipped_op = if (flipped) op.reverse() else op;
82968319 if (abi_size > 8) switch (flipped_op) {
......@@ -8404,7 +8427,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
84048427 try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp2_reg, tmp1_reg);
84058428 try self.genBinOpMir(.{ ._ss, .ucomi }, ty, tmp1_mcv, tmp2_mcv);
84068429 } else return self.fail("TODO implement airCmp for {}", .{
8407 ty.fmt(self.bin_file.options.module.?),
8430 ty.fmt(mod),
84088431 }),
84098432 32 => try self.genBinOpMir(
84108433 .{ ._ss, .ucomi },
......@@ -8419,7 +8442,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
84198442 src_mcv,
84208443 ),
84218444 else => return self.fail("TODO implement airCmp for {}", .{
8422 ty.fmt(self.bin_file.options.module.?),
8445 ty.fmt(mod),
84238446 }),
84248447 }
84258448
......@@ -8454,7 +8477,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
84548477 self.eflags_inst = inst;
84558478
84568479 const op_ty = self.air.typeOf(un_op);
8457 const op_abi_size = @intCast(u32, op_ty.abiSize(self.target.*));
8480 const op_abi_size = @intCast(u32, op_ty.abiSize(mod));
84588481 const op_mcv = try self.resolveInst(un_op);
84598482 const dst_reg = switch (op_mcv) {
84608483 .register => |reg| reg,
......@@ -8573,7 +8596,8 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
85738596}
85748597
85758598fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 {
8576 const abi_size = ty.abiSize(self.target.*);
8599 const mod = self.bin_file.options.module.?;
8600 const abi_size = ty.abiSize(mod);
85778601 switch (mcv) {
85788602 .eflags => |cc| {
85798603 // Here we map the opposites since the jump is to the false branch.
......@@ -8646,6 +8670,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
86468670}
86478671
86488672fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue {
8673 const mod = self.bin_file.options.module.?;
86498674 switch (opt_mcv) {
86508675 .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() },
86518676 else => {},
......@@ -8658,10 +8683,10 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
86588683 const pl_ty = opt_ty.optionalChild(&pl_buf);
86598684
86608685 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
8661 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload())
8686 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
86628687 .{ .off = 0, .ty = if (pl_ty.isSlice()) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
86638688 else
8664 .{ .off = @intCast(i32, pl_ty.abiSize(self.target.*)), .ty = Type.bool };
8689 .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
86658690
86668691 switch (opt_mcv) {
86678692 .none,
......@@ -8681,14 +8706,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
86818706
86828707 .register => |opt_reg| {
86838708 if (some_info.off == 0) {
8684 const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*));
8709 const some_abi_size = @intCast(u32, some_info.ty.abiSize(mod));
86858710 const alias_reg = registerAlias(opt_reg, some_abi_size);
86868711 assert(some_abi_size * 8 == alias_reg.bitSize());
86878712 try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg);
86888713 return .{ .eflags = .z };
86898714 }
86908715 assert(some_info.ty.tag() == .bool);
8691 const opt_abi_size = @intCast(u32, opt_ty.abiSize(self.target.*));
8716 const opt_abi_size = @intCast(u32, opt_ty.abiSize(mod));
86928717 try self.asmRegisterImmediate(
86938718 .{ ._, .bt },
86948719 registerAlias(opt_reg, opt_abi_size),
......@@ -8707,7 +8732,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
87078732 defer self.register_manager.unlockReg(addr_reg_lock);
87088733
87098734 try self.genSetReg(addr_reg, Type.usize, opt_mcv.address());
8710 const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*));
8735 const some_abi_size = @intCast(u32, some_info.ty.abiSize(mod));
87118736 try self.asmMemoryImmediate(
87128737 .{ ._, .cmp },
87138738 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), .{
......@@ -8720,7 +8745,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
87208745 },
87218746
87228747 .indirect, .load_frame => {
8723 const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*));
8748 const some_abi_size = @intCast(u32, some_info.ty.abiSize(mod));
87248749 try self.asmMemoryImmediate(
87258750 .{ ._, .cmp },
87268751 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), switch (opt_mcv) {
......@@ -8742,6 +8767,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
87428767}
87438768
87448769fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue {
8770 const mod = self.bin_file.options.module.?;
87458771 try self.spillEflagsIfOccupied();
87468772 self.eflags_inst = inst;
87478773
......@@ -8750,10 +8776,10 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
87508776 const pl_ty = opt_ty.optionalChild(&pl_buf);
87518777
87528778 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
8753 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload())
8779 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
87548780 .{ .off = 0, .ty = if (pl_ty.isSlice()) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
87558781 else
8756 .{ .off = @intCast(i32, pl_ty.abiSize(self.target.*)), .ty = Type.bool };
8782 .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
87578783
87588784 const ptr_reg = switch (ptr_mcv) {
87598785 .register => |reg| reg,
......@@ -8762,7 +8788,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
87628788 const ptr_lock = self.register_manager.lockReg(ptr_reg);
87638789 defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock);
87648790
8765 const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*));
8791 const some_abi_size = @intCast(u32, some_info.ty.abiSize(mod));
87668792 try self.asmMemoryImmediate(
87678793 .{ ._, .cmp },
87688794 Memory.sib(Memory.PtrSize.fromSize(some_abi_size), .{
......@@ -8775,6 +8801,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
87758801}
87768802
87778803fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {
8804 const mod = self.bin_file.options.module.?;
87788805 const err_type = ty.errorUnionSet();
87798806
87808807 if (err_type.errorSetIsEmpty()) {
......@@ -8786,7 +8813,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !
87868813 self.eflags_inst = inst;
87878814 }
87888815
8789 const err_off = errUnionErrorOffset(ty.errorUnionPayload(), self.target.*);
8816 const err_off = errUnionErrorOffset(ty.errorUnionPayload(), mod);
87908817 switch (operand) {
87918818 .register => |reg| {
87928819 const eu_lock = self.register_manager.lockReg(reg);
......@@ -9088,12 +9115,13 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void {
90889115}
90899116
90909117fn airBr(self: *Self, inst: Air.Inst.Index) !void {
9118 const mod = self.bin_file.options.module.?;
90919119 const br = self.air.instructions.items(.data)[inst].br;
90929120 const src_mcv = try self.resolveInst(br.operand);
90939121
90949122 const block_ty = self.air.typeOfIndex(br.block_inst);
90959123 const block_unused =
9096 !block_ty.hasRuntimeBitsIgnoreComptime() or self.liveness.isUnused(br.block_inst);
9124 !block_ty.hasRuntimeBitsIgnoreComptime(mod) or self.liveness.isUnused(br.block_inst);
90979125 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;
90989126 const block_data = self.blocks.getPtr(br.block_inst).?;
90999127 const first_br = block_data.relocs.items.len == 0;
......@@ -9402,7 +9430,8 @@ const MoveStrategy = union(enum) {
94029430 };
94039431};
94049432fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy {
9405 switch (ty.zigTypeTag()) {
9433 const mod = self.bin_file.options.module.?;
9434 switch (ty.zigTypeTag(mod)) {
94069435 else => return .{ .move = .{ ._, .mov } },
94079436 .Float => switch (ty.floatBits(self.target.*)) {
94089437 16 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{
......@@ -9419,8 +9448,8 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy {
94199448 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
94209449 else => {},
94219450 },
9422 .Vector => switch (ty.childType().zigTypeTag()) {
9423 .Int => switch (ty.childType().intInfo(self.target.*).bits) {
9451 .Vector => switch (ty.childType().zigTypeTag(mod)) {
9452 .Int => switch (ty.childType().intInfo(mod).bits) {
94249453 8 => switch (ty.vectorLen()) {
94259454 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{
94269455 .insert = .{ .vp_b, .insr },
......@@ -9647,7 +9676,8 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
96479676}
96489677
96499678fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void {
9650 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
9679 const mod = self.bin_file.options.module.?;
9680 const abi_size = @intCast(u32, ty.abiSize(mod));
96519681 if (abi_size * 8 > dst_reg.bitSize())
96529682 return self.fail("genSetReg called with a value larger than dst_reg", .{});
96539683 switch (src_mcv) {
......@@ -9730,7 +9760,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
97309760 .{ .register = try self.copyToTmpRegister(ty, src_mcv) },
97319761 ),
97329762 .sse => try self.asmRegisterRegister(
9733 if (@as(?Mir.Inst.FixedTag, switch (ty.scalarType().zigTypeTag()) {
9763 if (@as(?Mir.Inst.FixedTag, switch (ty.scalarType(mod).zigTypeTag(mod)) {
97349764 else => switch (abi_size) {
97359765 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },
97369766 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov },
......@@ -9738,7 +9768,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
97389768 17...32 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else null,
97399769 else => null,
97409770 },
9741 .Float => switch (ty.scalarType().floatBits(self.target.*)) {
9771 .Float => switch (ty.scalarType(mod).floatBits(self.target.*)) {
97429772 16, 128 => switch (abi_size) {
97439773 2...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },
97449774 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov },
......@@ -9789,7 +9819,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
97899819 .indirect => try self.moveStrategy(ty, false),
97909820 .load_frame => |frame_addr| try self.moveStrategy(
97919821 ty,
9792 self.getFrameAddrAlignment(frame_addr) >= ty.abiAlignment(self.target.*),
9822 self.getFrameAddrAlignment(frame_addr) >= ty.abiAlignment(mod),
97939823 ),
97949824 .lea_frame => .{ .move = .{ ._, .lea } },
97959825 else => unreachable,
......@@ -9821,7 +9851,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
98219851 switch (try self.moveStrategy(ty, mem.isAlignedGeneric(
98229852 u32,
98239853 @bitCast(u32, small_addr),
9824 ty.abiAlignment(self.target.*),
9854 ty.abiAlignment(mod),
98259855 ))) {
98269856 .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem),
98279857 .insert_extract => |ie| try self.asmRegisterMemoryImmediate(
......@@ -9839,7 +9869,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
98399869 ),
98409870 }
98419871 },
9842 .load_direct => |sym_index| switch (ty.zigTypeTag()) {
9872 .load_direct => |sym_index| switch (ty.zigTypeTag(mod)) {
98439873 else => {
98449874 const atom_index = try self.owner.getSymbolIndex(self);
98459875 _ = try self.addInst(.{
......@@ -9933,7 +9963,8 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
99339963}
99349964
99359965fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCValue) InnerError!void {
9936 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
9966 const mod = self.bin_file.options.module.?;
9967 const abi_size = @intCast(u32, ty.abiSize(mod));
99379968 const dst_ptr_mcv: MCValue = switch (base) {
99389969 .none => .{ .immediate = @bitCast(u64, @as(i64, disp)) },
99399970 .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } },
......@@ -9945,7 +9976,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
99459976 try self.genInlineMemset(dst_ptr_mcv, .{ .immediate = 0xaa }, .{ .immediate = abi_size }),
99469977 .immediate => |imm| switch (abi_size) {
99479978 1, 2, 4 => {
9948 const immediate = if (ty.isSignedInt())
9979 const immediate = if (ty.isSignedInt(mod))
99499980 Immediate.s(@truncate(i32, @bitCast(i64, imm)))
99509981 else
99519982 Immediate.u(@intCast(u32, imm));
......@@ -9967,7 +9998,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
99679998 while (offset < abi_size) : (offset += 4) try self.asmMemoryImmediate(
99689999 .{ ._, .mov },
996910000 Memory.sib(.dword, .{ .base = base, .disp = disp + offset }),
9970 if (ty.isSignedInt())
10001 if (ty.isSignedInt(mod))
997110002 Immediate.s(@truncate(
997210003 i32,
997310004 @bitCast(i64, imm) >> (math.cast(u6, offset * 8) orelse 63),
......@@ -9991,19 +10022,19 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
999110022 .none => mem.isAlignedGeneric(
999210023 u32,
999310024 @bitCast(u32, disp),
9994 ty.abiAlignment(self.target.*),
10025 ty.abiAlignment(mod),
999510026 ),
999610027 .reg => |reg| switch (reg) {
999710028 .es, .cs, .ss, .ds => mem.isAlignedGeneric(
999810029 u32,
999910030 @bitCast(u32, disp),
10000 ty.abiAlignment(self.target.*),
10031 ty.abiAlignment(mod),
1000110032 ),
1000210033 else => false,
1000310034 },
1000410035 .frame => |frame_index| self.getFrameAddrAlignment(
1000510036 .{ .index = frame_index, .off = disp },
10006 ) >= ty.abiAlignment(self.target.*),
10037 ) >= ty.abiAlignment(mod),
1000710038 })) {
1000810039 .move => |tag| try self.asmMemoryRegister(tag, dst_mem, src_alias),
1000910040 .insert_extract, .vex_insert_extract => |ie| try self.asmMemoryRegisterImmediate(
......@@ -10017,13 +10048,13 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
1001710048 .register_overflow => |ro| {
1001810049 try self.genSetMem(
1001910050 base,
10020 disp + @intCast(i32, ty.structFieldOffset(0, self.target.*)),
10051 disp + @intCast(i32, ty.structFieldOffset(0, mod)),
1002110052 ty.structFieldType(0),
1002210053 .{ .register = ro.reg },
1002310054 );
1002410055 try self.genSetMem(
1002510056 base,
10026 disp + @intCast(i32, ty.structFieldOffset(1, self.target.*)),
10057 disp + @intCast(i32, ty.structFieldOffset(1, mod)),
1002710058 ty.structFieldType(1),
1002810059 .{ .eflags = ro.eflags },
1002910060 );
......@@ -10146,13 +10177,14 @@ fn airPtrToInt(self: *Self, inst: Air.Inst.Index) !void {
1014610177}
1014710178
1014810179fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
10180 const mod = self.bin_file.options.module.?;
1014910181 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1015010182 const dst_ty = self.air.typeOfIndex(inst);
1015110183 const src_ty = self.air.typeOf(ty_op.operand);
1015210184
1015310185 const result = result: {
10154 const dst_rc = regClassForType(dst_ty);
10155 const src_rc = regClassForType(src_ty);
10186 const dst_rc = regClassForType(dst_ty, mod);
10187 const src_rc = regClassForType(src_ty, mod);
1015610188 const src_mcv = try self.resolveInst(ty_op.operand);
1015710189
1015810190 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
......@@ -10172,13 +10204,13 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
1017210204 };
1017310205
1017410206 const dst_signedness =
10175 if (dst_ty.isAbiInt()) dst_ty.intInfo(self.target.*).signedness else .unsigned;
10207 if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned;
1017610208 const src_signedness =
10177 if (src_ty.isAbiInt()) src_ty.intInfo(self.target.*).signedness else .unsigned;
10209 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;
1017810210 if (dst_signedness == src_signedness) break :result dst_mcv;
1017910211
10180 const abi_size = @intCast(u16, dst_ty.abiSize(self.target.*));
10181 const bit_size = @intCast(u16, dst_ty.bitSize(self.target.*));
10212 const abi_size = @intCast(u16, dst_ty.abiSize(mod));
10213 const bit_size = @intCast(u16, dst_ty.bitSize(mod));
1018210214 if (abi_size * 8 <= bit_size) break :result dst_mcv;
1018310215
1018410216 const dst_limbs_len = math.divCeil(i32, bit_size, 64) catch unreachable;
......@@ -10192,14 +10224,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
1019210224 const high_lock = self.register_manager.lockReg(high_reg);
1019310225 defer if (high_lock) |lock| self.register_manager.unlockReg(lock);
1019410226
10195 var high_pl = Type.Payload.Bits{
10196 .base = .{ .tag = switch (dst_signedness) {
10197 .signed => .int_signed,
10198 .unsigned => .int_unsigned,
10199 } },
10200 .data = bit_size % 64,
10201 };
10202 const high_ty = Type.initPayload(&high_pl.base);
10227 const high_ty = try mod.intType(dst_signedness, bit_size % 64);
1020310228
1020410229 try self.truncateRegister(high_ty, high_reg);
1020510230 if (!dst_mcv.isRegister()) try self.genCopy(
......@@ -10213,6 +10238,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
1021310238}
1021410239
1021510240fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
10241 const mod = self.bin_file.options.module.?;
1021610242 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1021710243
1021810244 const slice_ty = self.air.typeOfIndex(inst);
......@@ -10221,11 +10247,11 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
1022110247 const array_ty = ptr_ty.childType();
1022210248 const array_len = array_ty.arrayLen();
1022310249
10224 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(slice_ty, self.target.*));
10250 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(slice_ty, mod));
1022510251 try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr);
1022610252 try self.genSetMem(
1022710253 .{ .frame = frame_index },
10228 @intCast(i32, ptr_ty.abiSize(self.target.*)),
10254 @intCast(i32, ptr_ty.abiSize(mod)),
1022910255 Type.usize,
1023010256 .{ .immediate = array_len },
1023110257 );
......@@ -10235,12 +10261,13 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
1023510261}
1023610262
1023710263fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
10264 const mod = self.bin_file.options.module.?;
1023810265 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1023910266
1024010267 const src_ty = self.air.typeOf(ty_op.operand);
10241 const src_bits = @intCast(u32, src_ty.bitSize(self.target.*));
10268 const src_bits = @intCast(u32, src_ty.bitSize(mod));
1024210269 const src_signedness =
10243 if (src_ty.isAbiInt()) src_ty.intInfo(self.target.*).signedness else .unsigned;
10270 if (src_ty.isAbiInt(mod)) src_ty.intInfo(mod).signedness else .unsigned;
1024410271 const dst_ty = self.air.typeOfIndex(inst);
1024510272
1024610273 const src_size = math.divCeil(u32, @max(switch (src_signedness) {
......@@ -10248,7 +10275,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
1024810275 .unsigned => src_bits + 1,
1024910276 }, 32), 8) catch unreachable;
1025010277 if (src_size > 8) return self.fail("TODO implement airIntToFloat from {} to {}", .{
10251 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
10278 src_ty.fmt(mod), dst_ty.fmt(mod),
1025210279 });
1025310280
1025410281 const src_mcv = try self.resolveInst(ty_op.operand);
......@@ -10261,12 +10288,12 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
1026110288
1026210289 if (src_bits < src_size * 8) try self.truncateRegister(src_ty, src_reg);
1026310290
10264 const dst_reg = try self.register_manager.allocReg(inst, regClassForType(dst_ty));
10291 const dst_reg = try self.register_manager.allocReg(inst, regClassForType(dst_ty, mod));
1026510292 const dst_mcv = MCValue{ .register = dst_reg };
1026610293 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
1026710294 defer self.register_manager.unlockReg(dst_lock);
1026810295
10269 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (dst_ty.zigTypeTag()) {
10296 const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (dst_ty.zigTypeTag(mod)) {
1027010297 .Float => switch (dst_ty.floatBits(self.target.*)) {
1027110298 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 },
1027210299 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 },
......@@ -10275,7 +10302,7 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
1027510302 },
1027610303 else => null,
1027710304 })) |tag| tag else return self.fail("TODO implement airIntToFloat from {} to {}", .{
10278 src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?),
10305 src_ty.fmt(mod), dst_ty.fmt(mod),
1027910306 });
1028010307 const dst_alias = dst_reg.to128();
1028110308 const src_alias = registerAlias(src_reg, src_size);
......@@ -10288,13 +10315,14 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
1028810315}
1028910316
1029010317fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
10318 const mod = self.bin_file.options.module.?;
1029110319 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1029210320
1029310321 const src_ty = self.air.typeOf(ty_op.operand);
1029410322 const dst_ty = self.air.typeOfIndex(inst);
10295 const dst_bits = @intCast(u32, dst_ty.bitSize(self.target.*));
10323 const dst_bits = @intCast(u32, dst_ty.bitSize(mod));
1029610324 const dst_signedness =
10297 if (dst_ty.isAbiInt()) dst_ty.intInfo(self.target.*).signedness else .unsigned;
10325 if (dst_ty.isAbiInt(mod)) dst_ty.intInfo(mod).signedness else .unsigned;
1029810326
1029910327 const dst_size = math.divCeil(u32, @max(switch (dst_signedness) {
1030010328 .signed => dst_bits,
......@@ -10312,13 +10340,13 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
1031210340 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
1031310341 defer self.register_manager.unlockReg(src_lock);
1031410342
10315 const dst_reg = try self.register_manager.allocReg(inst, regClassForType(dst_ty));
10343 const dst_reg = try self.register_manager.allocReg(inst, regClassForType(dst_ty, mod));
1031610344 const dst_mcv = MCValue{ .register = dst_reg };
1031710345 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
1031810346 defer self.register_manager.unlockReg(dst_lock);
1031910347
1032010348 try self.asmRegisterRegister(
10321 if (@as(?Mir.Inst.FixedTag, switch (src_ty.zigTypeTag()) {
10349 if (@as(?Mir.Inst.FixedTag, switch (src_ty.zigTypeTag(mod)) {
1032210350 .Float => switch (src_ty.floatBits(self.target.*)) {
1032310351 32 => if (self.hasFeature(.avx)) .{ .v_, .cvttss2si } else .{ ._, .cvttss2si },
1032410352 64 => if (self.hasFeature(.avx)) .{ .v_, .cvttsd2si } else .{ ._, .cvttsd2si },
......@@ -10339,12 +10367,13 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
1033910367}
1034010368
1034110369fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
10370 const mod = self.bin_file.options.module.?;
1034210371 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1034310372 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
1034410373
1034510374 const ptr_ty = self.air.typeOf(extra.ptr);
1034610375 const val_ty = self.air.typeOf(extra.expected_value);
10347 const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*));
10376 const val_abi_size = @intCast(u32, val_ty.abiSize(mod));
1034810377
1034910378 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });
1035010379 const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx });
......@@ -10433,6 +10462,7 @@ fn atomicOp(
1043310462 rmw_op: ?std.builtin.AtomicRmwOp,
1043410463 order: std.builtin.AtomicOrder,
1043510464) InnerError!MCValue {
10465 const mod = self.bin_file.options.module.?;
1043610466 const ptr_lock = switch (ptr_mcv) {
1043710467 .register => |reg| self.register_manager.lockReg(reg),
1043810468 else => null,
......@@ -10445,7 +10475,7 @@ fn atomicOp(
1044510475 };
1044610476 defer if (val_lock) |lock| self.register_manager.unlockReg(lock);
1044710477
10448 const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*));
10478 const val_abi_size = @intCast(u32, val_ty.abiSize(mod));
1044910479 const ptr_size = Memory.PtrSize.fromSize(val_abi_size);
1045010480 const ptr_mem = switch (ptr_mcv) {
1045110481 .immediate, .register, .register_offset, .lea_frame => ptr_mcv.deref().mem(ptr_size),
......@@ -10539,8 +10569,8 @@ fn atomicOp(
1053910569 .Or => try self.genBinOpMir(.{ ._, .@"or" }, val_ty, tmp_mcv, val_mcv),
1054010570 .Xor => try self.genBinOpMir(.{ ._, .xor }, val_ty, tmp_mcv, val_mcv),
1054110571 .Min, .Max => {
10542 const cc: Condition = switch (if (val_ty.isAbiInt())
10543 val_ty.intInfo(self.target.*).signedness
10572 const cc: Condition = switch (if (val_ty.isAbiInt(mod))
10573 val_ty.intInfo(mod).signedness
1054410574 else
1054510575 .unsigned) {
1054610576 .unsigned => switch (op) {
......@@ -10728,6 +10758,7 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr
1072810758}
1072910759
1073010760fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
10761 const mod = self.bin_file.options.module.?;
1073110762 if (safety) {
1073210763 // TODO if the value is undef, write 0xaa bytes to dest
1073310764 } else {
......@@ -10752,7 +10783,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
1075210783 };
1075310784 defer if (src_val_lock) |lock| self.register_manager.unlockReg(lock);
1075410785
10755 const elem_abi_size = @intCast(u31, elem_ty.abiSize(self.target.*));
10786 const elem_abi_size = @intCast(u31, elem_ty.abiSize(mod));
1075610787
1075710788 if (elem_abi_size == 1) {
1075810789 const ptr: MCValue = switch (dst_ptr_ty.ptrSize()) {
......@@ -10897,8 +10928,8 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
1089710928 // We need a properly aligned and sized call frame to be able to call this function.
1089810929 {
1089910930 const needed_call_frame = FrameAlloc.init(.{
10900 .size = inst_ty.abiSize(self.target.*),
10901 .alignment = inst_ty.abiAlignment(self.target.*),
10931 .size = inst_ty.abiSize(mod),
10932 .alignment = inst_ty.abiAlignment(mod),
1090210933 });
1090310934 const frame_allocs_slice = self.frame_allocs.slice();
1090410935 const stack_frame_size =
......@@ -11013,14 +11044,15 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
1101311044}
1101411045
1101511046fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
11047 const mod = self.bin_file.options.module.?;
1101611048 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1101711049 const vector_ty = self.air.typeOfIndex(inst);
11018 const dst_rc = regClassForType(vector_ty);
11019 const scalar_ty = vector_ty.scalarType();
11050 const dst_rc = regClassForType(vector_ty, mod);
11051 const scalar_ty = vector_ty.scalarType(mod);
1102011052
1102111053 const src_mcv = try self.resolveInst(ty_op.operand);
1102211054 const result: MCValue = result: {
11023 switch (scalar_ty.zigTypeTag()) {
11055 switch (scalar_ty.zigTypeTag(mod)) {
1102411056 else => {},
1102511057 .Float => switch (scalar_ty.floatBits(self.target.*)) {
1102611058 32 => switch (vector_ty.vectorLen()) {
......@@ -11233,36 +11265,37 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
1123311265}
1123411266
1123511267fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
11268 const mod = self.bin_file.options.module.?;
1123611269 const result_ty = self.air.typeOfIndex(inst);
1123711270 const len = @intCast(usize, result_ty.arrayLen());
1123811271 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1123911272 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
1124011273 const result: MCValue = result: {
11241 switch (result_ty.zigTypeTag()) {
11274 switch (result_ty.zigTypeTag(mod)) {
1124211275 .Struct => {
1124311276 const frame_index =
11244 try self.allocFrameIndex(FrameAlloc.initType(result_ty, self.target.*));
11277 try self.allocFrameIndex(FrameAlloc.initType(result_ty, mod));
1124511278 if (result_ty.containerLayout() == .Packed) {
1124611279 const struct_obj = result_ty.castTag(.@"struct").?.data;
1124711280 try self.genInlineMemset(
1124811281 .{ .lea_frame = .{ .index = frame_index } },
1124911282 .{ .immediate = 0 },
11250 .{ .immediate = result_ty.abiSize(self.target.*) },
11283 .{ .immediate = result_ty.abiSize(mod) },
1125111284 );
1125211285 for (elements, 0..) |elem, elem_i| {
11253 if (result_ty.structFieldValueComptime(elem_i) != null) continue;
11286 if (result_ty.structFieldValueComptime(mod, elem_i) != null) continue;
1125411287
1125511288 const elem_ty = result_ty.structFieldType(elem_i);
11256 const elem_bit_size = @intCast(u32, elem_ty.bitSize(self.target.*));
11289 const elem_bit_size = @intCast(u32, elem_ty.bitSize(mod));
1125711290 if (elem_bit_size > 64) {
1125811291 return self.fail(
1125911292 "TODO airAggregateInit implement packed structs with large fields",
1126011293 .{},
1126111294 );
1126211295 }
11263 const elem_abi_size = @intCast(u32, elem_ty.abiSize(self.target.*));
11296 const elem_abi_size = @intCast(u32, elem_ty.abiSize(mod));
1126411297 const elem_abi_bits = elem_abi_size * 8;
11265 const elem_off = struct_obj.packedFieldBitOffset(self.target.*, elem_i);
11298 const elem_off = struct_obj.packedFieldBitOffset(mod, elem_i);
1126611299 const elem_byte_off = @intCast(i32, elem_off / elem_abi_bits * elem_abi_size);
1126711300 const elem_bit_off = elem_off % elem_abi_bits;
1126811301 const elem_mcv = try self.resolveInst(elem);
......@@ -11322,10 +11355,10 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1132211355 }
1132311356 }
1132411357 } else for (elements, 0..) |elem, elem_i| {
11325 if (result_ty.structFieldValueComptime(elem_i) != null) continue;
11358 if (result_ty.structFieldValueComptime(mod, elem_i) != null) continue;
1132611359
1132711360 const elem_ty = result_ty.structFieldType(elem_i);
11328 const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, self.target.*));
11361 const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, mod));
1132911362 const elem_mcv = try self.resolveInst(elem);
1133011363 const mat_elem_mcv = switch (elem_mcv) {
1133111364 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },
......@@ -11337,9 +11370,9 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1133711370 },
1133811371 .Array => {
1133911372 const frame_index =
11340 try self.allocFrameIndex(FrameAlloc.initType(result_ty, self.target.*));
11373 try self.allocFrameIndex(FrameAlloc.initType(result_ty, mod));
1134111374 const elem_ty = result_ty.childType();
11342 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
11375 const elem_size = @intCast(u32, elem_ty.abiSize(mod));
1134311376
1134411377 for (elements, 0..) |elem, elem_i| {
1134511378 const elem_mcv = try self.resolveInst(elem);
......@@ -11374,11 +11407,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1137411407}
1137511408
1137611409fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
11410 const mod = self.bin_file.options.module.?;
1137711411 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1137811412 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
1137911413 const result: MCValue = result: {
1138011414 const union_ty = self.air.typeOfIndex(inst);
11381 const layout = union_ty.unionGetLayout(self.target.*);
11415 const layout = union_ty.unionGetLayout(mod);
1138211416
1138311417 const src_ty = self.air.typeOf(extra.init);
1138411418 const src_mcv = try self.resolveInst(extra.init);
......@@ -11400,7 +11434,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
1140011434 const tag_val = Value.initPayload(&tag_pl.base);
1140111435 var tag_int_pl: Value.Payload.U64 = undefined;
1140211436 const tag_int_val = tag_val.enumToInt(tag_ty, &tag_int_pl);
11403 const tag_int = tag_int_val.toUnsignedInt(self.target.*);
11437 const tag_int = tag_int_val.toUnsignedInt(mod);
1140411438 const tag_off = if (layout.tag_align < layout.payload_align)
1140511439 @intCast(i32, layout.payload_size)
1140611440 else
......@@ -11424,6 +11458,7 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
1142411458}
1142511459
1142611460fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
11461 const mod = self.bin_file.options.module.?;
1142711462 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
1142811463 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
1142911464 const ty = self.air.typeOfIndex(inst);
......@@ -11466,14 +11501,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
1146611501 const mir_tag = if (@as(
1146711502 ?Mir.Inst.FixedTag,
1146811503 if (mem.eql(u2, &order, &.{ 1, 3, 2 }) or mem.eql(u2, &order, &.{ 3, 1, 2 }))
11469 switch (ty.zigTypeTag()) {
11504 switch (ty.zigTypeTag(mod)) {
1147011505 .Float => switch (ty.floatBits(self.target.*)) {
1147111506 32 => .{ .v_ss, .fmadd132 },
1147211507 64 => .{ .v_sd, .fmadd132 },
1147311508 16, 80, 128 => null,
1147411509 else => unreachable,
1147511510 },
11476 .Vector => switch (ty.childType().zigTypeTag()) {
11511 .Vector => switch (ty.childType().zigTypeTag(mod)) {
1147711512 .Float => switch (ty.childType().floatBits(self.target.*)) {
1147811513 32 => switch (ty.vectorLen()) {
1147911514 1 => .{ .v_ss, .fmadd132 },
......@@ -11493,14 +11528,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
1149311528 else => unreachable,
1149411529 }
1149511530 else if (mem.eql(u2, &order, &.{ 2, 1, 3 }) or mem.eql(u2, &order, &.{ 1, 2, 3 }))
11496 switch (ty.zigTypeTag()) {
11531 switch (ty.zigTypeTag(mod)) {
1149711532 .Float => switch (ty.floatBits(self.target.*)) {
1149811533 32 => .{ .v_ss, .fmadd213 },
1149911534 64 => .{ .v_sd, .fmadd213 },
1150011535 16, 80, 128 => null,
1150111536 else => unreachable,
1150211537 },
11503 .Vector => switch (ty.childType().zigTypeTag()) {
11538 .Vector => switch (ty.childType().zigTypeTag(mod)) {
1150411539 .Float => switch (ty.childType().floatBits(self.target.*)) {
1150511540 32 => switch (ty.vectorLen()) {
1150611541 1 => .{ .v_ss, .fmadd213 },
......@@ -11520,14 +11555,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
1152011555 else => unreachable,
1152111556 }
1152211557 else if (mem.eql(u2, &order, &.{ 2, 3, 1 }) or mem.eql(u2, &order, &.{ 3, 2, 1 }))
11523 switch (ty.zigTypeTag()) {
11558 switch (ty.zigTypeTag(mod)) {
1152411559 .Float => switch (ty.floatBits(self.target.*)) {
1152511560 32 => .{ .v_ss, .fmadd231 },
1152611561 64 => .{ .v_sd, .fmadd231 },
1152711562 16, 80, 128 => null,
1152811563 else => unreachable,
1152911564 },
11530 .Vector => switch (ty.childType().zigTypeTag()) {
11565 .Vector => switch (ty.childType().zigTypeTag(mod)) {
1153111566 .Float => switch (ty.childType().floatBits(self.target.*)) {
1153211567 32 => switch (ty.vectorLen()) {
1153311568 1 => .{ .v_ss, .fmadd231 },
......@@ -11555,7 +11590,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
1155511590 var mops: [3]MCValue = undefined;
1155611591 for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv;
1155711592
11558 const abi_size = @intCast(u32, ty.abiSize(self.target.*));
11593 const abi_size = @intCast(u32, ty.abiSize(mod));
1155911594 const mop1_reg = registerAlias(mops[0].getReg().?, abi_size);
1156011595 const mop2_reg = registerAlias(mops[1].getReg().?, abi_size);
1156111596 if (mops[2].isRegister()) try self.asmRegisterRegisterRegister(
......@@ -11573,10 +11608,11 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
1157311608}
1157411609
1157511610fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
11611 const mod = self.bin_file.options.module.?;
1157611612 const ty = self.air.typeOf(ref);
1157711613
1157811614 // If the type has no codegen bits, no need to store it.
11579 if (!ty.hasRuntimeBitsIgnoreComptime()) return .none;
11615 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;
1158011616
1158111617 if (Air.refToIndex(ref)) |inst| {
1158211618 const mcv = switch (self.air.instructions.items(.tag)[inst]) {
......@@ -11584,7 +11620,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
1158411620 const gop = try self.const_tracking.getOrPut(self.gpa, inst);
1158511621 if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{
1158611622 .ty = ty,
11587 .val = self.air.value(ref).?,
11623 .val = self.air.value(ref, mod).?,
1158811624 }));
1158911625 break :tracking gop.value_ptr;
1159011626 },
......@@ -11597,7 +11633,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
1159711633 }
1159811634 }
1159911635
11600 return self.genTypedValue(.{ .ty = ty, .val = self.air.value(ref).? });
11636 return self.genTypedValue(.{ .ty = ty, .val = self.air.value(ref, mod).? });
1160111637}
1160211638
1160311639fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) *InstTracking {
......@@ -11670,6 +11706,7 @@ fn resolveCallingConventionValues(
1167011706 var_args: []const Air.Inst.Ref,
1167111707 stack_frame_base: FrameIndex,
1167211708) !CallMCValues {
11709 const mod = self.bin_file.options.module.?;
1167311710 const cc = fn_ty.fnCallingConvention();
1167411711 const param_len = fn_ty.fnParamLen();
1167511712 const param_types = try self.gpa.alloc(Type, param_len + var_args.len);
......@@ -11702,21 +11739,21 @@ fn resolveCallingConventionValues(
1170211739 switch (self.target.os.tag) {
1170311740 .windows => {
1170411741 // Align the stack to 16bytes before allocating shadow stack space (if any).
11705 result.stack_byte_count += @intCast(u31, 4 * Type.usize.abiSize(self.target.*));
11742 result.stack_byte_count += @intCast(u31, 4 * Type.usize.abiSize(mod));
1170611743 },
1170711744 else => {},
1170811745 }
1170911746
1171011747 // Return values
11711 if (ret_ty.zigTypeTag() == .NoReturn) {
11748 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
1171211749 result.return_value = InstTracking.init(.unreach);
11713 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {
11750 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1171411751 // TODO: is this even possible for C calling convention?
1171511752 result.return_value = InstTracking.init(.none);
1171611753 } else {
1171711754 const classes = switch (self.target.os.tag) {
11718 .windows => &[1]abi.Class{abi.classifyWindows(ret_ty, self.target.*)},
11719 else => mem.sliceTo(&abi.classifySystemV(ret_ty, self.target.*, .ret), .none),
11755 .windows => &[1]abi.Class{abi.classifyWindows(ret_ty, mod)},
11756 else => mem.sliceTo(&abi.classifySystemV(ret_ty, mod, .ret), .none),
1172011757 };
1172111758 if (classes.len > 1) {
1172211759 return self.fail("TODO handle multiple classes per type", .{});
......@@ -11725,7 +11762,7 @@ fn resolveCallingConventionValues(
1172511762 result.return_value = switch (classes[0]) {
1172611763 .integer => InstTracking.init(.{ .register = registerAlias(
1172711764 ret_reg,
11728 @intCast(u32, ret_ty.abiSize(self.target.*)),
11765 @intCast(u32, ret_ty.abiSize(mod)),
1172911766 ) }),
1173011767 .float, .sse => InstTracking.init(.{ .register = .xmm0 }),
1173111768 .memory => ret: {
......@@ -11744,11 +11781,11 @@ fn resolveCallingConventionValues(
1174411781
1174511782 // Input params
1174611783 for (param_types, result.args) |ty, *arg| {
11747 assert(ty.hasRuntimeBitsIgnoreComptime());
11784 assert(ty.hasRuntimeBitsIgnoreComptime(mod));
1174811785
1174911786 const classes = switch (self.target.os.tag) {
11750 .windows => &[1]abi.Class{abi.classifyWindows(ty, self.target.*)},
11751 else => mem.sliceTo(&abi.classifySystemV(ty, self.target.*, .arg), .none),
11787 .windows => &[1]abi.Class{abi.classifyWindows(ty, mod)},
11788 else => mem.sliceTo(&abi.classifySystemV(ty, mod, .arg), .none),
1175211789 };
1175311790 if (classes.len > 1) {
1175411791 return self.fail("TODO handle multiple classes per type", .{});
......@@ -11783,8 +11820,8 @@ fn resolveCallingConventionValues(
1178311820 }),
1178411821 }
1178511822
11786 const param_size = @intCast(u31, ty.abiSize(self.target.*));
11787 const param_align = @intCast(u31, ty.abiAlignment(self.target.*));
11823 const param_size = @intCast(u31, ty.abiSize(mod));
11824 const param_align = @intCast(u31, ty.abiAlignment(mod));
1178811825 result.stack_byte_count =
1178911826 mem.alignForwardGeneric(u31, result.stack_byte_count, param_align);
1179011827 arg.* = .{ .load_frame = .{
......@@ -11798,13 +11835,13 @@ fn resolveCallingConventionValues(
1179811835 result.stack_align = 16;
1179911836
1180011837 // Return values
11801 if (ret_ty.zigTypeTag() == .NoReturn) {
11838 if (ret_ty.zigTypeTag(mod) == .NoReturn) {
1180211839 result.return_value = InstTracking.init(.unreach);
11803 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {
11840 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1180411841 result.return_value = InstTracking.init(.none);
1180511842 } else {
1180611843 const ret_reg = abi.getCAbiIntReturnRegs(self.target.*)[0];
11807 const ret_ty_size = @intCast(u31, ret_ty.abiSize(self.target.*));
11844 const ret_ty_size = @intCast(u31, ret_ty.abiSize(mod));
1180811845 if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) {
1180911846 const aliased_reg = registerAlias(ret_reg, ret_ty_size);
1181011847 result.return_value = .{ .short = .{ .register = aliased_reg }, .long = .none };
......@@ -11819,12 +11856,12 @@ fn resolveCallingConventionValues(
1181911856
1182011857 // Input params
1182111858 for (param_types, result.args) |ty, *arg| {
11822 if (!ty.hasRuntimeBitsIgnoreComptime()) {
11859 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
1182311860 arg.* = .none;
1182411861 continue;
1182511862 }
11826 const param_size = @intCast(u31, ty.abiSize(self.target.*));
11827 const param_align = @intCast(u31, ty.abiAlignment(self.target.*));
11863 const param_size = @intCast(u31, ty.abiSize(mod));
11864 const param_align = @intCast(u31, ty.abiAlignment(mod));
1182811865 result.stack_byte_count =
1182911866 mem.alignForwardGeneric(u31, result.stack_byte_count, param_align);
1183011867 arg.* = .{ .load_frame = .{
......@@ -11908,9 +11945,10 @@ fn registerAlias(reg: Register, size_bytes: u32) Register {
1190811945/// Truncates the value in the register in place.
1190911946/// Clobbers any remaining bits.
1191011947fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
11911 const int_info = if (ty.isAbiInt()) ty.intInfo(self.target.*) else std.builtin.Type.Int{
11948 const mod = self.bin_file.options.module.?;
11949 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{
1191211950 .signedness = .unsigned,
11913 .bits = @intCast(u16, ty.bitSize(self.target.*)),
11951 .bits = @intCast(u16, ty.bitSize(mod)),
1191411952 };
1191511953 const max_reg_bit_width = Register.rax.bitSize();
1191611954 switch (int_info.signedness) {
......@@ -11953,8 +11991,9 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
1195311991}
1195411992
1195511993fn regBitSize(self: *Self, ty: Type) u64 {
11956 const abi_size = ty.abiSize(self.target.*);
11957 return switch (ty.zigTypeTag()) {
11994 const mod = self.bin_file.options.module.?;
11995 const abi_size = ty.abiSize(mod);
11996 return switch (ty.zigTypeTag(mod)) {
1195811997 else => switch (abi_size) {
1195911998 1 => 8,
1196011999 2 => 16,
......@@ -11971,7 +12010,8 @@ fn regBitSize(self: *Self, ty: Type) u64 {
1197112010}
1197212011
1197312012fn regExtraBits(self: *Self, ty: Type) u64 {
11974 return self.regBitSize(ty) - ty.bitSize(self.target.*);
12013 const mod = self.bin_file.options.module.?;
12014 return self.regBitSize(ty) - ty.bitSize(mod);
1197512015}
1197612016
1197712017fn hasFeature(self: *Self, feature: Target.x86.Feature) bool {
src/arch/x86_64/abi.zig+26-56
......@@ -1,10 +1,3 @@
1const std = @import("std");
2const Type = @import("../../type.zig").Type;
3const Target = std.Target;
4const assert = std.debug.assert;
5const Register = @import("bits.zig").Register;
6const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
7
81pub const Class = enum {
92 integer,
103 sse,
......@@ -19,7 +12,7 @@ pub const Class = enum {
1912 float_combine,
2013};
2114
22pub fn classifyWindows(ty: Type, target: Target) Class {
15pub fn classifyWindows(ty: Type, mod: *const Module) Class {
2316 // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
2417 // "There's a strict one-to-one correspondence between a function call's arguments
2518 // and the registers used for those arguments. Any argument that doesn't fit in 8
......@@ -28,7 +21,7 @@ pub fn classifyWindows(ty: Type, target: Target) Class {
2821 // "All floating point operations are done using the 16 XMM registers."
2922 // "Structs and unions of size 8, 16, 32, or 64 bits, and __m64 types, are passed
3023 // as if they were integers of the same size."
31 switch (ty.zigTypeTag()) {
24 switch (ty.zigTypeTag(mod)) {
3225 .Pointer,
3326 .Int,
3427 .Bool,
......@@ -43,10 +36,10 @@ pub fn classifyWindows(ty: Type, target: Target) Class {
4336 .ErrorUnion,
4437 .AnyFrame,
4538 .Frame,
46 => switch (ty.abiSize(target)) {
39 => switch (ty.abiSize(mod)) {
4740 0 => unreachable,
4841 1, 2, 4, 8 => return .integer,
49 else => switch (ty.zigTypeTag()) {
42 else => switch (ty.zigTypeTag(mod)) {
5043 .Int => return .win_i128,
5144 .Struct, .Union => if (ty.containerLayout() == .Packed) {
5245 return .win_i128;
......@@ -75,13 +68,14 @@ pub const Context = enum { ret, arg, other };
7568
7669/// There are a maximum of 8 possible return slots. Returned values are in
7770/// the beginning of the array; unused slots are filled with .none.
78pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
71pub fn classifySystemV(ty: Type, mod: *const Module, ctx: Context) [8]Class {
72 const target = mod.getTarget();
7973 const memory_class = [_]Class{
8074 .memory, .none, .none, .none,
8175 .none, .none, .none, .none,
8276 };
8377 var result = [1]Class{.none} ** 8;
84 switch (ty.zigTypeTag()) {
78 switch (ty.zigTypeTag(mod)) {
8579 .Pointer => switch (ty.ptrSize()) {
8680 .Slice => {
8781 result[0] = .integer;
......@@ -94,7 +88,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
9488 },
9589 },
9690 .Int, .Enum, .ErrorSet => {
97 const bits = ty.intInfo(target).bits;
91 const bits = ty.intInfo(mod).bits;
9892 if (bits <= 64) {
9993 result[0] = .integer;
10094 return result;
......@@ -165,7 +159,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
165159 },
166160 .Vector => {
167161 const elem_ty = ty.childType();
168 const bits = elem_ty.bitSize(target) * ty.arrayLen();
162 const bits = elem_ty.bitSize(mod) * ty.arrayLen();
169163 if (bits <= 64) return .{
170164 .sse, .none, .none, .none,
171165 .none, .none, .none, .none,
......@@ -204,7 +198,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
204198 return memory_class;
205199 },
206200 .Optional => {
207 if (ty.isPtrLikeOptional()) {
201 if (ty.isPtrLikeOptional(mod)) {
208202 result[0] = .integer;
209203 return result;
210204 }
......@@ -215,7 +209,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
215209 // it contains unaligned fields, it has class MEMORY"
216210 // "If the size of the aggregate exceeds a single eightbyte, each is classified
217211 // separately.".
218 const ty_size = ty.abiSize(target);
212 const ty_size = ty.abiSize(mod);
219213 if (ty.containerLayout() == .Packed) {
220214 assert(ty_size <= 128);
221215 result[0] = .integer;
......@@ -230,12 +224,12 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
230224 const fields = ty.structFields();
231225 for (fields.values()) |field| {
232226 if (field.abi_align != 0) {
233 if (field.abi_align < field.ty.abiAlignment(target)) {
227 if (field.abi_align < field.ty.abiAlignment(mod)) {
234228 return memory_class;
235229 }
236230 }
237 const field_size = field.ty.abiSize(target);
238 const field_class_array = classifySystemV(field.ty, target, .other);
231 const field_size = field.ty.abiSize(mod);
232 const field_class_array = classifySystemV(field.ty, mod, .other);
239233 const field_class = std.mem.sliceTo(&field_class_array, .none);
240234 if (byte_i + field_size <= 8) {
241235 // Combine this field with the previous one.
......@@ -334,7 +328,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
334328 // it contains unaligned fields, it has class MEMORY"
335329 // "If the size of the aggregate exceeds a single eightbyte, each is classified
336330 // separately.".
337 const ty_size = ty.abiSize(target);
331 const ty_size = ty.abiSize(mod);
338332 if (ty.containerLayout() == .Packed) {
339333 assert(ty_size <= 128);
340334 result[0] = .integer;
......@@ -347,12 +341,12 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
347341 const fields = ty.unionFields();
348342 for (fields.values()) |field| {
349343 if (field.abi_align != 0) {
350 if (field.abi_align < field.ty.abiAlignment(target)) {
344 if (field.abi_align < field.ty.abiAlignment(mod)) {
351345 return memory_class;
352346 }
353347 }
354348 // Combine this field with the previous one.
355 const field_class = classifySystemV(field.ty, target, .other);
349 const field_class = classifySystemV(field.ty, mod, .other);
356350 for (&result, 0..) |*result_item, i| {
357351 const field_item = field_class[i];
358352 // "If both classes are equal, this is the resulting class."
......@@ -426,7 +420,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
426420 return result;
427421 },
428422 .Array => {
429 const ty_size = ty.abiSize(target);
423 const ty_size = ty.abiSize(mod);
430424 if (ty_size <= 64) {
431425 result[0] = .integer;
432426 return result;
......@@ -527,10 +521,17 @@ pub const RegisterClass = struct {
527521 };
528522};
529523
524const builtin = @import("builtin");
525const std = @import("std");
526const Target = std.Target;
527const assert = std.debug.assert;
530528const testing = std.testing;
529
531530const Module = @import("../../Module.zig");
531const Register = @import("bits.zig").Register;
532const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
533const Type = @import("../../type.zig").Type;
532534const Value = @import("../../value.zig").Value;
533const builtin = @import("builtin");
534535
535536fn _field(comptime tag: Type.Tag, offset: u32) Module.Struct.Field {
536537 return .{
......@@ -541,34 +542,3 @@ fn _field(comptime tag: Type.Tag, offset: u32) Module.Struct.Field {
541542 .is_comptime = false,
542543 };
543544}
544
545test "C_C_D" {
546 var fields = Module.Struct.Fields{};
547 // const C_C_D = extern struct { v1: i8, v2: i8, v3: f64 };
548 try fields.ensureTotalCapacity(testing.allocator, 3);
549 defer fields.deinit(testing.allocator);
550 fields.putAssumeCapacity("v1", _field(.i8, 0));
551 fields.putAssumeCapacity("v2", _field(.i8, 1));
552 fields.putAssumeCapacity("v3", _field(.f64, 4));
553
554 var C_C_D_struct = Module.Struct{
555 .fields = fields,
556 .namespace = undefined,
557 .owner_decl = undefined,
558 .zir_index = undefined,
559 .layout = .Extern,
560 .status = .fully_resolved,
561 .known_non_opv = true,
562 .is_tuple = false,
563 };
564 var C_C_D = Type.Payload.Struct{ .data = &C_C_D_struct };
565
566 try testing.expectEqual(
567 [_]Class{ .integer, .sse, .none, .none, .none, .none, .none, .none },
568 classifySystemV(Type.initPayload(&C_C_D.base), builtin.target, .ret),
569 );
570 try testing.expectEqual(
571 [_]Class{ .integer, .sse, .none, .none, .none, .none, .none, .none },
572 classifySystemV(Type.initPayload(&C_C_D.base), builtin.target, .arg),
573 );
574}
src/codegen.zig+101-103
......@@ -154,7 +154,7 @@ pub fn generateLazySymbol(
154154 }
155155 mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian);
156156 return Result.ok;
157 } else if (lazy_sym.ty.zigTypeTag() == .Enum) {
157 } else if (lazy_sym.ty.zigTypeTag(mod) == .Enum) {
158158 alignment.* = 1;
159159 for (lazy_sym.ty.enumFields().keys()) |tag_name| {
160160 try code.ensureUnusedCapacity(tag_name.len + 1);
......@@ -186,22 +186,22 @@ pub fn generateSymbol(
186186 typed_value.val = rt.data;
187187 }
188188
189 const target = bin_file.options.target;
189 const mod = bin_file.options.module.?;
190 const target = mod.getTarget();
190191 const endian = target.cpu.arch.endian();
191192
192 const mod = bin_file.options.module.?;
193193 log.debug("generateSymbol: ty = {}, val = {}", .{
194194 typed_value.ty.fmt(mod),
195195 typed_value.val.fmtValue(typed_value.ty, mod),
196196 });
197197
198198 if (typed_value.val.isUndefDeep()) {
199 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;
199 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
200200 try code.appendNTimes(0xaa, abi_size);
201201 return Result.ok;
202202 }
203203
204 switch (typed_value.ty.zigTypeTag()) {
204 switch (typed_value.ty.zigTypeTag(mod)) {
205205 .Fn => {
206206 return Result{
207207 .fail = try ErrorMsg.create(
......@@ -219,7 +219,7 @@ pub fn generateSymbol(
219219 64 => writeFloat(f64, typed_value.val.toFloat(f64), target, endian, try code.addManyAsArray(8)),
220220 80 => {
221221 writeFloat(f80, typed_value.val.toFloat(f80), target, endian, try code.addManyAsArray(10));
222 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;
222 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
223223 try code.appendNTimes(0, abi_size - 10);
224224 },
225225 128 => writeFloat(f128, typed_value.val.toFloat(f128), target, endian, try code.addManyAsArray(16)),
......@@ -242,7 +242,7 @@ pub fn generateSymbol(
242242 try code.ensureUnusedCapacity(bytes.len + 1);
243243 code.appendSliceAssumeCapacity(bytes);
244244 if (typed_value.ty.sentinel()) |sent_val| {
245 const byte = @intCast(u8, sent_val.toUnsignedInt(target));
245 const byte = @intCast(u8, sent_val.toUnsignedInt(mod));
246246 code.appendAssumeCapacity(byte);
247247 }
248248 return Result.ok;
......@@ -330,11 +330,11 @@ pub fn generateSymbol(
330330 .zero, .one, .int_u64, .int_big_positive => {
331331 switch (target.ptrBitWidth()) {
332332 32 => {
333 const x = typed_value.val.toUnsignedInt(target);
333 const x = typed_value.val.toUnsignedInt(mod);
334334 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, x), endian);
335335 },
336336 64 => {
337 const x = typed_value.val.toUnsignedInt(target);
337 const x = typed_value.val.toUnsignedInt(mod);
338338 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
339339 },
340340 else => unreachable,
......@@ -399,19 +399,19 @@ pub fn generateSymbol(
399399 },
400400 },
401401 .Int => {
402 const info = typed_value.ty.intInfo(target);
402 const info = typed_value.ty.intInfo(mod);
403403 if (info.bits <= 8) {
404404 const x: u8 = switch (info.signedness) {
405 .unsigned => @intCast(u8, typed_value.val.toUnsignedInt(target)),
406 .signed => @bitCast(u8, @intCast(i8, typed_value.val.toSignedInt(target))),
405 .unsigned => @intCast(u8, typed_value.val.toUnsignedInt(mod)),
406 .signed => @bitCast(u8, @intCast(i8, typed_value.val.toSignedInt(mod))),
407407 };
408408 try code.append(x);
409409 return Result.ok;
410410 }
411411 if (info.bits > 64) {
412412 var bigint_buffer: Value.BigIntSpace = undefined;
413 const bigint = typed_value.val.toBigInt(&bigint_buffer, target);
414 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;
413 const bigint = typed_value.val.toBigInt(&bigint_buffer, mod);
414 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
415415 const start = code.items.len;
416416 try code.resize(start + abi_size);
417417 bigint.writeTwosComplement(code.items[start..][0..abi_size], endian);
......@@ -420,25 +420,25 @@ pub fn generateSymbol(
420420 switch (info.signedness) {
421421 .unsigned => {
422422 if (info.bits <= 16) {
423 const x = @intCast(u16, typed_value.val.toUnsignedInt(target));
423 const x = @intCast(u16, typed_value.val.toUnsignedInt(mod));
424424 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);
425425 } else if (info.bits <= 32) {
426 const x = @intCast(u32, typed_value.val.toUnsignedInt(target));
426 const x = @intCast(u32, typed_value.val.toUnsignedInt(mod));
427427 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);
428428 } else {
429 const x = typed_value.val.toUnsignedInt(target);
429 const x = typed_value.val.toUnsignedInt(mod);
430430 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
431431 }
432432 },
433433 .signed => {
434434 if (info.bits <= 16) {
435 const x = @intCast(i16, typed_value.val.toSignedInt(target));
435 const x = @intCast(i16, typed_value.val.toSignedInt(mod));
436436 mem.writeInt(i16, try code.addManyAsArray(2), x, endian);
437437 } else if (info.bits <= 32) {
438 const x = @intCast(i32, typed_value.val.toSignedInt(target));
438 const x = @intCast(i32, typed_value.val.toSignedInt(mod));
439439 mem.writeInt(i32, try code.addManyAsArray(4), x, endian);
440440 } else {
441 const x = typed_value.val.toSignedInt(target);
441 const x = typed_value.val.toSignedInt(mod);
442442 mem.writeInt(i64, try code.addManyAsArray(8), x, endian);
443443 }
444444 },
......@@ -449,9 +449,9 @@ pub fn generateSymbol(
449449 var int_buffer: Value.Payload.U64 = undefined;
450450 const int_val = typed_value.enumToInt(&int_buffer);
451451
452 const info = typed_value.ty.intInfo(target);
452 const info = typed_value.ty.intInfo(mod);
453453 if (info.bits <= 8) {
454 const x = @intCast(u8, int_val.toUnsignedInt(target));
454 const x = @intCast(u8, int_val.toUnsignedInt(mod));
455455 try code.append(x);
456456 return Result.ok;
457457 }
......@@ -468,25 +468,25 @@ pub fn generateSymbol(
468468 switch (info.signedness) {
469469 .unsigned => {
470470 if (info.bits <= 16) {
471 const x = @intCast(u16, int_val.toUnsignedInt(target));
471 const x = @intCast(u16, int_val.toUnsignedInt(mod));
472472 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);
473473 } else if (info.bits <= 32) {
474 const x = @intCast(u32, int_val.toUnsignedInt(target));
474 const x = @intCast(u32, int_val.toUnsignedInt(mod));
475475 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);
476476 } else {
477 const x = int_val.toUnsignedInt(target);
477 const x = int_val.toUnsignedInt(mod);
478478 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
479479 }
480480 },
481481 .signed => {
482482 if (info.bits <= 16) {
483 const x = @intCast(i16, int_val.toSignedInt(target));
483 const x = @intCast(i16, int_val.toSignedInt(mod));
484484 mem.writeInt(i16, try code.addManyAsArray(2), x, endian);
485485 } else if (info.bits <= 32) {
486 const x = @intCast(i32, int_val.toSignedInt(target));
486 const x = @intCast(i32, int_val.toSignedInt(mod));
487487 mem.writeInt(i32, try code.addManyAsArray(4), x, endian);
488488 } else {
489 const x = int_val.toSignedInt(target);
489 const x = int_val.toSignedInt(mod);
490490 mem.writeInt(i64, try code.addManyAsArray(8), x, endian);
491491 }
492492 },
......@@ -503,7 +503,7 @@ pub fn generateSymbol(
503503 const struct_obj = typed_value.ty.castTag(.@"struct").?.data;
504504 const fields = struct_obj.fields.values();
505505 const field_vals = typed_value.val.castTag(.aggregate).?.data;
506 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;
506 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
507507 const current_pos = code.items.len;
508508 try code.resize(current_pos + abi_size);
509509 var bits: u16 = 0;
......@@ -512,8 +512,8 @@ pub fn generateSymbol(
512512 const field_ty = fields[index].ty;
513513 // pointer may point to a decl which must be marked used
514514 // but can also result in a relocation. Therefore we handle those seperately.
515 if (field_ty.zigTypeTag() == .Pointer) {
516 const field_size = math.cast(usize, field_ty.abiSize(target)) orelse return error.Overflow;
515 if (field_ty.zigTypeTag(mod) == .Pointer) {
516 const field_size = math.cast(usize, field_ty.abiSize(mod)) orelse return error.Overflow;
517517 var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);
518518 defer tmp_list.deinit();
519519 switch (try generateSymbol(bin_file, src_loc, .{
......@@ -526,7 +526,7 @@ pub fn generateSymbol(
526526 } else {
527527 field_val.writeToPackedMemory(field_ty, mod, code.items[current_pos..], bits) catch unreachable;
528528 }
529 bits += @intCast(u16, field_ty.bitSize(target));
529 bits += @intCast(u16, field_ty.bitSize(mod));
530530 }
531531
532532 return Result.ok;
......@@ -536,7 +536,7 @@ pub fn generateSymbol(
536536 const field_vals = typed_value.val.castTag(.aggregate).?.data;
537537 for (field_vals, 0..) |field_val, index| {
538538 const field_ty = typed_value.ty.structFieldType(index);
539 if (!field_ty.hasRuntimeBits()) continue;
539 if (!field_ty.hasRuntimeBits(mod)) continue;
540540
541541 switch (try generateSymbol(bin_file, src_loc, .{
542542 .ty = field_ty,
......@@ -548,7 +548,7 @@ pub fn generateSymbol(
548548 const unpadded_field_end = code.items.len - struct_begin;
549549
550550 // Pad struct members if required
551 const padded_field_end = typed_value.ty.structFieldOffset(index + 1, target);
551 const padded_field_end = typed_value.ty.structFieldOffset(index + 1, mod);
552552 const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse return error.Overflow;
553553
554554 if (padding > 0) {
......@@ -560,7 +560,7 @@ pub fn generateSymbol(
560560 },
561561 .Union => {
562562 const union_obj = typed_value.val.castTag(.@"union").?.data;
563 const layout = typed_value.ty.unionGetLayout(target);
563 const layout = typed_value.ty.unionGetLayout(mod);
564564
565565 if (layout.payload_size == 0) {
566566 return generateSymbol(bin_file, src_loc, .{
......@@ -584,7 +584,7 @@ pub fn generateSymbol(
584584 const field_index = typed_value.ty.unionTagFieldIndex(union_obj.tag, mod).?;
585585 assert(union_ty.haveFieldTypes());
586586 const field_ty = union_ty.fields.values()[field_index].ty;
587 if (!field_ty.hasRuntimeBits()) {
587 if (!field_ty.hasRuntimeBits(mod)) {
588588 try code.writer().writeByteNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
589589 } else {
590590 switch (try generateSymbol(bin_file, src_loc, .{
......@@ -595,7 +595,7 @@ pub fn generateSymbol(
595595 .fail => |em| return Result{ .fail = em },
596596 }
597597
598 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(target)) orelse return error.Overflow;
598 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(mod)) orelse return error.Overflow;
599599 if (padding > 0) {
600600 try code.writer().writeByteNTimes(0, padding);
601601 }
......@@ -620,15 +620,15 @@ pub fn generateSymbol(
620620 .Optional => {
621621 var opt_buf: Type.Payload.ElemType = undefined;
622622 const payload_type = typed_value.ty.optionalChild(&opt_buf);
623 const is_pl = !typed_value.val.isNull();
624 const abi_size = math.cast(usize, typed_value.ty.abiSize(target)) orelse return error.Overflow;
623 const is_pl = !typed_value.val.isNull(mod);
624 const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow;
625625
626 if (!payload_type.hasRuntimeBits()) {
626 if (!payload_type.hasRuntimeBits(mod)) {
627627 try code.writer().writeByteNTimes(@boolToInt(is_pl), abi_size);
628628 return Result.ok;
629629 }
630630
631 if (typed_value.ty.optionalReprIsPayload()) {
631 if (typed_value.ty.optionalReprIsPayload(mod)) {
632632 if (typed_value.val.castTag(.opt_payload)) |payload| {
633633 switch (try generateSymbol(bin_file, src_loc, .{
634634 .ty = payload_type,
......@@ -637,7 +637,7 @@ pub fn generateSymbol(
637637 .ok => {},
638638 .fail => |em| return Result{ .fail = em },
639639 }
640 } else if (!typed_value.val.isNull()) {
640 } else if (!typed_value.val.isNull(mod)) {
641641 switch (try generateSymbol(bin_file, src_loc, .{
642642 .ty = payload_type,
643643 .val = typed_value.val,
......@@ -652,7 +652,7 @@ pub fn generateSymbol(
652652 return Result.ok;
653653 }
654654
655 const padding = abi_size - (math.cast(usize, payload_type.abiSize(target)) orelse return error.Overflow) - 1;
655 const padding = abi_size - (math.cast(usize, payload_type.abiSize(mod)) orelse return error.Overflow) - 1;
656656 const value = if (typed_value.val.castTag(.opt_payload)) |payload| payload.data else Value.initTag(.undef);
657657 switch (try generateSymbol(bin_file, src_loc, .{
658658 .ty = payload_type,
......@@ -671,7 +671,7 @@ pub fn generateSymbol(
671671 const payload_ty = typed_value.ty.errorUnionPayload();
672672 const is_payload = typed_value.val.errorUnionIsPayload();
673673
674 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
674 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
675675 const err_val = if (is_payload) Value.initTag(.zero) else typed_value.val;
676676 return generateSymbol(bin_file, src_loc, .{
677677 .ty = error_ty,
......@@ -679,9 +679,9 @@ pub fn generateSymbol(
679679 }, code, debug_output, reloc_info);
680680 }
681681
682 const payload_align = payload_ty.abiAlignment(target);
683 const error_align = Type.anyerror.abiAlignment(target);
684 const abi_align = typed_value.ty.abiAlignment(target);
682 const payload_align = payload_ty.abiAlignment(mod);
683 const error_align = Type.anyerror.abiAlignment(mod);
684 const abi_align = typed_value.ty.abiAlignment(mod);
685685
686686 // error value first when its type is larger than the error union's payload
687687 if (error_align > payload_align) {
......@@ -743,7 +743,7 @@ pub fn generateSymbol(
743743 try code.writer().writeInt(u32, kv.value, endian);
744744 },
745745 else => {
746 try code.writer().writeByteNTimes(0, @intCast(usize, Type.anyerror.abiSize(target)));
746 try code.writer().writeByteNTimes(0, @intCast(usize, Type.anyerror.abiSize(mod)));
747747 },
748748 }
749749 return Result.ok;
......@@ -752,7 +752,7 @@ pub fn generateSymbol(
752752 .bytes => {
753753 const bytes = typed_value.val.castTag(.bytes).?.data;
754754 const len = math.cast(usize, typed_value.ty.arrayLen()) orelse return error.Overflow;
755 const padding = math.cast(usize, typed_value.ty.abiSize(target) - len) orelse
755 const padding = math.cast(usize, typed_value.ty.abiSize(mod) - len) orelse
756756 return error.Overflow;
757757 try code.ensureUnusedCapacity(len + padding);
758758 code.appendSliceAssumeCapacity(bytes[0..len]);
......@@ -763,8 +763,8 @@ pub fn generateSymbol(
763763 const elem_vals = typed_value.val.castTag(.aggregate).?.data;
764764 const elem_ty = typed_value.ty.elemType();
765765 const len = math.cast(usize, typed_value.ty.arrayLen()) orelse return error.Overflow;
766 const padding = math.cast(usize, typed_value.ty.abiSize(target) -
767 (math.divCeil(u64, elem_ty.bitSize(target) * len, 8) catch |err| switch (err) {
766 const padding = math.cast(usize, typed_value.ty.abiSize(mod) -
767 (math.divCeil(u64, elem_ty.bitSize(mod) * len, 8) catch |err| switch (err) {
768768 error.DivisionByZero => unreachable,
769769 else => |e| return e,
770770 })) orelse return error.Overflow;
......@@ -784,8 +784,8 @@ pub fn generateSymbol(
784784 const array = typed_value.val.castTag(.repeated).?.data;
785785 const elem_ty = typed_value.ty.childType();
786786 const len = typed_value.ty.arrayLen();
787 const padding = math.cast(usize, typed_value.ty.abiSize(target) -
788 (math.divCeil(u64, elem_ty.bitSize(target) * len, 8) catch |err| switch (err) {
787 const padding = math.cast(usize, typed_value.ty.abiSize(mod) -
788 (math.divCeil(u64, elem_ty.bitSize(mod) * len, 8) catch |err| switch (err) {
789789 error.DivisionByZero => unreachable,
790790 else => |e| return e,
791791 })) orelse return error.Overflow;
......@@ -805,7 +805,7 @@ pub fn generateSymbol(
805805 .str_lit => {
806806 const str_lit = typed_value.val.castTag(.str_lit).?.data;
807807 const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
808 const padding = math.cast(usize, typed_value.ty.abiSize(target) - str_lit.len) orelse
808 const padding = math.cast(usize, typed_value.ty.abiSize(mod) - str_lit.len) orelse
809809 return error.Overflow;
810810 try code.ensureUnusedCapacity(str_lit.len + padding);
811811 code.appendSliceAssumeCapacity(bytes);
......@@ -832,7 +832,7 @@ fn lowerParentPtr(
832832 debug_output: DebugInfoOutput,
833833 reloc_info: RelocInfo,
834834) CodeGenError!Result {
835 const target = bin_file.options.target;
835 const mod = bin_file.options.module.?;
836836 switch (parent_ptr.tag()) {
837837 .field_ptr => {
838838 const field_ptr = parent_ptr.castTag(.field_ptr).?.data;
......@@ -843,19 +843,19 @@ fn lowerParentPtr(
843843 field_ptr.container_ptr,
844844 code,
845845 debug_output,
846 reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag()) {
846 reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag(mod)) {
847847 .Pointer => offset: {
848848 assert(field_ptr.container_ty.isSlice());
849849 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
850850 break :offset switch (field_ptr.field_index) {
851851 0 => 0,
852 1 => field_ptr.container_ty.slicePtrFieldType(&buf).abiSize(target),
852 1 => field_ptr.container_ty.slicePtrFieldType(&buf).abiSize(mod),
853853 else => unreachable,
854854 };
855855 },
856856 .Struct, .Union => field_ptr.container_ty.structFieldOffset(
857857 field_ptr.field_index,
858 target,
858 mod,
859859 ),
860860 else => return Result{ .fail = try ErrorMsg.create(
861861 bin_file.allocator,
......@@ -875,7 +875,7 @@ fn lowerParentPtr(
875875 elem_ptr.array_ptr,
876876 code,
877877 debug_output,
878 reloc_info.offset(@intCast(u32, elem_ptr.index * elem_ptr.elem_ty.abiSize(target))),
878 reloc_info.offset(@intCast(u32, elem_ptr.index * elem_ptr.elem_ty.abiSize(mod))),
879879 );
880880 },
881881 .opt_payload_ptr => {
......@@ -900,7 +900,7 @@ fn lowerParentPtr(
900900 eu_payload_ptr.container_ptr,
901901 code,
902902 debug_output,
903 reloc_info.offset(@intCast(u32, errUnionPayloadOffset(pl_ty, target))),
903 reloc_info.offset(@intCast(u32, errUnionPayloadOffset(pl_ty, mod))),
904904 );
905905 },
906906 .variable, .decl_ref, .decl_ref_mut => |tag| return lowerDeclRef(
......@@ -945,7 +945,7 @@ fn lowerDeclRef(
945945 reloc_info: RelocInfo,
946946) CodeGenError!Result {
947947 const target = bin_file.options.target;
948 const module = bin_file.options.module.?;
948 const mod = bin_file.options.module.?;
949949 if (typed_value.ty.isSlice()) {
950950 // generate ptr
951951 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
......@@ -961,7 +961,7 @@ fn lowerDeclRef(
961961 // generate length
962962 var slice_len: Value.Payload.U64 = .{
963963 .base = .{ .tag = .int_u64 },
964 .data = typed_value.val.sliceLen(module),
964 .data = typed_value.val.sliceLen(mod),
965965 };
966966 switch (try generateSymbol(bin_file, src_loc, .{
967967 .ty = Type.usize,
......@@ -975,14 +975,14 @@ fn lowerDeclRef(
975975 }
976976
977977 const ptr_width = target.ptrBitWidth();
978 const decl = module.declPtr(decl_index);
979 const is_fn_body = decl.ty.zigTypeTag() == .Fn;
980 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {
978 const decl = mod.declPtr(decl_index);
979 const is_fn_body = decl.ty.zigTypeTag(mod) == .Fn;
980 if (!is_fn_body and !decl.ty.hasRuntimeBits(mod)) {
981981 try code.writer().writeByteNTimes(0xaa, @divExact(ptr_width, 8));
982982 return Result.ok;
983983 }
984984
985 module.markDeclAlive(decl);
985 mod.markDeclAlive(decl);
986986
987987 const vaddr = try bin_file.getDeclVAddr(decl_index, .{
988988 .parent_atom_index = reloc_info.parent_atom_index,
......@@ -1059,16 +1059,16 @@ fn genDeclRef(
10591059 tv: TypedValue,
10601060 decl_index: Module.Decl.Index,
10611061) CodeGenError!GenResult {
1062 const module = bin_file.options.module.?;
1063 log.debug("genDeclRef: ty = {}, val = {}", .{ tv.ty.fmt(module), tv.val.fmtValue(tv.ty, module) });
1062 const mod = bin_file.options.module.?;
1063 log.debug("genDeclRef: ty = {}, val = {}", .{ tv.ty.fmt(mod), tv.val.fmtValue(tv.ty, mod) });
10641064
10651065 const target = bin_file.options.target;
10661066 const ptr_bits = target.ptrBitWidth();
10671067 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
10681068
1069 const decl = module.declPtr(decl_index);
1069 const decl = mod.declPtr(decl_index);
10701070
1071 if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime()) {
1071 if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
10721072 const imm: u64 = switch (ptr_bytes) {
10731073 1 => 0xaa,
10741074 2 => 0xaaaa,
......@@ -1080,20 +1080,20 @@ fn genDeclRef(
10801080 }
10811081
10821082 // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
1083 if (tv.ty.castPtrToFn()) |fn_ty| {
1083 if (tv.ty.castPtrToFn(mod)) |fn_ty| {
10841084 if (fn_ty.fnInfo().is_generic) {
1085 return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(target) });
1085 return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(mod) });
10861086 }
1087 } else if (tv.ty.zigTypeTag() == .Pointer) {
1088 const elem_ty = tv.ty.elemType2();
1089 if (!elem_ty.hasRuntimeBits()) {
1090 return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(target) });
1087 } else if (tv.ty.zigTypeTag(mod) == .Pointer) {
1088 const elem_ty = tv.ty.elemType2(mod);
1089 if (!elem_ty.hasRuntimeBits(mod)) {
1090 return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(mod) });
10911091 }
10921092 }
10931093
1094 module.markDeclAlive(decl);
1094 mod.markDeclAlive(decl);
10951095
1096 const is_threadlocal = tv.val.isPtrToThreadLocal(module) and !bin_file.options.single_threaded;
1096 const is_threadlocal = tv.val.isPtrToThreadLocal(mod) and !bin_file.options.single_threaded;
10971097
10981098 if (bin_file.cast(link.File.Elf)) |elf_file| {
10991099 const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index);
......@@ -1186,7 +1186,7 @@ pub fn genTypedValue(
11861186 }
11871187 }
11881188
1189 switch (typed_value.ty.zigTypeTag()) {
1189 switch (typed_value.ty.zigTypeTag(mod)) {
11901190 .Void => return GenResult.mcv(.none),
11911191 .Pointer => switch (typed_value.ty.ptrSize()) {
11921192 .Slice => {},
......@@ -1196,18 +1196,18 @@ pub fn genTypedValue(
11961196 return GenResult.mcv(.{ .immediate = 0 });
11971197 },
11981198 .int_u64 => {
1199 return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(target) });
1199 return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(mod) });
12001200 },
12011201 else => {},
12021202 }
12031203 },
12041204 },
12051205 .Int => {
1206 const info = typed_value.ty.intInfo(target);
1206 const info = typed_value.ty.intInfo(mod);
12071207 if (info.bits <= ptr_bits) {
12081208 const unsigned = switch (info.signedness) {
1209 .signed => @bitCast(u64, typed_value.val.toSignedInt(target)),
1210 .unsigned => typed_value.val.toUnsignedInt(target),
1209 .signed => @bitCast(u64, typed_value.val.toSignedInt(mod)),
1210 .unsigned => typed_value.val.toUnsignedInt(mod),
12111211 };
12121212 return GenResult.mcv(.{ .immediate = unsigned });
12131213 }
......@@ -1216,7 +1216,7 @@ pub fn genTypedValue(
12161216 return GenResult.mcv(.{ .immediate = @boolToInt(typed_value.val.toBool()) });
12171217 },
12181218 .Optional => {
1219 if (typed_value.ty.isPtrLikeOptional()) {
1219 if (typed_value.ty.isPtrLikeOptional(mod)) {
12201220 if (typed_value.val.tag() == .null_value) return GenResult.mcv(.{ .immediate = 0 });
12211221
12221222 var buf: Type.Payload.ElemType = undefined;
......@@ -1224,8 +1224,8 @@ pub fn genTypedValue(
12241224 .ty = typed_value.ty.optionalChild(&buf),
12251225 .val = if (typed_value.val.castTag(.opt_payload)) |pl| pl.data else typed_value.val,
12261226 }, owner_decl_index);
1227 } else if (typed_value.ty.abiSize(target) == 1) {
1228 return GenResult.mcv(.{ .immediate = @boolToInt(!typed_value.val.isNull()) });
1227 } else if (typed_value.ty.abiSize(mod) == 1) {
1228 return GenResult.mcv(.{ .immediate = @boolToInt(!typed_value.val.isNull(mod)) });
12291229 }
12301230 },
12311231 .Enum => {
......@@ -1241,9 +1241,8 @@ pub fn genTypedValue(
12411241 typed_value.ty.cast(Type.Payload.EnumFull).?.data.values;
12421242 if (enum_values.count() != 0) {
12431243 const tag_val = enum_values.keys()[field_index.data];
1244 var buf: Type.Payload.Bits = undefined;
12451244 return genTypedValue(bin_file, src_loc, .{
1246 .ty = typed_value.ty.intTagType(&buf),
1245 .ty = typed_value.ty.intTagType(),
12471246 .val = tag_val,
12481247 }, owner_decl_index);
12491248 } else {
......@@ -1253,8 +1252,7 @@ pub fn genTypedValue(
12531252 else => unreachable,
12541253 }
12551254 } else {
1256 var int_tag_buffer: Type.Payload.Bits = undefined;
1257 const int_tag_ty = typed_value.ty.intTagType(&int_tag_buffer);
1255 const int_tag_ty = typed_value.ty.intTagType();
12581256 return genTypedValue(bin_file, src_loc, .{
12591257 .ty = int_tag_ty,
12601258 .val = typed_value.val,
......@@ -1281,7 +1279,7 @@ pub fn genTypedValue(
12811279 const payload_type = typed_value.ty.errorUnionPayload();
12821280 const is_pl = typed_value.val.errorUnionIsPayload();
12831281
1284 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {
1282 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
12851283 // We use the error type directly as the type.
12861284 const err_val = if (!is_pl) typed_value.val else Value.initTag(.zero);
12871285 return genTypedValue(bin_file, src_loc, .{
......@@ -1306,23 +1304,23 @@ pub fn genTypedValue(
13061304 return genUnnamedConst(bin_file, src_loc, typed_value, owner_decl_index);
13071305}
13081306
1309pub fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u64 {
1310 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return 0;
1311 const payload_align = payload_ty.abiAlignment(target);
1312 const error_align = Type.anyerror.abiAlignment(target);
1313 if (payload_align >= error_align or !payload_ty.hasRuntimeBitsIgnoreComptime()) {
1307pub fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u64 {
1308 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0;
1309 const payload_align = payload_ty.abiAlignment(mod);
1310 const error_align = Type.anyerror.abiAlignment(mod);
1311 if (payload_align >= error_align or !payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
13141312 return 0;
13151313 } else {
1316 return mem.alignForwardGeneric(u64, Type.anyerror.abiSize(target), payload_align);
1314 return mem.alignForwardGeneric(u64, Type.anyerror.abiSize(mod), payload_align);
13171315 }
13181316}
13191317
1320pub fn errUnionErrorOffset(payload_ty: Type, target: std.Target) u64 {
1321 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return 0;
1322 const payload_align = payload_ty.abiAlignment(target);
1323 const error_align = Type.anyerror.abiAlignment(target);
1324 if (payload_align >= error_align and payload_ty.hasRuntimeBitsIgnoreComptime()) {
1325 return mem.alignForwardGeneric(u64, payload_ty.abiSize(target), error_align);
1318pub fn errUnionErrorOffset(payload_ty: Type, mod: *const Module) u64 {
1319 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return 0;
1320 const payload_align = payload_ty.abiAlignment(mod);
1321 const error_align = Type.anyerror.abiAlignment(mod);
1322 if (payload_align >= error_align and payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1323 return mem.alignForwardGeneric(u64, payload_ty.abiSize(mod), error_align);
13261324 } else {
13271325 return 0;
13281326 }
src/codegen/c.zig+368-359
......@@ -16,6 +16,7 @@ const trace = @import("../tracy.zig").trace;
1616const LazySrcLoc = Module.LazySrcLoc;
1717const Air = @import("../Air.zig");
1818const Liveness = @import("../Liveness.zig");
19const InternPool = @import("../InternPool.zig");
1920
2021const BigIntLimb = std.math.big.Limb;
2122const BigInt = std.math.big.int;
......@@ -285,10 +286,11 @@ pub const Function = struct {
285286 const gop = try f.value_map.getOrPut(inst);
286287 if (gop.found_existing) return gop.value_ptr.*;
287288
288 const val = f.air.value(ref).?;
289 const mod = f.object.dg.module;
290 const val = f.air.value(ref, mod).?;
289291 const ty = f.air.typeOf(ref);
290292
291 const result: CValue = if (lowersToArray(ty, f.object.dg.module.getTarget())) result: {
293 const result: CValue = if (lowersToArray(ty, mod)) result: {
292294 const writer = f.object.code_header.writer();
293295 const alignment = 0;
294296 const decl_c_value = try f.allocLocalValue(ty, alignment);
......@@ -318,11 +320,11 @@ pub const Function = struct {
318320 /// those which go into `allocs`. This function does not add the resulting local into `allocs`;
319321 /// that responsibility lies with the caller.
320322 fn allocLocalValue(f: *Function, ty: Type, alignment: u32) !CValue {
323 const mod = f.object.dg.module;
321324 const gpa = f.object.dg.gpa;
322 const target = f.object.dg.module.getTarget();
323325 try f.locals.append(gpa, .{
324326 .cty_idx = try f.typeToIndex(ty, .complete),
325 .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(target)),
327 .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(mod)),
326328 });
327329 return .{ .new_local = @intCast(LocalIndex, f.locals.items.len - 1) };
328330 }
......@@ -336,10 +338,10 @@ pub const Function = struct {
336338 /// Only allocates the local; does not print anything. Will attempt to re-use locals, so should
337339 /// not be used for persistent locals (i.e. those in `allocs`).
338340 fn allocAlignedLocal(f: *Function, ty: Type, _: CQualifiers, alignment: u32) !CValue {
339 const target = f.object.dg.module.getTarget();
341 const mod = f.object.dg.module;
340342 if (f.free_locals_map.getPtr(.{
341343 .cty_idx = try f.typeToIndex(ty, .complete),
342 .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(target)),
344 .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(mod)),
343345 })) |locals_list| {
344346 if (locals_list.popOrNull()) |local_entry| {
345347 return .{ .new_local = local_entry.key };
......@@ -352,8 +354,9 @@ pub const Function = struct {
352354 fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void {
353355 switch (c_value) {
354356 .constant => |inst| {
357 const mod = f.object.dg.module;
355358 const ty = f.air.typeOf(inst);
356 const val = f.air.value(inst).?;
359 const val = f.air.value(inst, mod).?;
357360 return f.object.dg.renderValue(w, ty, val, location);
358361 },
359362 .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location),
......@@ -364,8 +367,9 @@ pub const Function = struct {
364367 fn writeCValueDeref(f: *Function, w: anytype, c_value: CValue) !void {
365368 switch (c_value) {
366369 .constant => |inst| {
370 const mod = f.object.dg.module;
367371 const ty = f.air.typeOf(inst);
368 const val = f.air.value(inst).?;
372 const val = f.air.value(inst, mod).?;
369373 try w.writeAll("(*");
370374 try f.object.dg.renderValue(w, ty, val, .Other);
371375 return w.writeByte(')');
......@@ -377,8 +381,9 @@ pub const Function = struct {
377381 fn writeCValueMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void {
378382 switch (c_value) {
379383 .constant => |inst| {
384 const mod = f.object.dg.module;
380385 const ty = f.air.typeOf(inst);
381 const val = f.air.value(inst).?;
386 const val = f.air.value(inst, mod).?;
382387 try f.object.dg.renderValue(w, ty, val, .Other);
383388 try w.writeByte('.');
384389 return f.writeCValue(w, member, .Other);
......@@ -390,8 +395,9 @@ pub const Function = struct {
390395 fn writeCValueDerefMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void {
391396 switch (c_value) {
392397 .constant => |inst| {
398 const mod = f.object.dg.module;
393399 const ty = f.air.typeOf(inst);
394 const val = f.air.value(inst).?;
400 const val = f.air.value(inst, mod).?;
395401 try w.writeByte('(');
396402 try f.object.dg.renderValue(w, ty, val, .Other);
397403 try w.writeAll(")->");
......@@ -522,11 +528,12 @@ pub const DeclGen = struct {
522528 decl_index: Decl.Index,
523529 location: ValueRenderLocation,
524530 ) error{ OutOfMemory, AnalysisFail }!void {
525 const decl = dg.module.declPtr(decl_index);
531 const mod = dg.module;
532 const decl = mod.declPtr(decl_index);
526533 assert(decl.has_tv);
527534
528535 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
529 if (ty.isPtrAtRuntime() and !decl.ty.isFnOrHasRuntimeBits()) {
536 if (ty.isPtrAtRuntime(mod) and !decl.ty.isFnOrHasRuntimeBits(mod)) {
530537 return dg.writeCValue(writer, .{ .undef = ty });
531538 }
532539
......@@ -553,7 +560,7 @@ pub const DeclGen = struct {
553560
554561 var len_pl: Value.Payload.U64 = .{
555562 .base = .{ .tag = .int_u64 },
556 .data = val.sliceLen(dg.module),
563 .data = val.sliceLen(mod),
557564 };
558565 const len_val = Value.initPayload(&len_pl.base);
559566
......@@ -568,7 +575,7 @@ pub const DeclGen = struct {
568575 // them). The analysis until now should ensure that the C function
569576 // pointers are compatible. If they are not, then there is a bug
570577 // somewhere and we should let the C compiler tell us about it.
571 const need_typecast = if (ty.castPtrToFn()) |_| false else !ty.eql(decl.ty, dg.module);
578 const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.eql(decl.ty, mod);
572579 if (need_typecast) {
573580 try writer.writeAll("((");
574581 try dg.renderType(writer, ty);
......@@ -584,6 +591,8 @@ pub const DeclGen = struct {
584591 //
585592 // Used for .elem_ptr, .field_ptr, .opt_payload_ptr, .eu_payload_ptr
586593 fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type, location: ValueRenderLocation) error{ OutOfMemory, AnalysisFail }!void {
594 const mod = dg.module;
595
587596 if (!ptr_ty.isSlice()) {
588597 try writer.writeByte('(');
589598 try dg.renderType(writer, ptr_ty);
......@@ -601,7 +610,6 @@ pub const DeclGen = struct {
601610 try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index, location);
602611 },
603612 .field_ptr => {
604 const target = dg.module.getTarget();
605613 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
606614
607615 // Ensure complete type definition is visible before accessing fields.
......@@ -615,7 +623,7 @@ pub const DeclGen = struct {
615623 field_ptr.container_ty,
616624 ptr_ty,
617625 @intCast(u32, field_ptr.field_index),
618 target,
626 mod,
619627 )) {
620628 .begin => try dg.renderParentPtr(
621629 writer,
......@@ -714,19 +722,20 @@ pub const DeclGen = struct {
714722 if (val.castTag(.runtime_value)) |rt| {
715723 val = rt.data;
716724 }
717 const target = dg.module.getTarget();
725 const mod = dg.module;
726 const target = mod.getTarget();
718727 const initializer_type: ValueRenderLocation = switch (location) {
719728 .StaticInitializer => .StaticInitializer,
720729 else => .Initializer,
721730 };
722731
723 const safety_on = switch (dg.module.optimizeMode()) {
732 const safety_on = switch (mod.optimizeMode()) {
724733 .Debug, .ReleaseSafe => true,
725734 .ReleaseFast, .ReleaseSmall => false,
726735 };
727736
728737 if (val.isUndefDeep()) {
729 switch (ty.zigTypeTag()) {
738 switch (ty.zigTypeTag(mod)) {
730739 .Bool => {
731740 if (safety_on) {
732741 return writer.writeAll("0xaa");
......@@ -737,8 +746,8 @@ pub const DeclGen = struct {
737746 .Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val, location)}),
738747 .Float => {
739748 const bits = ty.floatBits(target);
740 var repr_pl = Type.Payload.Bits{ .base = .{ .tag = .int_unsigned }, .data = bits };
741 const repr_ty = Type.initPayload(&repr_pl.base);
749 // All unsigned ints matching float types are pre-allocated.
750 const repr_ty = mod.intType(.unsigned, bits) catch unreachable;
742751
743752 try writer.writeAll("zig_cast_");
744753 try dg.renderTypeForBuiltinFnName(writer, ty);
......@@ -778,11 +787,11 @@ pub const DeclGen = struct {
778787 var opt_buf: Type.Payload.ElemType = undefined;
779788 const payload_ty = ty.optionalChild(&opt_buf);
780789
781 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
790 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
782791 return dg.renderValue(writer, Type.bool, val, location);
783792 }
784793
785 if (ty.optionalReprIsPayload()) {
794 if (ty.optionalReprIsPayload(mod)) {
786795 return dg.renderValue(writer, payload_ty, val, location);
787796 }
788797
......@@ -811,7 +820,7 @@ pub const DeclGen = struct {
811820 for (0..ty.structFieldCount()) |field_i| {
812821 if (ty.structFieldIsComptime(field_i)) continue;
813822 const field_ty = ty.structFieldType(field_i);
814 if (!field_ty.hasRuntimeBits()) continue;
823 if (!field_ty.hasRuntimeBits(mod)) continue;
815824
816825 if (!empty) try writer.writeByte(',');
817826 try dg.renderValue(writer, field_ty, val, initializer_type);
......@@ -832,17 +841,17 @@ pub const DeclGen = struct {
832841
833842 try writer.writeByte('{');
834843 if (ty.unionTagTypeSafety()) |tag_ty| {
835 const layout = ty.unionGetLayout(target);
844 const layout = ty.unionGetLayout(mod);
836845 if (layout.tag_size != 0) {
837846 try writer.writeAll(" .tag = ");
838847 try dg.renderValue(writer, tag_ty, val, initializer_type);
839848 }
840 if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}');
849 if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}');
841850 if (layout.tag_size != 0) try writer.writeByte(',');
842851 try writer.writeAll(" .payload = {");
843852 }
844853 for (ty.unionFields().values()) |field| {
845 if (!field.ty.hasRuntimeBits()) continue;
854 if (!field.ty.hasRuntimeBits(mod)) continue;
846855 try dg.renderValue(writer, field.ty, val, initializer_type);
847856 break;
848857 }
......@@ -853,7 +862,7 @@ pub const DeclGen = struct {
853862 const payload_ty = ty.errorUnionPayload();
854863 const error_ty = ty.errorUnionSet();
855864
856 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
865 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
857866 return dg.renderValue(writer, error_ty, val, location);
858867 }
859868
......@@ -916,7 +925,7 @@ pub const DeclGen = struct {
916925 }
917926 unreachable;
918927 }
919 switch (ty.zigTypeTag()) {
928 switch (ty.zigTypeTag(mod)) {
920929 .Int => switch (val.tag()) {
921930 .field_ptr,
922931 .elem_ptr,
......@@ -931,8 +940,8 @@ pub const DeclGen = struct {
931940 const bits = ty.floatBits(target);
932941 const f128_val = val.toFloat(f128);
933942
934 var repr_ty_pl = Type.Payload.Bits{ .base = .{ .tag = .int_unsigned }, .data = bits };
935 const repr_ty = Type.initPayload(&repr_ty_pl.base);
943 // All unsigned ints matching float types are pre-allocated.
944 const repr_ty = mod.intType(.unsigned, bits) catch unreachable;
936945
937946 assert(bits <= 128);
938947 var repr_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined;
......@@ -1109,7 +1118,7 @@ pub const DeclGen = struct {
11091118 },
11101119 else => unreachable,
11111120 };
1112 const sentinel = if (ty.sentinel()) |sentinel| @intCast(u8, sentinel.toUnsignedInt(target)) else null;
1121 const sentinel = if (ty.sentinel()) |sentinel| @intCast(u8, sentinel.toUnsignedInt(mod)) else null;
11131122 try writer.print("{s}", .{
11141123 fmtStringLiteral(bytes[0..@intCast(usize, ty.arrayLen())], sentinel),
11151124 });
......@@ -1131,11 +1140,11 @@ pub const DeclGen = struct {
11311140 var index: usize = 0;
11321141 while (index < ai.len) : (index += 1) {
11331142 const elem_val = try val.elemValue(dg.module, arena_allocator, index);
1134 const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(target));
1143 const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
11351144 try literal.writeChar(elem_val_u8);
11361145 }
11371146 if (ai.sentinel) |s| {
1138 const s_u8 = @intCast(u8, s.toUnsignedInt(target));
1147 const s_u8 = @intCast(u8, s.toUnsignedInt(mod));
11391148 if (s_u8 != 0) try literal.writeChar(s_u8);
11401149 }
11411150 try literal.end();
......@@ -1145,7 +1154,7 @@ pub const DeclGen = struct {
11451154 while (index < ai.len) : (index += 1) {
11461155 if (index != 0) try writer.writeByte(',');
11471156 const elem_val = try val.elemValue(dg.module, arena_allocator, index);
1148 const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(target));
1157 const elem_val_u8 = if (elem_val.isUndef()) undefPattern(u8) else @intCast(u8, elem_val.toUnsignedInt(mod));
11491158 try writer.print("'\\x{x}'", .{elem_val_u8});
11501159 }
11511160 if (ai.sentinel) |s| {
......@@ -1183,10 +1192,10 @@ pub const DeclGen = struct {
11831192 const payload_ty = ty.optionalChild(&opt_buf);
11841193
11851194 const is_null_val = Value.makeBool(val.tag() == .null_value);
1186 if (!payload_ty.hasRuntimeBitsIgnoreComptime())
1195 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
11871196 return dg.renderValue(writer, Type.bool, is_null_val, location);
11881197
1189 if (ty.optionalReprIsPayload()) {
1198 if (ty.optionalReprIsPayload(mod)) {
11901199 const payload_val = if (val.castTag(.opt_payload)) |pl| pl.data else val;
11911200 return dg.renderValue(writer, payload_ty, payload_val, location);
11921201 }
......@@ -1218,7 +1227,7 @@ pub const DeclGen = struct {
12181227 const error_ty = ty.errorUnionSet();
12191228 const error_val = if (val.errorUnionIsPayload()) Value.zero else val;
12201229
1221 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1230 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
12221231 return dg.renderValue(writer, error_ty, error_val, location);
12231232 }
12241233
......@@ -1263,8 +1272,7 @@ pub const DeclGen = struct {
12631272 }
12641273 },
12651274 else => {
1266 var int_tag_ty_buffer: Type.Payload.Bits = undefined;
1267 const int_tag_ty = ty.intTagType(&int_tag_ty_buffer);
1275 const int_tag_ty = ty.intTagType();
12681276 return dg.renderValue(writer, int_tag_ty, val, location);
12691277 },
12701278 }
......@@ -1295,7 +1303,7 @@ pub const DeclGen = struct {
12951303 for (field_vals, 0..) |field_val, field_i| {
12961304 if (ty.structFieldIsComptime(field_i)) continue;
12971305 const field_ty = ty.structFieldType(field_i);
1298 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
1306 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
12991307
13001308 if (!empty) try writer.writeByte(',');
13011309 try dg.renderValue(writer, field_ty, field_val, initializer_type);
......@@ -1306,13 +1314,10 @@ pub const DeclGen = struct {
13061314 },
13071315 .Packed => {
13081316 const field_vals = val.castTag(.aggregate).?.data;
1309 const int_info = ty.intInfo(target);
1317 const int_info = ty.intInfo(mod);
13101318
1311 var bit_offset_ty_pl = Type.Payload.Bits{
1312 .base = .{ .tag = .int_unsigned },
1313 .data = Type.smallestUnsignedBits(int_info.bits - 1),
1314 };
1315 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
1319 const bits = Type.smallestUnsignedBits(int_info.bits - 1);
1320 const bit_offset_ty = try mod.intType(.unsigned, bits);
13161321
13171322 var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 };
13181323 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
......@@ -1321,7 +1326,7 @@ pub const DeclGen = struct {
13211326 for (0..field_vals.len) |field_i| {
13221327 if (ty.structFieldIsComptime(field_i)) continue;
13231328 const field_ty = ty.structFieldType(field_i);
1324 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
1329 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
13251330
13261331 eff_num_fields += 1;
13271332 }
......@@ -1330,7 +1335,7 @@ pub const DeclGen = struct {
13301335 try writer.writeByte('(');
13311336 try dg.renderValue(writer, ty, Value.undef, initializer_type);
13321337 try writer.writeByte(')');
1333 } else if (ty.bitSize(target) > 64) {
1338 } else if (ty.bitSize(mod) > 64) {
13341339 // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))
13351340 var num_or = eff_num_fields - 1;
13361341 while (num_or > 0) : (num_or -= 1) {
......@@ -1344,7 +1349,7 @@ pub const DeclGen = struct {
13441349 for (field_vals, 0..) |field_val, field_i| {
13451350 if (ty.structFieldIsComptime(field_i)) continue;
13461351 const field_ty = ty.structFieldType(field_i);
1347 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
1352 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
13481353
13491354 const cast_context = IntCastContext{ .value = .{ .value = field_val } };
13501355 if (bit_offset_val_pl.data != 0) {
......@@ -1362,7 +1367,7 @@ pub const DeclGen = struct {
13621367 if (needs_closing_paren) try writer.writeByte(')');
13631368 if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");
13641369
1365 bit_offset_val_pl.data += field_ty.bitSize(target);
1370 bit_offset_val_pl.data += field_ty.bitSize(mod);
13661371 needs_closing_paren = true;
13671372 eff_index += 1;
13681373 }
......@@ -1373,7 +1378,7 @@ pub const DeclGen = struct {
13731378 for (field_vals, 0..) |field_val, field_i| {
13741379 if (ty.structFieldIsComptime(field_i)) continue;
13751380 const field_ty = ty.structFieldType(field_i);
1376 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
1381 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
13771382
13781383 if (!empty) try writer.writeAll(" | ");
13791384 try writer.writeByte('(');
......@@ -1388,7 +1393,7 @@ pub const DeclGen = struct {
13881393 try dg.renderValue(writer, field_ty, field_val, .Other);
13891394 }
13901395
1391 bit_offset_val_pl.data += field_ty.bitSize(target);
1396 bit_offset_val_pl.data += field_ty.bitSize(mod);
13921397 empty = false;
13931398 }
13941399 try writer.writeByte(')');
......@@ -1408,12 +1413,12 @@ pub const DeclGen = struct {
14081413 const field_ty = ty.unionFields().values()[field_i].ty;
14091414 const field_name = ty.unionFields().keys()[field_i];
14101415 if (ty.containerLayout() == .Packed) {
1411 if (field_ty.hasRuntimeBits()) {
1412 if (field_ty.isPtrAtRuntime()) {
1416 if (field_ty.hasRuntimeBits(mod)) {
1417 if (field_ty.isPtrAtRuntime(mod)) {
14131418 try writer.writeByte('(');
14141419 try dg.renderType(writer, ty);
14151420 try writer.writeByte(')');
1416 } else if (field_ty.zigTypeTag() == .Float) {
1421 } else if (field_ty.zigTypeTag(mod) == .Float) {
14171422 try writer.writeByte('(');
14181423 try dg.renderType(writer, ty);
14191424 try writer.writeByte(')');
......@@ -1427,21 +1432,21 @@ pub const DeclGen = struct {
14271432
14281433 try writer.writeByte('{');
14291434 if (ty.unionTagTypeSafety()) |tag_ty| {
1430 const layout = ty.unionGetLayout(target);
1435 const layout = ty.unionGetLayout(mod);
14311436 if (layout.tag_size != 0) {
14321437 try writer.writeAll(" .tag = ");
14331438 try dg.renderValue(writer, tag_ty, union_obj.tag, initializer_type);
14341439 }
1435 if (ty.unionHasAllZeroBitFieldTypes()) return try writer.writeByte('}');
1440 if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}');
14361441 if (layout.tag_size != 0) try writer.writeByte(',');
14371442 try writer.writeAll(" .payload = {");
14381443 }
1439 if (field_ty.hasRuntimeBits()) {
1444 if (field_ty.hasRuntimeBits(mod)) {
14401445 try writer.print(" .{ } = ", .{fmtIdent(field_name)});
14411446 try dg.renderValue(writer, field_ty, union_obj.val, initializer_type);
14421447 try writer.writeByte(' ');
14431448 } else for (ty.unionFields().values()) |field| {
1444 if (!field.ty.hasRuntimeBits()) continue;
1449 if (!field.ty.hasRuntimeBits(mod)) continue;
14451450 try dg.renderValue(writer, field.ty, Value.undef, initializer_type);
14461451 break;
14471452 }
......@@ -1478,9 +1483,9 @@ pub const DeclGen = struct {
14781483 },
14791484 ) !void {
14801485 const store = &dg.ctypes.set;
1481 const module = dg.module;
1486 const mod = dg.module;
14821487
1483 const fn_decl = module.declPtr(fn_decl_index);
1488 const fn_decl = mod.declPtr(fn_decl_index);
14841489 const fn_cty_idx = try dg.typeToIndex(fn_decl.ty, kind);
14851490
14861491 const fn_info = fn_decl.ty.fnInfo();
......@@ -1498,7 +1503,7 @@ pub const DeclGen = struct {
14981503 const trailing = try renderTypePrefix(
14991504 dg.decl_index,
15001505 store.*,
1501 module,
1506 mod,
15021507 w,
15031508 fn_cty_idx,
15041509 .suffix,
......@@ -1525,7 +1530,7 @@ pub const DeclGen = struct {
15251530 try renderTypeSuffix(
15261531 dg.decl_index,
15271532 store.*,
1528 module,
1533 mod,
15291534 w,
15301535 fn_cty_idx,
15311536 .suffix,
......@@ -1577,9 +1582,9 @@ pub const DeclGen = struct {
15771582
15781583 fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void {
15791584 const store = &dg.ctypes.set;
1580 const module = dg.module;
1581 _ = try renderTypePrefix(dg.decl_index, store.*, module, w, idx, .suffix, .{});
1582 try renderTypeSuffix(dg.decl_index, store.*, module, w, idx, .suffix, .{});
1585 const mod = dg.module;
1586 _ = try renderTypePrefix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});
1587 try renderTypeSuffix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});
15831588 }
15841589
15851590 const IntCastContext = union(enum) {
......@@ -1619,18 +1624,18 @@ pub const DeclGen = struct {
16191624 /// | > 64 bit integer | < 64 bit integer | zig_make_<dest_ty>(0, src)
16201625 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
16211626 fn renderIntCast(dg: *DeclGen, w: anytype, dest_ty: Type, context: IntCastContext, src_ty: Type, location: ValueRenderLocation) !void {
1622 const target = dg.module.getTarget();
1623 const dest_bits = dest_ty.bitSize(target);
1624 const dest_int_info = dest_ty.intInfo(target);
1627 const mod = dg.module;
1628 const dest_bits = dest_ty.bitSize(mod);
1629 const dest_int_info = dest_ty.intInfo(mod);
16251630
1626 const src_is_ptr = src_ty.isPtrAtRuntime();
1631 const src_is_ptr = src_ty.isPtrAtRuntime(mod);
16271632 const src_eff_ty: Type = if (src_is_ptr) switch (dest_int_info.signedness) {
16281633 .unsigned => Type.usize,
16291634 .signed => Type.isize,
16301635 } else src_ty;
16311636
1632 const src_bits = src_eff_ty.bitSize(target);
1633 const src_int_info = if (src_eff_ty.isAbiInt()) src_eff_ty.intInfo(target) else null;
1637 const src_bits = src_eff_ty.bitSize(mod);
1638 const src_int_info = if (src_eff_ty.isAbiInt(mod)) src_eff_ty.intInfo(mod) else null;
16341639 if (dest_bits <= 64 and src_bits <= 64) {
16351640 const needs_cast = src_int_info == null or
16361641 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
......@@ -1703,8 +1708,8 @@ pub const DeclGen = struct {
17031708 alignment: u32,
17041709 kind: CType.Kind,
17051710 ) error{ OutOfMemory, AnalysisFail }!void {
1706 const target = dg.module.getTarget();
1707 const alignas = CType.AlignAs.init(alignment, ty.abiAlignment(target));
1711 const mod = dg.module;
1712 const alignas = CType.AlignAs.init(alignment, ty.abiAlignment(mod));
17081713 try dg.renderCTypeAndName(w, try dg.typeToIndex(ty, kind), name, qualifiers, alignas);
17091714 }
17101715
......@@ -1717,7 +1722,7 @@ pub const DeclGen = struct {
17171722 alignas: CType.AlignAs,
17181723 ) error{ OutOfMemory, AnalysisFail }!void {
17191724 const store = &dg.ctypes.set;
1720 const module = dg.module;
1725 const mod = dg.module;
17211726
17221727 switch (std.math.order(alignas.@"align", alignas.abi)) {
17231728 .lt => try w.print("zig_under_align({}) ", .{alignas.getAlign()}),
......@@ -1726,22 +1731,23 @@ pub const DeclGen = struct {
17261731 }
17271732
17281733 const trailing =
1729 try renderTypePrefix(dg.decl_index, store.*, module, w, cty_idx, .suffix, qualifiers);
1734 try renderTypePrefix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, qualifiers);
17301735 try w.print("{}", .{trailing});
17311736 try dg.writeCValue(w, name);
1732 try renderTypeSuffix(dg.decl_index, store.*, module, w, cty_idx, .suffix, .{});
1737 try renderTypeSuffix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, .{});
17331738 }
17341739
17351740 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {
1741 const mod = dg.module;
17361742 switch (tv.val.tag()) {
17371743 .extern_fn => return true,
17381744 .function => {
17391745 const func = tv.val.castTag(.function).?.data;
1740 return dg.module.decl_exports.contains(func.owner_decl);
1746 return mod.decl_exports.contains(func.owner_decl);
17411747 },
17421748 .variable => {
17431749 const variable = tv.val.castTag(.variable).?.data;
1744 return dg.module.decl_exports.contains(variable.owner_decl);
1750 return mod.decl_exports.contains(variable.owner_decl);
17451751 },
17461752 else => unreachable,
17471753 }
......@@ -1838,10 +1844,11 @@ pub const DeclGen = struct {
18381844 }
18391845
18401846 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index, export_index: u32) !void {
1841 const decl = dg.module.declPtr(decl_index);
1842 dg.module.markDeclAlive(decl);
1847 const mod = dg.module;
1848 const decl = mod.declPtr(decl_index);
1849 mod.markDeclAlive(decl);
18431850
1844 if (dg.module.decl_exports.get(decl_index)) |exports| {
1851 if (mod.decl_exports.get(decl_index)) |exports| {
18451852 try writer.writeAll(exports.items[export_index].options.name);
18461853 } else if (decl.isExtern()) {
18471854 try writer.writeAll(mem.span(decl.name));
......@@ -1850,7 +1857,7 @@ pub const DeclGen = struct {
18501857 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
18511858 var name: [100]u8 = undefined;
18521859 var name_stream = std.io.fixedBufferStream(&name);
1853 decl.renderFullyQualifiedName(dg.module, name_stream.writer()) catch |err| switch (err) {
1860 decl.renderFullyQualifiedName(mod, name_stream.writer()) catch |err| switch (err) {
18541861 error.NoSpaceLeft => {},
18551862 };
18561863 try writer.print("{}__{d}", .{
......@@ -1894,10 +1901,10 @@ pub const DeclGen = struct {
18941901 .bits => {},
18951902 }
18961903
1897 const target = dg.module.getTarget();
1898 const int_info = if (ty.isAbiInt()) ty.intInfo(target) else std.builtin.Type.Int{
1904 const mod = dg.module;
1905 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{
18991906 .signedness = .unsigned,
1900 .bits = @intCast(u16, ty.bitSize(target)),
1907 .bits = @intCast(u16, ty.bitSize(mod)),
19011908 };
19021909
19031910 if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});
......@@ -1916,6 +1923,7 @@ pub const DeclGen = struct {
19161923 val: Value,
19171924 loc: ValueRenderLocation,
19181925 ) !std.fmt.Formatter(formatIntLiteral) {
1926 const mod = dg.module;
19191927 const kind: CType.Kind = switch (loc) {
19201928 .FunctionArgument => .parameter,
19211929 .Initializer, .Other => .complete,
......@@ -1923,7 +1931,7 @@ pub const DeclGen = struct {
19231931 };
19241932 return std.fmt.Formatter(formatIntLiteral){ .data = .{
19251933 .dg = dg,
1926 .int_info = ty.intInfo(dg.module.getTarget()),
1934 .int_info = ty.intInfo(mod),
19271935 .kind = kind,
19281936 .cty = try dg.typeToCType(ty, kind),
19291937 .val = val,
......@@ -2646,11 +2654,12 @@ pub fn genDecl(o: *Object) !void {
26462654 const tracy = trace(@src());
26472655 defer tracy.end();
26482656
2657 const mod = o.dg.module;
26492658 const decl = o.dg.decl.?;
26502659 const decl_c_value = .{ .decl = o.dg.decl_index.unwrap().? };
26512660 const tv: TypedValue = .{ .ty = decl.ty, .val = decl.val };
26522661
2653 if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime()) return;
2662 if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return;
26542663 if (tv.val.tag() == .extern_fn) {
26552664 const fwd_decl_writer = o.dg.fwd_decl.writer();
26562665 try fwd_decl_writer.writeAll("zig_extern ");
......@@ -2704,8 +2713,9 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
27042713 .val = dg.decl.?.val,
27052714 };
27062715 const writer = dg.fwd_decl.writer();
2716 const mod = dg.module;
27072717
2708 switch (tv.ty.zigTypeTag()) {
2718 switch (tv.ty.zigTypeTag(mod)) {
27092719 .Fn => {
27102720 const is_global = dg.declIsGlobal(tv);
27112721 if (is_global) {
......@@ -2791,6 +2801,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
27912801}
27922802
27932803fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {
2804 const mod = f.object.dg.module;
27942805 const air_tags = f.air.instructions.items(.tag);
27952806
27962807 for (body) |inst| {
......@@ -2826,10 +2837,10 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
28262837 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),
28272838 .rem => blk: {
28282839 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2829 const lhs_scalar_ty = f.air.typeOf(bin_op.lhs).scalarType();
2840 const lhs_scalar_ty = f.air.typeOf(bin_op.lhs).scalarType(mod);
28302841 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
28312842 // so we only check one.
2832 break :blk if (lhs_scalar_ty.isInt())
2843 break :blk if (lhs_scalar_ty.isInt(mod))
28332844 try airBinOp(f, inst, "%", "rem", .none)
28342845 else
28352846 try airBinFloatOp(f, inst, "fmod");
......@@ -3095,9 +3106,10 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
30953106}
30963107
30973108fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3109 const mod = f.object.dg.module;
30983110 const inst_ty = f.air.typeOfIndex(inst);
30993111 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3100 if (!inst_ty.hasRuntimeBitsIgnoreComptime()) {
3112 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
31013113 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
31023114 return .none;
31033115 }
......@@ -3120,13 +3132,14 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
31203132}
31213133
31223134fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3135 const mod = f.object.dg.module;
31233136 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
31243137 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
31253138
31263139 const inst_ty = f.air.typeOfIndex(inst);
31273140 const ptr_ty = f.air.typeOf(bin_op.lhs);
31283141 const elem_ty = ptr_ty.childType();
3129 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime();
3142 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);
31303143
31313144 const ptr = try f.resolveInst(bin_op.lhs);
31323145 const index = try f.resolveInst(bin_op.rhs);
......@@ -3155,9 +3168,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
31553168}
31563169
31573170fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3171 const mod = f.object.dg.module;
31583172 const inst_ty = f.air.typeOfIndex(inst);
31593173 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
3160 if (!inst_ty.hasRuntimeBitsIgnoreComptime()) {
3174 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
31613175 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
31623176 return .none;
31633177 }
......@@ -3180,13 +3194,14 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
31803194}
31813195
31823196fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3197 const mod = f.object.dg.module;
31833198 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
31843199 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
31853200
31863201 const inst_ty = f.air.typeOfIndex(inst);
31873202 const slice_ty = f.air.typeOf(bin_op.lhs);
3188 const elem_ty = slice_ty.elemType2();
3189 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime();
3203 const elem_ty = slice_ty.elemType2(mod);
3204 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod);
31903205
31913206 const slice = try f.resolveInst(bin_op.lhs);
31923207 const index = try f.resolveInst(bin_op.rhs);
......@@ -3209,9 +3224,10 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
32093224}
32103225
32113226fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3227 const mod = f.object.dg.module;
32123228 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
32133229 const inst_ty = f.air.typeOfIndex(inst);
3214 if (!inst_ty.hasRuntimeBitsIgnoreComptime()) {
3230 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
32153231 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
32163232 return .none;
32173233 }
......@@ -3234,14 +3250,14 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
32343250}
32353251
32363252fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3253 const mod = f.object.dg.module;
32373254 const inst_ty = f.air.typeOfIndex(inst);
32383255 const elem_type = inst_ty.elemType();
3239 if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime()) return .{ .undef = inst_ty };
3256 if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty };
32403257
3241 const target = f.object.dg.module.getTarget();
32423258 const local = try f.allocLocalValue(
32433259 elem_type,
3244 inst_ty.ptrAlignment(target),
3260 inst_ty.ptrAlignment(mod),
32453261 );
32463262 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
32473263 const gpa = f.object.dg.module.gpa;
......@@ -3250,14 +3266,14 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
32503266}
32513267
32523268fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3269 const mod = f.object.dg.module;
32533270 const inst_ty = f.air.typeOfIndex(inst);
32543271 const elem_ty = inst_ty.elemType();
3255 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return .{ .undef = inst_ty };
3272 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty };
32563273
3257 const target = f.object.dg.module.getTarget();
32583274 const local = try f.allocLocalValue(
32593275 elem_ty,
3260 inst_ty.ptrAlignment(target),
3276 inst_ty.ptrAlignment(mod),
32613277 );
32623278 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
32633279 const gpa = f.object.dg.module.gpa;
......@@ -3290,14 +3306,15 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
32903306}
32913307
32923308fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3309 const mod = f.object.dg.module;
32933310 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
32943311
32953312 const ptr_ty = f.air.typeOf(ty_op.operand);
3296 const ptr_scalar_ty = ptr_ty.scalarType();
3313 const ptr_scalar_ty = ptr_ty.scalarType(mod);
32973314 const ptr_info = ptr_scalar_ty.ptrInfo().data;
32983315 const src_ty = ptr_info.pointee_type;
32993316
3300 if (!src_ty.hasRuntimeBitsIgnoreComptime()) {
3317 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) {
33013318 try reap(f, inst, &.{ty_op.operand});
33023319 return .none;
33033320 }
......@@ -3306,9 +3323,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33063323
33073324 try reap(f, inst, &.{ty_op.operand});
33083325
3309 const target = f.object.dg.module.getTarget();
3310 const is_aligned = ptr_info.@"align" == 0 or ptr_info.@"align" >= src_ty.abiAlignment(target);
3311 const is_array = lowersToArray(src_ty, target);
3326 const is_aligned = ptr_info.@"align" == 0 or ptr_info.@"align" >= src_ty.abiAlignment(mod);
3327 const is_array = lowersToArray(src_ty, mod);
33123328 const need_memcpy = !is_aligned or is_array;
33133329
33143330 const writer = f.object.writer();
......@@ -3327,17 +3343,10 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33273343 try f.renderType(writer, src_ty);
33283344 try writer.writeAll("))");
33293345 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {
3330 var host_pl = Type.Payload.Bits{
3331 .base = .{ .tag = .int_unsigned },
3332 .data = ptr_info.host_size * 8,
3333 };
3334 const host_ty = Type.initPayload(&host_pl.base);
3346 const host_bits: u16 = ptr_info.host_size * 8;
3347 const host_ty = try mod.intType(.unsigned, host_bits);
33353348
3336 var bit_offset_ty_pl = Type.Payload.Bits{
3337 .base = .{ .tag = .int_unsigned },
3338 .data = Type.smallestUnsignedBits(host_pl.data - 1),
3339 };
3340 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
3349 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
33413350
33423351 var bit_offset_val_pl: Value.Payload.U64 = .{
33433352 .base = .{ .tag = .int_u64 },
......@@ -3345,11 +3354,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33453354 };
33463355 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
33473356
3348 var field_pl = Type.Payload.Bits{
3349 .base = .{ .tag = .int_unsigned },
3350 .data = @intCast(u16, src_ty.bitSize(target)),
3351 };
3352 const field_ty = Type.initPayload(&field_pl.base);
3357 const field_ty = try mod.intType(.unsigned, @intCast(u16, src_ty.bitSize(mod)));
33533358
33543359 try f.writeCValue(writer, local, .Other);
33553360 try v.elem(f, writer);
......@@ -3360,9 +3365,9 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33603365 try writer.writeAll("((");
33613366 try f.renderType(writer, field_ty);
33623367 try writer.writeByte(')');
3363 const cant_cast = host_ty.isInt() and host_ty.bitSize(target) > 64;
3368 const cant_cast = host_ty.isInt(mod) and host_ty.bitSize(mod) > 64;
33643369 if (cant_cast) {
3365 if (field_ty.bitSize(target) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
3370 if (field_ty.bitSize(mod) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
33663371 try writer.writeAll("zig_lo_");
33673372 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
33683373 try writer.writeByte('(');
......@@ -3390,23 +3395,23 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
33903395}
33913396
33923397fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
3398 const mod = f.object.dg.module;
33933399 const un_op = f.air.instructions.items(.data)[inst].un_op;
33943400 const writer = f.object.writer();
3395 const target = f.object.dg.module.getTarget();
33963401 const op_inst = Air.refToIndex(un_op);
33973402 const op_ty = f.air.typeOf(un_op);
33983403 const ret_ty = if (is_ptr) op_ty.childType() else op_ty;
33993404 var lowered_ret_buf: LowerFnRetTyBuffer = undefined;
3400 const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, target);
3405 const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, mod);
34013406
34023407 if (op_inst != null and f.air.instructions.items(.tag)[op_inst.?] == .call_always_tail) {
34033408 try reap(f, inst, &.{un_op});
34043409 _ = try airCall(f, op_inst.?, .always_tail);
3405 } else if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime()) {
3410 } else if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
34063411 const operand = try f.resolveInst(un_op);
34073412 try reap(f, inst, &.{un_op});
34083413 var deref = is_ptr;
3409 const is_array = lowersToArray(ret_ty, target);
3414 const is_array = lowersToArray(ret_ty, mod);
34103415 const ret_val = if (is_array) ret_val: {
34113416 const array_local = try f.allocLocal(inst, lowered_ret_ty);
34123417 try writer.writeAll("memcpy(");
......@@ -3442,15 +3447,16 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
34423447}
34433448
34443449fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
3450 const mod = f.object.dg.module;
34453451 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
34463452
34473453 const operand = try f.resolveInst(ty_op.operand);
34483454 try reap(f, inst, &.{ty_op.operand});
34493455
34503456 const inst_ty = f.air.typeOfIndex(inst);
3451 const inst_scalar_ty = inst_ty.scalarType();
3457 const inst_scalar_ty = inst_ty.scalarType(mod);
34523458 const operand_ty = f.air.typeOf(ty_op.operand);
3453 const scalar_ty = operand_ty.scalarType();
3459 const scalar_ty = operand_ty.scalarType(mod);
34543460
34553461 const writer = f.object.writer();
34563462 const local = try f.allocLocal(inst, inst_ty);
......@@ -3467,20 +3473,20 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
34673473}
34683474
34693475fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
3476 const mod = f.object.dg.module;
34703477 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
34713478
34723479 const operand = try f.resolveInst(ty_op.operand);
34733480 try reap(f, inst, &.{ty_op.operand});
34743481 const inst_ty = f.air.typeOfIndex(inst);
3475 const inst_scalar_ty = inst_ty.scalarType();
3476 const target = f.object.dg.module.getTarget();
3477 const dest_int_info = inst_scalar_ty.intInfo(target);
3482 const inst_scalar_ty = inst_ty.scalarType(mod);
3483 const dest_int_info = inst_scalar_ty.intInfo(mod);
34783484 const dest_bits = dest_int_info.bits;
34793485 const dest_c_bits = toCIntBits(dest_int_info.bits) orelse
34803486 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
34813487 const operand_ty = f.air.typeOf(ty_op.operand);
3482 const scalar_ty = operand_ty.scalarType();
3483 const scalar_int_info = scalar_ty.intInfo(target);
3488 const scalar_ty = operand_ty.scalarType(mod);
3489 const scalar_int_info = scalar_ty.intInfo(mod);
34843490
34853491 const writer = f.object.writer();
34863492 const local = try f.allocLocal(inst, inst_ty);
......@@ -3515,7 +3521,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35153521 var stack align(@alignOf(ExpectedContents)) =
35163522 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());
35173523
3518 const mask_val = try inst_scalar_ty.maxInt(stack.get(), target);
3524 const mask_val = try inst_scalar_ty.maxInt(stack.get(), mod);
35193525 try writer.writeAll("zig_and_");
35203526 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
35213527 try writer.writeByte('(');
......@@ -3577,17 +3583,18 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue {
35773583}
35783584
35793585fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
3586 const mod = f.object.dg.module;
35803587 // *a = b;
35813588 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
35823589
35833590 const ptr_ty = f.air.typeOf(bin_op.lhs);
3584 const ptr_scalar_ty = ptr_ty.scalarType();
3591 const ptr_scalar_ty = ptr_ty.scalarType(mod);
35853592 const ptr_info = ptr_scalar_ty.ptrInfo().data;
35863593
35873594 const ptr_val = try f.resolveInst(bin_op.lhs);
35883595 const src_ty = f.air.typeOf(bin_op.rhs);
35893596
3590 const val_is_undef = if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false;
3597 const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep() else false;
35913598
35923599 if (val_is_undef) {
35933600 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
......@@ -3602,10 +3609,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
36023609 return .none;
36033610 }
36043611
3605 const target = f.object.dg.module.getTarget();
36063612 const is_aligned = ptr_info.@"align" == 0 or
3607 ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(target);
3608 const is_array = lowersToArray(ptr_info.pointee_type, target);
3613 ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(mod);
3614 const is_array = lowersToArray(ptr_info.pointee_type, mod);
36093615 const need_memcpy = !is_aligned or is_array;
36103616
36113617 const src_val = try f.resolveInst(bin_op.rhs);
......@@ -3647,14 +3653,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
36473653 }
36483654 } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) {
36493655 const host_bits = ptr_info.host_size * 8;
3650 var host_pl = Type.Payload.Bits{ .base = .{ .tag = .int_unsigned }, .data = host_bits };
3651 const host_ty = Type.initPayload(&host_pl.base);
3656 const host_ty = try mod.intType(.unsigned, host_bits);
36523657
3653 var bit_offset_ty_pl = Type.Payload.Bits{
3654 .base = .{ .tag = .int_unsigned },
3655 .data = Type.smallestUnsignedBits(host_bits - 1),
3656 };
3657 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
3658 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(host_bits - 1));
36583659
36593660 var bit_offset_val_pl: Value.Payload.U64 = .{
36603661 .base = .{ .tag = .int_u64 },
......@@ -3662,7 +3663,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
36623663 };
36633664 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
36643665
3665 const src_bits = src_ty.bitSize(target);
3666 const src_bits = src_ty.bitSize(mod);
36663667
36673668 const ExpectedContents = [BigInt.Managed.default_capacity]BigIntLimb;
36683669 var stack align(@alignOf(ExpectedContents)) =
......@@ -3693,9 +3694,9 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
36933694 try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)});
36943695 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
36953696 try writer.writeByte('(');
3696 const cant_cast = host_ty.isInt() and host_ty.bitSize(target) > 64;
3697 const cant_cast = host_ty.isInt(mod) and host_ty.bitSize(mod) > 64;
36973698 if (cant_cast) {
3698 if (src_ty.bitSize(target) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
3699 if (src_ty.bitSize(mod) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
36993700 try writer.writeAll("zig_make_");
37003701 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
37013702 try writer.writeAll("(0, ");
......@@ -3705,7 +3706,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
37053706 try writer.writeByte(')');
37063707 }
37073708
3708 if (src_ty.isPtrAtRuntime()) {
3709 if (src_ty.isPtrAtRuntime(mod)) {
37093710 try writer.writeByte('(');
37103711 try f.renderType(writer, Type.usize);
37113712 try writer.writeByte(')');
......@@ -3728,6 +3729,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
37283729}
37293730
37303731fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {
3732 const mod = f.object.dg.module;
37313733 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
37323734 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
37333735
......@@ -3737,7 +3739,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
37373739
37383740 const inst_ty = f.air.typeOfIndex(inst);
37393741 const operand_ty = f.air.typeOf(bin_op.lhs);
3740 const scalar_ty = operand_ty.scalarType();
3742 const scalar_ty = operand_ty.scalarType(mod);
37413743
37423744 const w = f.object.writer();
37433745 const local = try f.allocLocal(inst, inst_ty);
......@@ -3765,9 +3767,10 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
37653767}
37663768
37673769fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
3770 const mod = f.object.dg.module;
37683771 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
37693772 const operand_ty = f.air.typeOf(ty_op.operand);
3770 const scalar_ty = operand_ty.scalarType();
3773 const scalar_ty = operand_ty.scalarType(mod);
37713774 if (scalar_ty.tag() != .bool) return try airUnBuiltinCall(f, inst, "not", .bits);
37723775
37733776 const op = try f.resolveInst(ty_op.operand);
......@@ -3797,11 +3800,11 @@ fn airBinOp(
37973800 operation: []const u8,
37983801 info: BuiltinInfo,
37993802) !CValue {
3803 const mod = f.object.dg.module;
38003804 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
38013805 const operand_ty = f.air.typeOf(bin_op.lhs);
3802 const scalar_ty = operand_ty.scalarType();
3803 const target = f.object.dg.module.getTarget();
3804 if ((scalar_ty.isInt() and scalar_ty.bitSize(target) > 64) or scalar_ty.isRuntimeFloat())
3806 const scalar_ty = operand_ty.scalarType(mod);
3807 if ((scalar_ty.isInt(mod) and scalar_ty.bitSize(mod) > 64) or scalar_ty.isRuntimeFloat())
38053808 return try airBinBuiltinCall(f, inst, operation, info);
38063809
38073810 const lhs = try f.resolveInst(bin_op.lhs);
......@@ -3835,12 +3838,12 @@ fn airCmpOp(
38353838 data: anytype,
38363839 operator: std.math.CompareOperator,
38373840) !CValue {
3841 const mod = f.object.dg.module;
38383842 const lhs_ty = f.air.typeOf(data.lhs);
3839 const scalar_ty = lhs_ty.scalarType();
3843 const scalar_ty = lhs_ty.scalarType(mod);
38403844
3841 const target = f.object.dg.module.getTarget();
3842 const scalar_bits = scalar_ty.bitSize(target);
3843 if (scalar_ty.isInt() and scalar_bits > 64)
3845 const scalar_bits = scalar_ty.bitSize(mod);
3846 if (scalar_ty.isInt(mod) and scalar_bits > 64)
38443847 return airCmpBuiltinCall(
38453848 f,
38463849 inst,
......@@ -3885,12 +3888,12 @@ fn airEquality(
38853888 inst: Air.Inst.Index,
38863889 operator: std.math.CompareOperator,
38873890) !CValue {
3891 const mod = f.object.dg.module;
38883892 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
38893893
38903894 const operand_ty = f.air.typeOf(bin_op.lhs);
3891 const target = f.object.dg.module.getTarget();
3892 const operand_bits = operand_ty.bitSize(target);
3893 if (operand_ty.isInt() and operand_bits > 64)
3895 const operand_bits = operand_ty.bitSize(mod);
3896 if (operand_ty.isInt(mod) and operand_bits > 64)
38943897 return airCmpBuiltinCall(
38953898 f,
38963899 inst,
......@@ -3912,7 +3915,7 @@ fn airEquality(
39123915 try f.writeCValue(writer, local, .Other);
39133916 try writer.writeAll(" = ");
39143917
3915 if (operand_ty.zigTypeTag() == .Optional and !operand_ty.optionalReprIsPayload()) {
3918 if (operand_ty.zigTypeTag(mod) == .Optional and !operand_ty.optionalReprIsPayload(mod)) {
39163919 // (A && B) || (C && (A == B))
39173920 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload
39183921
......@@ -3965,6 +3968,7 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
39653968}
39663969
39673970fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
3971 const mod = f.object.dg.module;
39683972 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
39693973 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
39703974
......@@ -3973,8 +3977,8 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
39733977 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
39743978
39753979 const inst_ty = f.air.typeOfIndex(inst);
3976 const inst_scalar_ty = inst_ty.scalarType();
3977 const elem_ty = inst_scalar_ty.elemType2();
3980 const inst_scalar_ty = inst_ty.scalarType(mod);
3981 const elem_ty = inst_scalar_ty.elemType2(mod);
39783982
39793983 const local = try f.allocLocal(inst, inst_ty);
39803984 const writer = f.object.writer();
......@@ -3983,7 +3987,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
39833987 try v.elem(f, writer);
39843988 try writer.writeAll(" = ");
39853989
3986 if (elem_ty.hasRuntimeBitsIgnoreComptime()) {
3990 if (elem_ty.hasRuntimeBitsIgnoreComptime(mod)) {
39873991 // We must convert to and from integer types to prevent UB if the operation
39883992 // results in a NULL pointer, or if LHS is NULL. The operation is only UB
39893993 // if the result is NULL and then dereferenced.
......@@ -4012,13 +4016,13 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
40124016}
40134017
40144018fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue {
4019 const mod = f.object.dg.module;
40154020 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
40164021
40174022 const inst_ty = f.air.typeOfIndex(inst);
4018 const inst_scalar_ty = inst_ty.scalarType();
4023 const inst_scalar_ty = inst_ty.scalarType(mod);
40194024
4020 const target = f.object.dg.module.getTarget();
4021 if (inst_scalar_ty.isInt() and inst_scalar_ty.bitSize(target) > 64)
4025 if (inst_scalar_ty.isInt(mod) and inst_scalar_ty.bitSize(mod) > 64)
40224026 return try airBinBuiltinCall(f, inst, operation[1..], .none);
40234027 if (inst_scalar_ty.isRuntimeFloat())
40244028 return try airBinFloatOp(f, inst, operation);
......@@ -4092,12 +4096,11 @@ fn airCall(
40924096 inst: Air.Inst.Index,
40934097 modifier: std.builtin.CallModifier,
40944098) !CValue {
4099 const mod = f.object.dg.module;
40954100 // Not even allowed to call panic in a naked function.
40964101 if (f.object.dg.decl) |decl| if (decl.ty.fnCallingConvention() == .Naked) return .none;
40974102
40984103 const gpa = f.object.dg.gpa;
4099 const module = f.object.dg.module;
4100 const target = module.getTarget();
41014104 const writer = f.object.writer();
41024105
41034106 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
......@@ -4116,7 +4119,7 @@ fn airCall(
41164119 resolved_arg.* = try f.resolveInst(arg);
41174120 if (arg_cty != try f.typeToIndex(arg_ty, .complete)) {
41184121 var lowered_arg_buf: LowerFnRetTyBuffer = undefined;
4119 const lowered_arg_ty = lowerFnRetTy(arg_ty, &lowered_arg_buf, target);
4122 const lowered_arg_ty = lowerFnRetTy(arg_ty, &lowered_arg_buf, mod);
41204123
41214124 const array_local = try f.allocLocal(inst, lowered_arg_ty);
41224125 try writer.writeAll("memcpy(");
......@@ -4139,7 +4142,7 @@ fn airCall(
41394142 }
41404143
41414144 const callee_ty = f.air.typeOf(pl_op.operand);
4142 const fn_ty = switch (callee_ty.zigTypeTag()) {
4145 const fn_ty = switch (callee_ty.zigTypeTag(mod)) {
41434146 .Fn => callee_ty,
41444147 .Pointer => callee_ty.childType(),
41454148 else => unreachable,
......@@ -4147,13 +4150,13 @@ fn airCall(
41474150
41484151 const ret_ty = fn_ty.fnReturnType();
41494152 var lowered_ret_buf: LowerFnRetTyBuffer = undefined;
4150 const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, target);
4153 const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, mod);
41514154
41524155 const result_local = result: {
41534156 if (modifier == .always_tail) {
41544157 try writer.writeAll("zig_always_tail return ");
41554158 break :result .none;
4156 } else if (!lowered_ret_ty.hasRuntimeBitsIgnoreComptime()) {
4159 } else if (!lowered_ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
41574160 break :result .none;
41584161 } else if (f.liveness.isUnused(inst)) {
41594162 try writer.writeByte('(');
......@@ -4171,7 +4174,7 @@ fn airCall(
41714174 callee: {
41724175 known: {
41734176 const fn_decl = fn_decl: {
4174 const callee_val = f.air.value(pl_op.operand) orelse break :known;
4177 const callee_val = f.air.value(pl_op.operand, mod) orelse break :known;
41754178 break :fn_decl switch (callee_val.tag()) {
41764179 .extern_fn => callee_val.castTag(.extern_fn).?.data.owner_decl,
41774180 .function => callee_val.castTag(.function).?.data.owner_decl,
......@@ -4181,9 +4184,9 @@ fn airCall(
41814184 };
41824185 switch (modifier) {
41834186 .auto, .always_tail => try f.object.dg.renderDeclName(writer, fn_decl, 0),
4184 inline .never_tail, .never_inline => |mod| try writer.writeAll(try f.getLazyFnName(
4185 @unionInit(LazyFnKey, @tagName(mod), fn_decl),
4186 @unionInit(LazyFnValue.Data, @tagName(mod), {}),
4187 inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName(
4188 @unionInit(LazyFnKey, @tagName(m), fn_decl),
4189 @unionInit(LazyFnValue.Data, @tagName(m), {}),
41874190 )),
41884191 else => unreachable,
41894192 }
......@@ -4211,7 +4214,7 @@ fn airCall(
42114214 try writer.writeAll(");\n");
42124215
42134216 const result = result: {
4214 if (result_local == .none or !lowersToArray(ret_ty, target))
4217 if (result_local == .none or !lowersToArray(ret_ty, mod))
42154218 break :result result_local;
42164219
42174220 const array_local = try f.allocLocal(inst, ret_ty);
......@@ -4254,9 +4257,10 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
42544257}
42554258
42564259fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4260 const mod = f.object.dg.module;
42574261 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
42584262 const name = f.air.nullTerminatedString(pl_op.payload);
4259 const operand_is_undef = if (f.air.value(pl_op.operand)) |v| v.isUndefDeep() else false;
4263 const operand_is_undef = if (f.air.value(pl_op.operand, mod)) |v| v.isUndefDeep() else false;
42604264 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
42614265
42624266 try reap(f, inst, &.{pl_op.operand});
......@@ -4330,12 +4334,13 @@ fn lowerTry(
43304334 err_union_ty: Type,
43314335 is_ptr: bool,
43324336) !CValue {
4337 const mod = f.object.dg.module;
43334338 const err_union = try f.resolveInst(operand);
43344339 const inst_ty = f.air.typeOfIndex(inst);
43354340 const liveness_condbr = f.liveness.getCondBr(inst);
43364341 const writer = f.object.writer();
43374342 const payload_ty = err_union_ty.errorUnionPayload();
4338 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
4343 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
43394344
43404345 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
43414346 try writer.writeAll("if (");
......@@ -4431,6 +4436,8 @@ const LocalResult = struct {
44314436 need_free: bool,
44324437
44334438 fn move(lr: LocalResult, f: *Function, inst: Air.Inst.Index, dest_ty: Type) !CValue {
4439 const mod = f.object.dg.module;
4440
44344441 if (lr.need_free) {
44354442 // Move the freshly allocated local to be owned by this instruction,
44364443 // by returning it here instead of freeing it.
......@@ -4441,7 +4448,7 @@ const LocalResult = struct {
44414448 try lr.free(f);
44424449 const writer = f.object.writer();
44434450 try f.writeCValue(writer, local, .Other);
4444 if (dest_ty.isAbiInt()) {
4451 if (dest_ty.isAbiInt(mod)) {
44454452 try writer.writeAll(" = ");
44464453 } else {
44474454 try writer.writeAll(" = (");
......@@ -4461,12 +4468,13 @@ const LocalResult = struct {
44614468};
44624469
44634470fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !LocalResult {
4464 const target = f.object.dg.module.getTarget();
4471 const mod = f.object.dg.module;
4472 const target = mod.getTarget();
44654473 const writer = f.object.writer();
44664474
4467 if (operand_ty.isAbiInt() and dest_ty.isAbiInt()) {
4468 const src_info = dest_ty.intInfo(target);
4469 const dest_info = operand_ty.intInfo(target);
4475 if (operand_ty.isAbiInt(mod) and dest_ty.isAbiInt(mod)) {
4476 const src_info = dest_ty.intInfo(mod);
4477 const dest_info = operand_ty.intInfo(mod);
44704478 if (src_info.signedness == dest_info.signedness and
44714479 src_info.bits == dest_info.bits)
44724480 {
......@@ -4477,7 +4485,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
44774485 }
44784486 }
44794487
4480 if (dest_ty.isPtrAtRuntime() and operand_ty.isPtrAtRuntime()) {
4488 if (dest_ty.isPtrAtRuntime(mod) and operand_ty.isPtrAtRuntime(mod)) {
44814489 const local = try f.allocLocal(0, dest_ty);
44824490 try f.writeCValue(writer, local, .Other);
44834491 try writer.writeAll(" = (");
......@@ -4494,7 +4502,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
44944502 const operand_lval = if (operand == .constant) blk: {
44954503 const operand_local = try f.allocLocal(0, operand_ty);
44964504 try f.writeCValue(writer, operand_local, .Other);
4497 if (operand_ty.isAbiInt()) {
4505 if (operand_ty.isAbiInt(mod)) {
44984506 try writer.writeAll(" = ");
44994507 } else {
45004508 try writer.writeAll(" = (");
......@@ -4516,13 +4524,10 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
45164524 try writer.writeAll("));\n");
45174525
45184526 // Ensure padding bits have the expected value.
4519 if (dest_ty.isAbiInt()) {
4527 if (dest_ty.isAbiInt(mod)) {
45204528 const dest_cty = try f.typeToCType(dest_ty, .complete);
4521 const dest_info = dest_ty.intInfo(target);
4522 var info_ty_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dest_info.signedness) {
4523 .unsigned => .int_unsigned,
4524 .signed => .int_signed,
4525 } }, .data = dest_info.bits };
4529 const dest_info = dest_ty.intInfo(mod);
4530 var bits: u16 = dest_info.bits;
45264531 var wrap_cty: ?CType = null;
45274532 var need_bitcasts = false;
45284533
......@@ -4535,9 +4540,9 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
45354540 const elem_cty = f.indexToCType(pl.data.elem_type);
45364541 wrap_cty = elem_cty.toSignedness(dest_info.signedness);
45374542 need_bitcasts = wrap_cty.?.tag() == .zig_i128;
4538 info_ty_pl.data -= 1;
4539 info_ty_pl.data %= @intCast(u16, f.byteSize(elem_cty) * 8);
4540 info_ty_pl.data += 1;
4543 bits -= 1;
4544 bits %= @intCast(u16, f.byteSize(elem_cty) * 8);
4545 bits += 1;
45414546 }
45424547 try writer.writeAll(" = ");
45434548 if (need_bitcasts) {
......@@ -4546,7 +4551,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
45464551 try writer.writeByte('(');
45474552 }
45484553 try writer.writeAll("zig_wrap_");
4549 const info_ty = Type.initPayload(&info_ty_pl.base);
4554 const info_ty = try mod.intType(dest_info.signedness, bits);
45504555 if (wrap_cty) |cty|
45514556 try f.object.dg.renderCTypeForBuiltinFnName(writer, cty)
45524557 else
......@@ -4675,6 +4680,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
46754680}
46764681
46774682fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4683 const mod = f.object.dg.module;
46784684 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
46794685 const condition = try f.resolveInst(pl_op.operand);
46804686 try reap(f, inst, &.{pl_op.operand});
......@@ -4683,11 +4689,11 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
46834689 const writer = f.object.writer();
46844690
46854691 try writer.writeAll("switch (");
4686 if (condition_ty.zigTypeTag() == .Bool) {
4692 if (condition_ty.zigTypeTag(mod) == .Bool) {
46874693 try writer.writeByte('(');
46884694 try f.renderType(writer, Type.u1);
46894695 try writer.writeByte(')');
4690 } else if (condition_ty.isPtrAtRuntime()) {
4696 } else if (condition_ty.isPtrAtRuntime(mod)) {
46914697 try writer.writeByte('(');
46924698 try f.renderType(writer, Type.usize);
46934699 try writer.writeByte(')');
......@@ -4714,12 +4720,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
47144720 for (items) |item| {
47154721 try f.object.indent_writer.insertNewline();
47164722 try writer.writeAll("case ");
4717 if (condition_ty.isPtrAtRuntime()) {
4723 if (condition_ty.isPtrAtRuntime(mod)) {
47184724 try writer.writeByte('(');
47194725 try f.renderType(writer, Type.usize);
47204726 try writer.writeByte(')');
47214727 }
4722 try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?, .Other);
4728 try f.object.dg.renderValue(writer, condition_ty, f.air.value(item, mod).?, .Other);
47234729 try writer.writeByte(':');
47244730 }
47254731 try writer.writeByte(' ');
......@@ -4764,6 +4770,7 @@ fn asmInputNeedsLocal(constraint: []const u8, value: CValue) bool {
47644770}
47654771
47664772fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4773 const mod = f.object.dg.module;
47674774 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
47684775 const extra = f.air.extraData(Air.Asm, ty_pl.payload);
47694776 const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
......@@ -4778,7 +4785,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
47784785 const result = result: {
47794786 const writer = f.object.writer();
47804787 const inst_ty = f.air.typeOfIndex(inst);
4781 const local = if (inst_ty.hasRuntimeBitsIgnoreComptime()) local: {
4788 const local = if (inst_ty.hasRuntimeBitsIgnoreComptime(mod)) local: {
47824789 const local = try f.allocLocal(inst, inst_ty);
47834790 if (f.wantSafety()) {
47844791 try f.writeCValue(writer, local, .Other);
......@@ -5025,6 +5032,7 @@ fn airIsNull(
50255032 operator: []const u8,
50265033 is_ptr: bool,
50275034) !CValue {
5035 const mod = f.object.dg.module;
50285036 const un_op = f.air.instructions.items(.data)[inst].un_op;
50295037
50305038 const writer = f.object.writer();
......@@ -5046,14 +5054,14 @@ fn airIsNull(
50465054 const payload_ty = optional_ty.optionalChild(&payload_buf);
50475055 var slice_ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
50485056
5049 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime())
5057 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
50505058 TypedValue{ .ty = Type.bool, .val = Value.true }
5051 else if (optional_ty.isPtrLikeOptional())
5059 else if (optional_ty.isPtrLikeOptional(mod))
50525060 // operand is a regular pointer, test `operand !=/== NULL`
50535061 TypedValue{ .ty = optional_ty, .val = Value.null }
5054 else if (payload_ty.zigTypeTag() == .ErrorSet)
5062 else if (payload_ty.zigTypeTag(mod) == .ErrorSet)
50555063 TypedValue{ .ty = payload_ty, .val = Value.zero }
5056 else if (payload_ty.isSlice() and optional_ty.optionalReprIsPayload()) rhs: {
5064 else if (payload_ty.isSlice() and optional_ty.optionalReprIsPayload(mod)) rhs: {
50575065 try writer.writeAll(".ptr");
50585066 const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf);
50595067 break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null };
......@@ -5070,6 +5078,7 @@ fn airIsNull(
50705078}
50715079
50725080fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
5081 const mod = f.object.dg.module;
50735082 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
50745083
50755084 const operand = try f.resolveInst(ty_op.operand);
......@@ -5079,7 +5088,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
50795088 var buf: Type.Payload.ElemType = undefined;
50805089 const payload_ty = opt_ty.optionalChild(&buf);
50815090
5082 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
5091 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
50835092 return .none;
50845093 }
50855094
......@@ -5087,7 +5096,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
50875096 const writer = f.object.writer();
50885097 const local = try f.allocLocal(inst, inst_ty);
50895098
5090 if (opt_ty.optionalReprIsPayload()) {
5099 if (opt_ty.optionalReprIsPayload(mod)) {
50915100 try f.writeCValue(writer, local, .Other);
50925101 try writer.writeAll(" = ");
50935102 try f.writeCValue(writer, operand, .Other);
......@@ -5104,6 +5113,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
51045113}
51055114
51065115fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5116 const mod = f.object.dg.module;
51075117 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
51085118
51095119 const writer = f.object.writer();
......@@ -5113,14 +5123,14 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
51135123 const opt_ty = ptr_ty.childType();
51145124 const inst_ty = f.air.typeOfIndex(inst);
51155125
5116 if (!inst_ty.childType().hasRuntimeBitsIgnoreComptime()) {
5126 if (!inst_ty.childType().hasRuntimeBitsIgnoreComptime(mod)) {
51175127 return .{ .undef = inst_ty };
51185128 }
51195129
51205130 const local = try f.allocLocal(inst, inst_ty);
51215131 try f.writeCValue(writer, local, .Other);
51225132
5123 if (opt_ty.optionalReprIsPayload()) {
5133 if (opt_ty.optionalReprIsPayload(mod)) {
51245134 // the operand is just a regular pointer, no need to do anything special.
51255135 // *?*T -> **T and ?*T -> *T are **T -> **T and *T -> *T in C
51265136 try writer.writeAll(" = ");
......@@ -5134,6 +5144,7 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
51345144}
51355145
51365146fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5147 const mod = f.object.dg.module;
51375148 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
51385149 const writer = f.object.writer();
51395150 const operand = try f.resolveInst(ty_op.operand);
......@@ -5144,7 +5155,7 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
51445155
51455156 const inst_ty = f.air.typeOfIndex(inst);
51465157
5147 if (opt_ty.optionalReprIsPayload()) {
5158 if (opt_ty.optionalReprIsPayload(mod)) {
51485159 if (f.liveness.isUnused(inst)) {
51495160 return .none;
51505161 }
......@@ -5179,36 +5190,36 @@ fn fieldLocation(
51795190 container_ty: Type,
51805191 field_ptr_ty: Type,
51815192 field_index: u32,
5182 target: std.Target,
5193 mod: *const Module,
51835194) union(enum) {
51845195 begin: void,
51855196 field: CValue,
51865197 byte_offset: u32,
51875198 end: void,
51885199} {
5189 return switch (container_ty.zigTypeTag()) {
5200 return switch (container_ty.zigTypeTag(mod)) {
51905201 .Struct => switch (container_ty.containerLayout()) {
51915202 .Auto, .Extern => for (field_index..container_ty.structFieldCount()) |next_field_index| {
51925203 if (container_ty.structFieldIsComptime(next_field_index)) continue;
51935204 const field_ty = container_ty.structFieldType(next_field_index);
5194 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
5205 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
51955206
51965207 break .{ .field = if (container_ty.isSimpleTuple())
51975208 .{ .field = next_field_index }
51985209 else
51995210 .{ .identifier = container_ty.structFieldName(next_field_index) } };
5200 } else if (container_ty.hasRuntimeBitsIgnoreComptime()) .end else .begin,
5211 } else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin,
52015212 .Packed => if (field_ptr_ty.ptrInfo().data.host_size == 0)
5202 .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, target) }
5213 .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) }
52035214 else
52045215 .begin,
52055216 },
52065217 .Union => switch (container_ty.containerLayout()) {
52075218 .Auto, .Extern => {
52085219 const field_ty = container_ty.structFieldType(field_index);
5209 if (!field_ty.hasRuntimeBitsIgnoreComptime())
5220 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod))
52105221 return if (container_ty.unionTagTypeSafety() != null and
5211 !container_ty.unionHasAllZeroBitFieldTypes())
5222 !container_ty.unionHasAllZeroBitFieldTypes(mod))
52125223 .{ .field = .{ .identifier = "payload" } }
52135224 else
52145225 .begin;
......@@ -5252,10 +5263,10 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
52525263}
52535264
52545265fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5266 const mod = f.object.dg.module;
52555267 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
52565268 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
52575269
5258 const target = f.object.dg.module.getTarget();
52595270 const container_ptr_ty = f.air.typeOfIndex(inst);
52605271 const container_ty = container_ptr_ty.childType();
52615272
......@@ -5270,7 +5281,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
52705281 try f.renderType(writer, container_ptr_ty);
52715282 try writer.writeByte(')');
52725283
5273 switch (fieldLocation(container_ty, field_ptr_ty, extra.field_index, target)) {
5284 switch (fieldLocation(container_ty, field_ptr_ty, extra.field_index, mod)) {
52745285 .begin => try f.writeCValue(writer, field_ptr_val, .Initializer),
52755286 .field => |field| {
52765287 var u8_ptr_pl = field_ptr_ty.ptrInfo();
......@@ -5321,7 +5332,7 @@ fn fieldPtr(
53215332 container_ptr_val: CValue,
53225333 field_index: u32,
53235334) !CValue {
5324 const target = f.object.dg.module.getTarget();
5335 const mod = f.object.dg.module;
53255336 const container_ty = container_ptr_ty.elemType();
53265337 const field_ptr_ty = f.air.typeOfIndex(inst);
53275338
......@@ -5335,7 +5346,7 @@ fn fieldPtr(
53355346 try f.renderType(writer, field_ptr_ty);
53365347 try writer.writeByte(')');
53375348
5338 switch (fieldLocation(container_ty, field_ptr_ty, field_index, target)) {
5349 switch (fieldLocation(container_ty, field_ptr_ty, field_index, mod)) {
53395350 .begin => try f.writeCValue(writer, container_ptr_val, .Initializer),
53405351 .field => |field| {
53415352 try writer.writeByte('&');
......@@ -5370,16 +5381,16 @@ fn fieldPtr(
53705381}
53715382
53725383fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5384 const mod = f.object.dg.module;
53735385 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
53745386 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
53755387
53765388 const inst_ty = f.air.typeOfIndex(inst);
5377 if (!inst_ty.hasRuntimeBitsIgnoreComptime()) {
5389 if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
53785390 try reap(f, inst, &.{extra.struct_operand});
53795391 return .none;
53805392 }
53815393
5382 const target = f.object.dg.module.getTarget();
53835394 const struct_byval = try f.resolveInst(extra.struct_operand);
53845395 try reap(f, inst, &.{extra.struct_operand});
53855396 const struct_ty = f.air.typeOf(extra.struct_operand);
......@@ -5396,32 +5407,21 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
53965407 .{ .identifier = struct_ty.structFieldName(extra.field_index) },
53975408 .Packed => {
53985409 const struct_obj = struct_ty.castTag(.@"struct").?.data;
5399 const int_info = struct_ty.intInfo(target);
5410 const int_info = struct_ty.intInfo(mod);
54005411
5401 var bit_offset_ty_pl = Type.Payload.Bits{
5402 .base = .{ .tag = .int_unsigned },
5403 .data = Type.smallestUnsignedBits(int_info.bits - 1),
5404 };
5405 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
5412 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
54065413
54075414 var bit_offset_val_pl: Value.Payload.U64 = .{
54085415 .base = .{ .tag = .int_u64 },
5409 .data = struct_obj.packedFieldBitOffset(target, extra.field_index),
5416 .data = struct_obj.packedFieldBitOffset(mod, extra.field_index),
54105417 };
54115418 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
54125419
5413 const field_int_signedness = if (inst_ty.isAbiInt())
5414 inst_ty.intInfo(target).signedness
5420 const field_int_signedness = if (inst_ty.isAbiInt(mod))
5421 inst_ty.intInfo(mod).signedness
54155422 else
54165423 .unsigned;
5417 var field_int_pl = Type.Payload.Bits{
5418 .base = .{ .tag = switch (field_int_signedness) {
5419 .unsigned => .int_unsigned,
5420 .signed => .int_signed,
5421 } },
5422 .data = @intCast(u16, inst_ty.bitSize(target)),
5423 };
5424 const field_int_ty = Type.initPayload(&field_int_pl.base);
5424 const field_int_ty = try mod.intType(field_int_signedness, @intCast(u16, inst_ty.bitSize(mod)));
54255425
54265426 const temp_local = try f.allocLocal(inst, field_int_ty);
54275427 try f.writeCValue(writer, temp_local, .Other);
......@@ -5432,7 +5432,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54325432 try writer.writeByte(')');
54335433 const cant_cast = int_info.bits > 64;
54345434 if (cant_cast) {
5435 if (field_int_ty.bitSize(target) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
5435 if (field_int_ty.bitSize(mod) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
54365436 try writer.writeAll("zig_lo_");
54375437 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
54385438 try writer.writeByte('(');
......@@ -5511,6 +5511,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
55115511/// *(E!T) -> E
55125512/// Note that the result is never a pointer.
55135513fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5514 const mod = f.object.dg.module;
55145515 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55155516
55165517 const inst_ty = f.air.typeOfIndex(inst);
......@@ -5518,13 +5519,13 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
55185519 const operand_ty = f.air.typeOf(ty_op.operand);
55195520 try reap(f, inst, &.{ty_op.operand});
55205521
5521 const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer;
5522 const operand_is_ptr = operand_ty.zigTypeTag(mod) == .Pointer;
55225523 const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
55235524 const error_ty = error_union_ty.errorUnionSet();
55245525 const payload_ty = error_union_ty.errorUnionPayload();
55255526 const local = try f.allocLocal(inst, inst_ty);
55265527
5527 if (!payload_ty.hasRuntimeBits() and operand == .local and operand.local == local.new_local) {
5528 if (!payload_ty.hasRuntimeBits(mod) and operand == .local and operand.local == local.new_local) {
55285529 // The store will be 'x = x'; elide it.
55295530 return local;
55305531 }
......@@ -5533,7 +5534,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
55335534 try f.writeCValue(writer, local, .Other);
55345535 try writer.writeAll(" = ");
55355536
5536 if (!payload_ty.hasRuntimeBits()) {
5537 if (!payload_ty.hasRuntimeBits(mod)) {
55375538 try f.writeCValue(writer, operand, .Other);
55385539 } else {
55395540 if (!error_ty.errorSetIsEmpty())
......@@ -5549,6 +5550,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
55495550}
55505551
55515552fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
5553 const mod = f.object.dg.module;
55525554 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55535555
55545556 const inst_ty = f.air.typeOfIndex(inst);
......@@ -5558,7 +5560,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
55585560 const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty;
55595561
55605562 const writer = f.object.writer();
5561 if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) {
5563 if (!error_union_ty.errorUnionPayload().hasRuntimeBits(mod)) {
55625564 if (!is_ptr) return .none;
55635565
55645566 const local = try f.allocLocal(inst, inst_ty);
......@@ -5584,10 +5586,11 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
55845586}
55855587
55865588fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
5589 const mod = f.object.dg.module;
55875590 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
55885591
55895592 const inst_ty = f.air.typeOfIndex(inst);
5590 const repr_is_payload = inst_ty.optionalReprIsPayload();
5593 const repr_is_payload = inst_ty.optionalReprIsPayload(mod);
55915594 const payload_ty = f.air.typeOf(ty_op.operand);
55925595 const payload = try f.resolveInst(ty_op.operand);
55935596 try reap(f, inst, &.{ty_op.operand});
......@@ -5615,11 +5618,12 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
56155618}
56165619
56175620fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5621 const mod = f.object.dg.module;
56185622 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56195623
56205624 const inst_ty = f.air.typeOfIndex(inst);
56215625 const payload_ty = inst_ty.errorUnionPayload();
5622 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime();
5626 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
56235627 const err_ty = inst_ty.errorUnionSet();
56245628 const err = try f.resolveInst(ty_op.operand);
56255629 try reap(f, inst, &.{ty_op.operand});
......@@ -5653,6 +5657,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
56535657}
56545658
56555659fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5660 const mod = f.object.dg.module;
56565661 const writer = f.object.writer();
56575662 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56585663 const operand = try f.resolveInst(ty_op.operand);
......@@ -5662,7 +5667,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
56625667 const payload_ty = error_union_ty.errorUnionPayload();
56635668
56645669 // First, set the non-error value.
5665 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
5670 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
56665671 try f.writeCValueDeref(writer, operand);
56675672 try writer.writeAll(" = ");
56685673 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other);
......@@ -5703,12 +5708,13 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {
57035708}
57045709
57055710fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
5711 const mod = f.object.dg.module;
57065712 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
57075713
57085714 const inst_ty = f.air.typeOfIndex(inst);
57095715 const payload_ty = inst_ty.errorUnionPayload();
57105716 const payload = try f.resolveInst(ty_op.operand);
5711 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime();
5717 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
57125718 const err_ty = inst_ty.errorUnionSet();
57135719 try reap(f, inst, &.{ty_op.operand});
57145720
......@@ -5735,6 +5741,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
57355741}
57365742
57375743fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {
5744 const mod = f.object.dg.module;
57385745 const un_op = f.air.instructions.items(.data)[inst].un_op;
57395746
57405747 const writer = f.object.writer();
......@@ -5750,7 +5757,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
57505757 try writer.writeAll(" = ");
57515758
57525759 if (!error_ty.errorSetIsEmpty())
5753 if (payload_ty.hasRuntimeBits())
5760 if (payload_ty.hasRuntimeBits(mod))
57545761 if (is_ptr)
57555762 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
57565763 else
......@@ -5768,6 +5775,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
57685775}
57695776
57705777fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
5778 const mod = f.object.dg.module;
57715779 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
57725780
57735781 const operand = try f.resolveInst(ty_op.operand);
......@@ -5784,7 +5792,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
57845792 if (operand == .undef) {
57855793 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
57865794 try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf) }, .Initializer);
5787 } else if (array_ty.hasRuntimeBitsIgnoreComptime()) {
5795 } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
57885796 try writer.writeAll("&(");
57895797 try f.writeCValueDeref(writer, operand);
57905798 try writer.print(")[{}]", .{try f.fmtIntLiteral(Type.usize, Value.zero)});
......@@ -5801,6 +5809,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
58015809}
58025810
58035811fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
5812 const mod = f.object.dg.module;
58045813 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
58055814
58065815 const inst_ty = f.air.typeOfIndex(inst);
......@@ -5810,10 +5819,10 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
58105819 const target = f.object.dg.module.getTarget();
58115820 const operation = if (inst_ty.isRuntimeFloat() and operand_ty.isRuntimeFloat())
58125821 if (inst_ty.floatBits(target) < operand_ty.floatBits(target)) "trunc" else "extend"
5813 else if (inst_ty.isInt() and operand_ty.isRuntimeFloat())
5814 if (inst_ty.isSignedInt()) "fix" else "fixuns"
5815 else if (inst_ty.isRuntimeFloat() and operand_ty.isInt())
5816 if (operand_ty.isSignedInt()) "float" else "floatun"
5822 else if (inst_ty.isInt(mod) and operand_ty.isRuntimeFloat())
5823 if (inst_ty.isSignedInt(mod)) "fix" else "fixuns"
5824 else if (inst_ty.isRuntimeFloat() and operand_ty.isInt(mod))
5825 if (operand_ty.isSignedInt(mod)) "float" else "floatun"
58175826 else
58185827 unreachable;
58195828
......@@ -5822,19 +5831,19 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
58225831 try f.writeCValue(writer, local, .Other);
58235832
58245833 try writer.writeAll(" = ");
5825 if (inst_ty.isInt() and operand_ty.isRuntimeFloat()) {
5834 if (inst_ty.isInt(mod) and operand_ty.isRuntimeFloat()) {
58265835 try writer.writeAll("zig_wrap_");
58275836 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
58285837 try writer.writeByte('(');
58295838 }
58305839 try writer.writeAll("zig_");
58315840 try writer.writeAll(operation);
5832 try writer.writeAll(compilerRtAbbrev(operand_ty, target));
5833 try writer.writeAll(compilerRtAbbrev(inst_ty, target));
5841 try writer.writeAll(compilerRtAbbrev(operand_ty, mod));
5842 try writer.writeAll(compilerRtAbbrev(inst_ty, mod));
58345843 try writer.writeByte('(');
58355844 try f.writeCValue(writer, operand, .FunctionArgument);
58365845 try writer.writeByte(')');
5837 if (inst_ty.isInt() and operand_ty.isRuntimeFloat()) {
5846 if (inst_ty.isInt(mod) and operand_ty.isRuntimeFloat()) {
58385847 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);
58395848 try writer.writeByte(')');
58405849 }
......@@ -5871,14 +5880,15 @@ fn airUnBuiltinCall(
58715880 operation: []const u8,
58725881 info: BuiltinInfo,
58735882) !CValue {
5883 const mod = f.object.dg.module;
58745884 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
58755885
58765886 const operand = try f.resolveInst(ty_op.operand);
58775887 try reap(f, inst, &.{ty_op.operand});
58785888 const inst_ty = f.air.typeOfIndex(inst);
5879 const inst_scalar_ty = inst_ty.scalarType();
5889 const inst_scalar_ty = inst_ty.scalarType(mod);
58805890 const operand_ty = f.air.typeOf(ty_op.operand);
5881 const scalar_ty = operand_ty.scalarType();
5891 const scalar_ty = operand_ty.scalarType(mod);
58825892
58835893 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
58845894 const ref_ret = inst_scalar_cty.tag() == .array;
......@@ -5914,6 +5924,7 @@ fn airBinBuiltinCall(
59145924 operation: []const u8,
59155925 info: BuiltinInfo,
59165926) !CValue {
5927 const mod = f.object.dg.module;
59175928 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
59185929
59195930 const operand_ty = f.air.typeOf(bin_op.lhs);
......@@ -5925,8 +5936,8 @@ fn airBinBuiltinCall(
59255936 if (!is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
59265937
59275938 const inst_ty = f.air.typeOfIndex(inst);
5928 const inst_scalar_ty = inst_ty.scalarType();
5929 const scalar_ty = operand_ty.scalarType();
5939 const inst_scalar_ty = inst_ty.scalarType(mod);
5940 const scalar_ty = operand_ty.scalarType(mod);
59305941
59315942 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
59325943 const ref_ret = inst_scalar_cty.tag() == .array;
......@@ -5968,14 +5979,15 @@ fn airCmpBuiltinCall(
59685979 operation: enum { cmp, operator },
59695980 info: BuiltinInfo,
59705981) !CValue {
5982 const mod = f.object.dg.module;
59715983 const lhs = try f.resolveInst(data.lhs);
59725984 const rhs = try f.resolveInst(data.rhs);
59735985 try reap(f, inst, &.{ data.lhs, data.rhs });
59745986
59755987 const inst_ty = f.air.typeOfIndex(inst);
5976 const inst_scalar_ty = inst_ty.scalarType();
5988 const inst_scalar_ty = inst_ty.scalarType(mod);
59775989 const operand_ty = f.air.typeOf(data.lhs);
5978 const scalar_ty = operand_ty.scalarType();
5990 const scalar_ty = operand_ty.scalarType(mod);
59795991
59805992 const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete);
59815993 const ref_ret = inst_scalar_cty.tag() == .array;
......@@ -6017,6 +6029,7 @@ fn airCmpBuiltinCall(
60176029}
60186030
60196031fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {
6032 const mod = f.object.dg.module;
60206033 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
60216034 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
60226035 const inst_ty = f.air.typeOfIndex(inst);
......@@ -6030,15 +6043,13 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
60306043 const new_value_mat = try Materialize.start(f, inst, writer, ty, new_value);
60316044 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });
60326045
6033 const target = f.object.dg.module.getTarget();
6034 var repr_pl = Type.Payload.Bits{
6035 .base = .{ .tag = .int_unsigned },
6036 .data = @intCast(u16, ty.abiSize(target) * 8),
6037 };
6038 const repr_ty = if (ty.isRuntimeFloat()) Type.initPayload(&repr_pl.base) else ty;
6046 const repr_ty = if (ty.isRuntimeFloat())
6047 mod.intType(.unsigned, @intCast(u16, ty.abiSize(mod) * 8)) catch unreachable
6048 else
6049 ty;
60396050
60406051 const local = try f.allocLocal(inst, inst_ty);
6041 if (inst_ty.isPtrLikeOptional()) {
6052 if (inst_ty.isPtrLikeOptional(mod)) {
60426053 {
60436054 const a = try Assignment.start(f, writer, ty);
60446055 try f.writeCValue(writer, local, .Other);
......@@ -6123,6 +6134,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
61236134}
61246135
61256136fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6137 const mod = f.object.dg.module;
61266138 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
61276139 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
61286140 const inst_ty = f.air.typeOfIndex(inst);
......@@ -6135,14 +6147,10 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
61356147 const operand_mat = try Materialize.start(f, inst, writer, ty, operand);
61366148 try reap(f, inst, &.{ pl_op.operand, extra.operand });
61376149
6138 const target = f.object.dg.module.getTarget();
6139 var repr_pl = Type.Payload.Bits{
6140 .base = .{ .tag = .int_unsigned },
6141 .data = @intCast(u16, ty.abiSize(target) * 8),
6142 };
6150 const repr_bits = @intCast(u16, ty.abiSize(mod) * 8);
61436151 const is_float = ty.isRuntimeFloat();
6144 const is_128 = repr_pl.data == 128;
6145 const repr_ty = if (is_float) Type.initPayload(&repr_pl.base) else ty;
6152 const is_128 = repr_bits == 128;
6153 const repr_ty = if (is_float) mod.intType(.unsigned, repr_bits) catch unreachable else ty;
61466154
61476155 const local = try f.allocLocal(inst, inst_ty);
61486156 try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
......@@ -6181,18 +6189,17 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
61816189}
61826190
61836191fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6192 const mod = f.object.dg.module;
61846193 const atomic_load = f.air.instructions.items(.data)[inst].atomic_load;
61856194 const ptr = try f.resolveInst(atomic_load.ptr);
61866195 try reap(f, inst, &.{atomic_load.ptr});
61876196 const ptr_ty = f.air.typeOf(atomic_load.ptr);
61886197 const ty = ptr_ty.childType();
61896198
6190 const target = f.object.dg.module.getTarget();
6191 var repr_pl = Type.Payload.Bits{
6192 .base = .{ .tag = .int_unsigned },
6193 .data = @intCast(u16, ty.abiSize(target) * 8),
6194 };
6195 const repr_ty = if (ty.isRuntimeFloat()) Type.initPayload(&repr_pl.base) else ty;
6199 const repr_ty = if (ty.isRuntimeFloat())
6200 mod.intType(.unsigned, @intCast(u16, ty.abiSize(mod) * 8)) catch unreachable
6201 else
6202 ty;
61966203
61976204 const inst_ty = f.air.typeOfIndex(inst);
61986205 const writer = f.object.writer();
......@@ -6218,6 +6225,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
62186225}
62196226
62206227fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {
6228 const mod = f.object.dg.module;
62216229 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
62226230 const ptr_ty = f.air.typeOf(bin_op.lhs);
62236231 const ty = ptr_ty.childType();
......@@ -6228,12 +6236,10 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
62286236 const element_mat = try Materialize.start(f, inst, writer, ty, element);
62296237 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
62306238
6231 const target = f.object.dg.module.getTarget();
6232 var repr_pl = Type.Payload.Bits{
6233 .base = .{ .tag = .int_unsigned },
6234 .data = @intCast(u16, ty.abiSize(target) * 8),
6235 };
6236 const repr_ty = if (ty.isRuntimeFloat()) Type.initPayload(&repr_pl.base) else ty;
6239 const repr_ty = if (ty.isRuntimeFloat())
6240 mod.intType(.unsigned, @intCast(u16, ty.abiSize(mod) * 8)) catch unreachable
6241 else
6242 ty;
62376243
62386244 try writer.writeAll("zig_atomic_store((zig_atomic(");
62396245 try f.renderType(writer, ty);
......@@ -6262,14 +6268,14 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo
62626268}
62636269
62646270fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6271 const mod = f.object.dg.module;
62656272 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
62666273 const dest_ty = f.air.typeOf(bin_op.lhs);
62676274 const dest_slice = try f.resolveInst(bin_op.lhs);
62686275 const value = try f.resolveInst(bin_op.rhs);
62696276 const elem_ty = f.air.typeOf(bin_op.rhs);
6270 const target = f.object.dg.module.getTarget();
6271 const elem_abi_size = elem_ty.abiSize(target);
6272 const val_is_undef = if (f.air.value(bin_op.rhs)) |val| val.isUndefDeep() else false;
6277 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;
62736279 const writer = f.object.writer();
62746280
62756281 if (val_is_undef) {
......@@ -6383,12 +6389,12 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
63836389}
63846390
63856391fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
6392 const mod = f.object.dg.module;
63866393 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
63876394 const dest_ptr = try f.resolveInst(bin_op.lhs);
63886395 const src_ptr = try f.resolveInst(bin_op.rhs);
63896396 const dest_ty = f.air.typeOf(bin_op.lhs);
63906397 const src_ty = f.air.typeOf(bin_op.rhs);
6391 const target = f.object.dg.module.getTarget();
63926398 const writer = f.object.writer();
63936399
63946400 try writer.writeAll("memcpy(");
......@@ -6399,7 +6405,7 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
63996405 switch (dest_ty.ptrSize()) {
64006406 .Slice => {
64016407 const elem_ty = dest_ty.childType();
6402 const elem_abi_size = elem_ty.abiSize(target);
6408 const elem_abi_size = elem_ty.abiSize(mod);
64036409 try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" });
64046410 if (elem_abi_size > 1) {
64056411 try writer.print(" * {d});\n", .{elem_abi_size});
......@@ -6410,7 +6416,7 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
64106416 .One => {
64116417 const array_ty = dest_ty.childType();
64126418 const elem_ty = array_ty.childType();
6413 const elem_abi_size = elem_ty.abiSize(target);
6419 const elem_abi_size = elem_ty.abiSize(mod);
64146420 const len = array_ty.arrayLen() * elem_abi_size;
64156421 try writer.print("{d});\n", .{len});
64166422 },
......@@ -6422,14 +6428,14 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
64226428}
64236429
64246430fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6431 const mod = f.object.dg.module;
64256432 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
64266433 const union_ptr = try f.resolveInst(bin_op.lhs);
64276434 const new_tag = try f.resolveInst(bin_op.rhs);
64286435 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
64296436
6430 const target = f.object.dg.module.getTarget();
64316437 const union_ty = f.air.typeOf(bin_op.lhs).childType();
6432 const layout = union_ty.unionGetLayout(target);
6438 const layout = union_ty.unionGetLayout(mod);
64336439 if (layout.tag_size == 0) return .none;
64346440 const tag_ty = union_ty.unionTagTypeSafety().?;
64356441
......@@ -6443,14 +6449,14 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
64436449}
64446450
64456451fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6452 const mod = f.object.dg.module;
64466453 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
64476454
64486455 const operand = try f.resolveInst(ty_op.operand);
64496456 try reap(f, inst, &.{ty_op.operand});
64506457
64516458 const union_ty = f.air.typeOf(ty_op.operand);
6452 const target = f.object.dg.module.getTarget();
6453 const layout = union_ty.unionGetLayout(target);
6459 const layout = union_ty.unionGetLayout(mod);
64546460 if (layout.tag_size == 0) return .none;
64556461
64566462 const inst_ty = f.air.typeOfIndex(inst);
......@@ -6501,13 +6507,14 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
65016507}
65026508
65036509fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
6510 const mod = f.object.dg.module;
65046511 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
65056512
65066513 const operand = try f.resolveInst(ty_op.operand);
65076514 try reap(f, inst, &.{ty_op.operand});
65086515
65096516 const inst_ty = f.air.typeOfIndex(inst);
6510 const inst_scalar_ty = inst_ty.scalarType();
6517 const inst_scalar_ty = inst_ty.scalarType(mod);
65116518
65126519 const writer = f.object.writer();
65136520 const local = try f.allocLocal(inst, inst_ty);
......@@ -6555,6 +6562,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
65556562}
65566563
65576564fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
6565 const mod = f.object.dg.module;
65586566 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
65596567 const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data;
65606568
......@@ -6562,8 +6570,6 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
65626570 const lhs = try f.resolveInst(extra.a);
65636571 const rhs = try f.resolveInst(extra.b);
65646572
6565 const module = f.object.dg.module;
6566 const target = module.getTarget();
65676573 const inst_ty = f.air.typeOfIndex(inst);
65686574
65696575 const writer = f.object.writer();
......@@ -6581,7 +6587,7 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
65816587 try writer.writeAll("] = ");
65826588
65836589 var buf: Value.ElemValueBuffer = undefined;
6584 const mask_elem = mask.elemValueBuffer(module, index, &buf).toSignedInt(target);
6590 const mask_elem = mask.elemValueBuffer(mod, index, &buf).toSignedInt(mod);
65856591 var src_pl = Value.Payload.U64{
65866592 .base = .{ .tag = .int_u64 },
65876593 .data = @intCast(u64, mask_elem ^ mask_elem >> 63),
......@@ -6597,16 +6603,17 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
65976603}
65986604
65996605fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6606 const mod = f.object.dg.module;
66006607 const reduce = f.air.instructions.items(.data)[inst].reduce;
66016608
6602 const target = f.object.dg.module.getTarget();
6609 const target = mod.getTarget();
66036610 const scalar_ty = f.air.typeOfIndex(inst);
66046611 const operand = try f.resolveInst(reduce.operand);
66056612 try reap(f, inst, &.{reduce.operand});
66066613 const operand_ty = f.air.typeOf(reduce.operand);
66076614 const writer = f.object.writer();
66086615
6609 const use_operator = scalar_ty.bitSize(target) <= 64;
6616 const use_operator = scalar_ty.bitSize(mod) <= 64;
66106617 const op: union(enum) {
66116618 const Func = struct { operation: []const u8, info: BuiltinInfo = .none };
66126619 float_op: Func,
......@@ -6617,28 +6624,28 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
66176624 .And => if (use_operator) .{ .infix = " &= " } else .{ .builtin = .{ .operation = "and" } },
66186625 .Or => if (use_operator) .{ .infix = " |= " } else .{ .builtin = .{ .operation = "or" } },
66196626 .Xor => if (use_operator) .{ .infix = " ^= " } else .{ .builtin = .{ .operation = "xor" } },
6620 .Min => switch (scalar_ty.zigTypeTag()) {
6627 .Min => switch (scalar_ty.zigTypeTag(mod)) {
66216628 .Int => if (use_operator) .{ .ternary = " < " } else .{
66226629 .builtin = .{ .operation = "min" },
66236630 },
66246631 .Float => .{ .float_op = .{ .operation = "fmin" } },
66256632 else => unreachable,
66266633 },
6627 .Max => switch (scalar_ty.zigTypeTag()) {
6634 .Max => switch (scalar_ty.zigTypeTag(mod)) {
66286635 .Int => if (use_operator) .{ .ternary = " > " } else .{
66296636 .builtin = .{ .operation = "max" },
66306637 },
66316638 .Float => .{ .float_op = .{ .operation = "fmax" } },
66326639 else => unreachable,
66336640 },
6634 .Add => switch (scalar_ty.zigTypeTag()) {
6641 .Add => switch (scalar_ty.zigTypeTag(mod)) {
66356642 .Int => if (use_operator) .{ .infix = " += " } else .{
66366643 .builtin = .{ .operation = "addw", .info = .bits },
66376644 },
66386645 .Float => .{ .builtin = .{ .operation = "add" } },
66396646 else => unreachable,
66406647 },
6641 .Mul => switch (scalar_ty.zigTypeTag()) {
6648 .Mul => switch (scalar_ty.zigTypeTag(mod)) {
66426649 .Int => if (use_operator) .{ .infix = " *= " } else .{
66436650 .builtin = .{ .operation = "mulw", .info = .bits },
66446651 },
......@@ -6680,22 +6687,22 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
66806687
66816688 try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) {
66826689 .Or, .Xor, .Add => Value.zero,
6683 .And => switch (scalar_ty.zigTypeTag()) {
6690 .And => switch (scalar_ty.zigTypeTag(mod)) {
66846691 .Bool => Value.one,
6685 else => switch (scalar_ty.intInfo(target).signedness) {
6686 .unsigned => try scalar_ty.maxInt(stack.get(), target),
6692 else => switch (scalar_ty.intInfo(mod).signedness) {
6693 .unsigned => try scalar_ty.maxInt(stack.get(), mod),
66876694 .signed => Value.negative_one,
66886695 },
66896696 },
6690 .Min => switch (scalar_ty.zigTypeTag()) {
6697 .Min => switch (scalar_ty.zigTypeTag(mod)) {
66916698 .Bool => Value.one,
6692 .Int => try scalar_ty.maxInt(stack.get(), target),
6699 .Int => try scalar_ty.maxInt(stack.get(), mod),
66936700 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),
66946701 else => unreachable,
66956702 },
6696 .Max => switch (scalar_ty.zigTypeTag()) {
6703 .Max => switch (scalar_ty.zigTypeTag(mod)) {
66976704 .Bool => Value.zero,
6698 .Int => try scalar_ty.minInt(stack.get(), target),
6705 .Int => try scalar_ty.minInt(stack.get(), mod),
66996706 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),
67006707 else => unreachable,
67016708 },
......@@ -6753,6 +6760,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
67536760}
67546761
67556762fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6763 const mod = f.object.dg.module;
67566764 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
67576765 const inst_ty = f.air.typeOfIndex(inst);
67586766 const len = @intCast(usize, inst_ty.arrayLen());
......@@ -6770,11 +6778,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
67706778 }
67716779 }
67726780
6773 const target = f.object.dg.module.getTarget();
6774
67756781 const writer = f.object.writer();
67766782 const local = try f.allocLocal(inst, inst_ty);
6777 switch (inst_ty.zigTypeTag()) {
6783 switch (inst_ty.zigTypeTag(mod)) {
67786784 .Array, .Vector => {
67796785 const elem_ty = inst_ty.childType();
67806786 const a = try Assignment.init(f, elem_ty);
......@@ -6799,7 +6805,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
67996805 .Auto, .Extern => for (resolved_elements, 0..) |element, field_i| {
68006806 if (inst_ty.structFieldIsComptime(field_i)) continue;
68016807 const field_ty = inst_ty.structFieldType(field_i);
6802 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
6808 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
68036809
68046810 const a = try Assignment.start(f, writer, field_ty);
68056811 try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple())
......@@ -6813,13 +6819,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
68136819 .Packed => {
68146820 try f.writeCValue(writer, local, .Other);
68156821 try writer.writeAll(" = ");
6816 const int_info = inst_ty.intInfo(target);
6822 const int_info = inst_ty.intInfo(mod);
68176823
6818 var bit_offset_ty_pl = Type.Payload.Bits{
6819 .base = .{ .tag = .int_unsigned },
6820 .data = Type.smallestUnsignedBits(int_info.bits - 1),
6821 };
6822 const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base);
6824 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
68236825
68246826 var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 };
68256827 const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base);
......@@ -6828,7 +6830,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
68286830 for (0..elements.len) |field_i| {
68296831 if (inst_ty.structFieldIsComptime(field_i)) continue;
68306832 const field_ty = inst_ty.structFieldType(field_i);
6831 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
6833 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
68326834
68336835 if (!empty) {
68346836 try writer.writeAll("zig_or_");
......@@ -6841,7 +6843,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
68416843 for (resolved_elements, 0..) |element, field_i| {
68426844 if (inst_ty.structFieldIsComptime(field_i)) continue;
68436845 const field_ty = inst_ty.structFieldType(field_i);
6844 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
6846 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
68456847
68466848 if (!empty) try writer.writeAll(", ");
68476849 // TODO: Skip this entire shift if val is 0?
......@@ -6849,13 +6851,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
68496851 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
68506852 try writer.writeByte('(');
68516853
6852 if (inst_ty.isAbiInt() and (field_ty.isAbiInt() or field_ty.isPtrAtRuntime())) {
6854 if (inst_ty.isAbiInt(mod) and (field_ty.isAbiInt(mod) or field_ty.isPtrAtRuntime(mod))) {
68536855 try f.renderIntCast(writer, inst_ty, element, .{}, field_ty, .FunctionArgument);
68546856 } else {
68556857 try writer.writeByte('(');
68566858 try f.renderType(writer, inst_ty);
68576859 try writer.writeByte(')');
6858 if (field_ty.isPtrAtRuntime()) {
6860 if (field_ty.isPtrAtRuntime(mod)) {
68596861 try writer.writeByte('(');
68606862 try f.renderType(writer, switch (int_info.signedness) {
68616863 .unsigned => Type.usize,
......@@ -6872,7 +6874,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
68726874 try writer.writeByte(')');
68736875 if (!empty) try writer.writeByte(')');
68746876
6875 bit_offset_val_pl.data += field_ty.bitSize(target);
6877 bit_offset_val_pl.data += field_ty.bitSize(mod);
68766878 empty = false;
68776879 }
68786880
......@@ -6886,11 +6888,11 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
68866888}
68876889
68886890fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
6891 const mod = f.object.dg.module;
68896892 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
68906893 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
68916894
68926895 const union_ty = f.air.typeOfIndex(inst);
6893 const target = f.object.dg.module.getTarget();
68946896 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
68956897 const field_name = union_obj.fields.keys()[extra.field_index];
68966898 const payload_ty = f.air.typeOf(extra.init);
......@@ -6908,7 +6910,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
69086910 }
69096911
69106912 const field: CValue = if (union_ty.unionTagTypeSafety()) |tag_ty| field: {
6911 const layout = union_ty.unionGetLayout(target);
6913 const layout = union_ty.unionGetLayout(mod);
69126914 if (layout.tag_size != 0) {
69136915 const field_index = tag_ty.enumFieldIndex(field_name).?;
69146916
......@@ -6991,13 +6993,14 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
69916993}
69926994
69936995fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
6996 const mod = f.object.dg.module;
69946997 const un_op = f.air.instructions.items(.data)[inst].un_op;
69956998
69966999 const operand = try f.resolveInst(un_op);
69977000 try reap(f, inst, &.{un_op});
69987001
69997002 const operand_ty = f.air.typeOf(un_op);
7000 const scalar_ty = operand_ty.scalarType();
7003 const scalar_ty = operand_ty.scalarType(mod);
70017004
70027005 const writer = f.object.writer();
70037006 const local = try f.allocLocal(inst, operand_ty);
......@@ -7016,13 +7019,14 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
70167019}
70177020
70187021fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {
7022 const mod = f.object.dg.module;
70197023 const un_op = f.air.instructions.items(.data)[inst].un_op;
70207024
70217025 const operand = try f.resolveInst(un_op);
70227026 try reap(f, inst, &.{un_op});
70237027
70247028 const inst_ty = f.air.typeOfIndex(inst);
7025 const inst_scalar_ty = inst_ty.scalarType();
7029 const inst_scalar_ty = inst_ty.scalarType(mod);
70267030
70277031 const writer = f.object.writer();
70287032 const local = try f.allocLocal(inst, inst_ty);
......@@ -7043,6 +7047,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
70437047}
70447048
70457049fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {
7050 const mod = f.object.dg.module;
70467051 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
70477052
70487053 const lhs = try f.resolveInst(bin_op.lhs);
......@@ -7050,7 +7055,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
70507055 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
70517056
70527057 const inst_ty = f.air.typeOfIndex(inst);
7053 const inst_scalar_ty = inst_ty.scalarType();
7058 const inst_scalar_ty = inst_ty.scalarType(mod);
70547059
70557060 const writer = f.object.writer();
70567061 const local = try f.allocLocal(inst, inst_ty);
......@@ -7074,6 +7079,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
70747079}
70757080
70767081fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7082 const mod = f.object.dg.module;
70777083 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
70787084 const bin_op = f.air.extraData(Air.Bin, pl_op.payload).data;
70797085
......@@ -7083,7 +7089,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
70837089 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });
70847090
70857091 const inst_ty = f.air.typeOfIndex(inst);
7086 const inst_scalar_ty = inst_ty.scalarType();
7092 const inst_scalar_ty = inst_ty.scalarType(mod);
70877093
70887094 const writer = f.object.writer();
70897095 const local = try f.allocLocal(inst, inst_ty);
......@@ -7279,8 +7285,9 @@ fn signAbbrev(signedness: std.builtin.Signedness) u8 {
72797285 };
72807286}
72817287
7282fn compilerRtAbbrev(ty: Type, target: std.Target) []const u8 {
7283 return if (ty.isInt()) switch (ty.intInfo(target).bits) {
7288fn compilerRtAbbrev(ty: Type, mod: *Module) []const u8 {
7289 const target = mod.getTarget();
7290 return if (ty.isInt(mod)) switch (ty.intInfo(mod).bits) {
72847291 1...32 => "si",
72857292 33...64 => "di",
72867293 65...128 => "ti",
......@@ -7407,7 +7414,7 @@ fn undefPattern(comptime IntType: type) IntType {
74077414
74087415const FormatIntLiteralContext = struct {
74097416 dg: *DeclGen,
7410 int_info: std.builtin.Type.Int,
7417 int_info: InternPool.Key.IntType,
74117418 kind: CType.Kind,
74127419 cty: CType,
74137420 val: Value,
......@@ -7418,7 +7425,8 @@ fn formatIntLiteral(
74187425 options: std.fmt.FormatOptions,
74197426 writer: anytype,
74207427) @TypeOf(writer).Error!void {
7421 const target = data.dg.module.getTarget();
7428 const mod = data.dg.module;
7429 const target = mod.getTarget();
74227430
74237431 const ExpectedContents = struct {
74247432 const base = 10;
......@@ -7449,7 +7457,7 @@ fn formatIntLiteral(
74497457 };
74507458 undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits);
74517459 break :blk undef_int.toConst();
7452 } else data.val.toBigInt(&int_buf, target);
7460 } else data.val.toBigInt(&int_buf, mod);
74537461 assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits));
74547462
74557463 const c_bits = @intCast(usize, data.cty.byteSize(data.dg.ctypes.set, target) * 8);
......@@ -7684,7 +7692,8 @@ const Vectorize = struct {
76847692 index: CValue = .none,
76857693
76867694 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {
7687 return if (ty.zigTypeTag() == .Vector) index: {
7695 const mod = f.object.dg.module;
7696 return if (ty.zigTypeTag(mod) == .Vector) index: {
76887697 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() };
76897698
76907699 const local = try f.allocLocal(inst, Type.usize);
......@@ -7727,10 +7736,10 @@ const LowerFnRetTyBuffer = struct {
77277736 values: [1]Value,
77287737 payload: Type.Payload.AnonStruct,
77297738};
7730fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) Type {
7731 if (ret_ty.zigTypeTag() == .NoReturn) return Type.initTag(.noreturn);
7739fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *const Module) Type {
7740 if (ret_ty.zigTypeTag(mod) == .NoReturn) return Type.initTag(.noreturn);
77327741
7733 if (lowersToArray(ret_ty, target)) {
7742 if (lowersToArray(ret_ty, mod)) {
77347743 buffer.names = [1][]const u8{"array"};
77357744 buffer.types = [1]Type{ret_ty};
77367745 buffer.values = [1]Value{Value.initTag(.unreachable_value)};
......@@ -7742,13 +7751,13 @@ fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) T
77427751 return Type.initPayload(&buffer.payload.base);
77437752 }
77447753
7745 return if (ret_ty.hasRuntimeBitsIgnoreComptime()) ret_ty else Type.void;
7754 return if (ret_ty.hasRuntimeBitsIgnoreComptime(mod)) ret_ty else Type.void;
77467755}
77477756
7748fn lowersToArray(ty: Type, target: std.Target) bool {
7749 return switch (ty.zigTypeTag()) {
7757fn lowersToArray(ty: Type, mod: *const Module) bool {
7758 return switch (ty.zigTypeTag(mod)) {
77507759 .Array, .Vector => return true,
7751 else => return ty.isAbiInt() and toCIntBits(@intCast(u32, ty.bitSize(target))) == null,
7760 else => return ty.isAbiInt(mod) and toCIntBits(@intCast(u32, ty.bitSize(mod))) == null,
77527761 };
77537762}
77547763
src/codegen/c/type.zig+74-76
......@@ -292,19 +292,19 @@ pub const CType = extern union {
292292 .abi = std.math.log2_int(u32, abi_alignment),
293293 };
294294 }
295 pub fn abiAlign(ty: Type, target: Target) AlignAs {
296 const abi_align = ty.abiAlignment(target);
295 pub fn abiAlign(ty: Type, mod: *const Module) AlignAs {
296 const abi_align = ty.abiAlignment(mod);
297297 return init(abi_align, abi_align);
298298 }
299 pub fn fieldAlign(struct_ty: Type, field_i: usize, target: Target) AlignAs {
299 pub fn fieldAlign(struct_ty: Type, field_i: usize, mod: *const Module) AlignAs {
300300 return init(
301 struct_ty.structFieldAlign(field_i, target),
302 struct_ty.structFieldType(field_i).abiAlignment(target),
301 struct_ty.structFieldAlign(field_i, mod),
302 struct_ty.structFieldType(field_i).abiAlignment(mod),
303303 );
304304 }
305 pub fn unionPayloadAlign(union_ty: Type, target: Target) AlignAs {
305 pub fn unionPayloadAlign(union_ty: Type, mod: *const Module) AlignAs {
306306 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
307 const union_payload_align = union_obj.abiAlignment(target, false);
307 const union_payload_align = union_obj.abiAlignment(mod, false);
308308 return init(union_payload_align, union_payload_align);
309309 }
310310
......@@ -344,8 +344,8 @@ pub const CType = extern union {
344344 return self.map.entries.items(.hash)[index - Tag.no_payload_count];
345345 }
346346
347 pub fn typeToIndex(self: Set, ty: Type, target: Target, kind: Kind) ?Index {
348 const lookup = Convert.Lookup{ .imm = .{ .set = &self, .target = target } };
347 pub fn typeToIndex(self: Set, ty: Type, mod: *Module, kind: Kind) ?Index {
348 const lookup = Convert.Lookup{ .imm = .{ .set = &self, .mod = mod } };
349349
350350 var convert: Convert = undefined;
351351 convert.initType(ty, kind, lookup) catch unreachable;
......@@ -405,7 +405,7 @@ pub const CType = extern union {
405405 );
406406 if (!gop.found_existing) {
407407 errdefer _ = self.set.map.pop();
408 gop.key_ptr.* = try createFromConvert(self, ty, lookup.getTarget(), kind, convert);
408 gop.key_ptr.* = try createFromConvert(self, ty, lookup.getModule(), kind, convert);
409409 }
410410 if (std.debug.runtime_safety) {
411411 const adapter = TypeAdapter64{
......@@ -1236,10 +1236,10 @@ pub const CType = extern union {
12361236 }
12371237
12381238 pub const Lookup = union(enum) {
1239 fail: Target,
1239 fail: *Module,
12401240 imm: struct {
12411241 set: *const Store.Set,
1242 target: Target,
1242 mod: *Module,
12431243 },
12441244 mut: struct {
12451245 promoted: *Store.Promoted,
......@@ -1254,10 +1254,14 @@ pub const CType = extern union {
12541254 }
12551255
12561256 pub fn getTarget(self: @This()) Target {
1257 return self.getModule().getTarget();
1258 }
1259
1260 pub fn getModule(self: @This()) *Module {
12571261 return switch (self) {
1258 .fail => |target| target,
1259 .imm => |imm| imm.target,
1260 .mut => |mut| mut.mod.getTarget(),
1262 .fail => |mod| mod,
1263 .imm => |imm| imm.mod,
1264 .mut => |mut| mut.mod,
12611265 };
12621266 }
12631267
......@@ -1272,7 +1276,7 @@ pub const CType = extern union {
12721276 pub fn typeToIndex(self: @This(), ty: Type, kind: Kind) !?Index {
12731277 return switch (self) {
12741278 .fail => null,
1275 .imm => |imm| imm.set.typeToIndex(ty, imm.target, kind),
1279 .imm => |imm| imm.set.typeToIndex(ty, imm.mod, kind),
12761280 .mut => |mut| try mut.promoted.typeToIndex(ty, mut.mod, kind),
12771281 };
12781282 }
......@@ -1284,7 +1288,7 @@ pub const CType = extern union {
12841288 pub fn freeze(self: @This()) @This() {
12851289 return switch (self) {
12861290 .fail, .imm => self,
1287 .mut => |mut| .{ .imm = .{ .set = &mut.promoted.set, .target = self.getTarget() } },
1291 .mut => |mut| .{ .imm = .{ .set = &mut.promoted.set, .mod = mut.mod } },
12881292 };
12891293 }
12901294 };
......@@ -1338,7 +1342,7 @@ pub const CType = extern union {
13381342 self.storage.anon.fields[0] = .{
13391343 .name = "array",
13401344 .type = array_idx,
1341 .alignas = AlignAs.abiAlign(ty, lookup.getTarget()),
1345 .alignas = AlignAs.abiAlign(ty, lookup.getModule()),
13421346 };
13431347 self.initAnon(kind, fwd_idx, 1);
13441348 } else self.init(switch (kind) {
......@@ -1350,12 +1354,12 @@ pub const CType = extern union {
13501354 }
13511355
13521356 pub fn initType(self: *@This(), ty: Type, kind: Kind, lookup: Lookup) !void {
1353 const target = lookup.getTarget();
1357 const mod = lookup.getModule();
13541358
13551359 self.* = undefined;
1356 if (!ty.isFnOrHasRuntimeBitsIgnoreComptime())
1360 if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(mod))
13571361 self.init(.void)
1358 else if (ty.isAbiInt()) switch (ty.tag()) {
1362 else if (ty.isAbiInt(mod)) switch (ty.tag()) {
13591363 .usize => self.init(.uintptr_t),
13601364 .isize => self.init(.intptr_t),
13611365 .c_char => self.init(.char),
......@@ -1367,13 +1371,13 @@ pub const CType = extern union {
13671371 .c_ulong => self.init(.@"unsigned long"),
13681372 .c_longlong => self.init(.@"long long"),
13691373 .c_ulonglong => self.init(.@"unsigned long long"),
1370 else => switch (tagFromIntInfo(ty.intInfo(target))) {
1374 else => switch (tagFromIntInfo(ty.intInfo(mod))) {
13711375 .void => unreachable,
13721376 else => |t| self.init(t),
13731377 .array => switch (kind) {
13741378 .forward, .complete, .global => {
1375 const abi_size = ty.abiSize(target);
1376 const abi_align = ty.abiAlignment(target);
1379 const abi_size = ty.abiSize(mod);
1380 const abi_align = ty.abiAlignment(mod);
13771381 self.storage = .{ .seq = .{ .base = .{ .tag = .array }, .data = .{
13781382 .len = @divExact(abi_size, abi_align),
13791383 .elem_type = tagFromIntInfo(.{
......@@ -1389,7 +1393,7 @@ pub const CType = extern union {
13891393 .payload => unreachable,
13901394 },
13911395 },
1392 } else switch (ty.zigTypeTag()) {
1396 } else switch (ty.zigTypeTag(mod)) {
13931397 .Frame => unreachable,
13941398 .AnyFrame => unreachable,
13951399
......@@ -1434,12 +1438,12 @@ pub const CType = extern union {
14341438 self.storage.anon.fields[0] = .{
14351439 .name = "ptr",
14361440 .type = ptr_idx,
1437 .alignas = AlignAs.abiAlign(ptr_ty, target),
1441 .alignas = AlignAs.abiAlign(ptr_ty, mod),
14381442 };
14391443 self.storage.anon.fields[1] = .{
14401444 .name = "len",
14411445 .type = Tag.uintptr_t.toIndex(),
1442 .alignas = AlignAs.abiAlign(Type.usize, target),
1446 .alignas = AlignAs.abiAlign(Type.usize, mod),
14431447 };
14441448 self.initAnon(kind, fwd_idx, 2);
14451449 } else self.init(switch (kind) {
......@@ -1462,12 +1466,8 @@ pub const CType = extern union {
14621466 },
14631467 };
14641468
1465 var host_int_pl = Type.Payload.Bits{
1466 .base = .{ .tag = .int_unsigned },
1467 .data = info.host_size * 8,
1468 };
14691469 const pointee_ty = if (info.host_size > 0 and info.vector_index == .none)
1470 Type.initPayload(&host_int_pl.base)
1470 try mod.intType(.unsigned, info.host_size * 8)
14711471 else
14721472 info.pointee_type;
14731473
......@@ -1490,11 +1490,9 @@ pub const CType = extern union {
14901490 if (ty.castTag(.@"struct")) |struct_obj| {
14911491 try self.initType(struct_obj.data.backing_int_ty, kind, lookup);
14921492 } else {
1493 var buf: Type.Payload.Bits = .{
1494 .base = .{ .tag = .int_unsigned },
1495 .data = @intCast(u16, ty.bitSize(target)),
1496 };
1497 try self.initType(Type.initPayload(&buf.base), kind, lookup);
1493 const bits = @intCast(u16, ty.bitSize(mod));
1494 const int_ty = try mod.intType(.unsigned, bits);
1495 try self.initType(int_ty, kind, lookup);
14981496 }
14991497 } else if (ty.isTupleOrAnonStruct()) {
15001498 if (lookup.isMutable()) {
......@@ -1505,7 +1503,7 @@ pub const CType = extern union {
15051503 }) |field_i| {
15061504 const field_ty = ty.structFieldType(field_i);
15071505 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or
1508 !field_ty.hasRuntimeBitsIgnoreComptime()) continue;
1506 !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
15091507 _ = try lookup.typeToIndex(field_ty, switch (kind) {
15101508 .forward, .forward_parameter => .forward,
15111509 .complete, .parameter => .complete,
......@@ -1555,7 +1553,7 @@ pub const CType = extern union {
15551553 self.storage.anon.fields[field_count] = .{
15561554 .name = "payload",
15571555 .type = payload_idx.?,
1558 .alignas = AlignAs.unionPayloadAlign(ty, target),
1556 .alignas = AlignAs.unionPayloadAlign(ty, mod),
15591557 };
15601558 field_count += 1;
15611559 }
......@@ -1563,7 +1561,7 @@ pub const CType = extern union {
15631561 self.storage.anon.fields[field_count] = .{
15641562 .name = "tag",
15651563 .type = tag_idx.?,
1566 .alignas = AlignAs.abiAlign(tag_ty.?, target),
1564 .alignas = AlignAs.abiAlign(tag_ty.?, mod),
15671565 };
15681566 field_count += 1;
15691567 }
......@@ -1576,7 +1574,7 @@ pub const CType = extern union {
15761574 } };
15771575 self.value = .{ .cty = initPayload(&self.storage.anon.pl.complete) };
15781576 } else self.init(.@"struct");
1579 } else if (kind == .payload and ty.unionHasAllZeroBitFieldTypes()) {
1577 } else if (kind == .payload and ty.unionHasAllZeroBitFieldTypes(mod)) {
15801578 self.init(.void);
15811579 } else {
15821580 var is_packed = false;
......@@ -1586,9 +1584,9 @@ pub const CType = extern union {
15861584 else => unreachable,
15871585 }) |field_i| {
15881586 const field_ty = ty.structFieldType(field_i);
1589 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
1587 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
15901588
1591 const field_align = AlignAs.fieldAlign(ty, field_i, target);
1589 const field_align = AlignAs.fieldAlign(ty, field_i, mod);
15921590 if (field_align.@"align" < field_align.abi) {
15931591 is_packed = true;
15941592 if (!lookup.isMutable()) break;
......@@ -1643,8 +1641,8 @@ pub const CType = extern union {
16431641 .Optional => {
16441642 var buf: Type.Payload.ElemType = undefined;
16451643 const payload_ty = ty.optionalChild(&buf);
1646 if (payload_ty.hasRuntimeBitsIgnoreComptime()) {
1647 if (ty.optionalReprIsPayload()) {
1644 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1645 if (ty.optionalReprIsPayload(mod)) {
16481646 try self.initType(payload_ty, kind, lookup);
16491647 } else if (switch (kind) {
16501648 .forward, .forward_parameter => @as(Index, undefined),
......@@ -1661,12 +1659,12 @@ pub const CType = extern union {
16611659 self.storage.anon.fields[0] = .{
16621660 .name = "payload",
16631661 .type = payload_idx,
1664 .alignas = AlignAs.abiAlign(payload_ty, target),
1662 .alignas = AlignAs.abiAlign(payload_ty, mod),
16651663 };
16661664 self.storage.anon.fields[1] = .{
16671665 .name = "is_null",
16681666 .type = Tag.bool.toIndex(),
1669 .alignas = AlignAs.abiAlign(Type.bool, target),
1667 .alignas = AlignAs.abiAlign(Type.bool, mod),
16701668 };
16711669 self.initAnon(kind, fwd_idx, 2);
16721670 } else self.init(switch (kind) {
......@@ -1699,12 +1697,12 @@ pub const CType = extern union {
16991697 self.storage.anon.fields[0] = .{
17001698 .name = "payload",
17011699 .type = payload_idx,
1702 .alignas = AlignAs.abiAlign(payload_ty, target),
1700 .alignas = AlignAs.abiAlign(payload_ty, mod),
17031701 };
17041702 self.storage.anon.fields[1] = .{
17051703 .name = "error",
17061704 .type = error_idx,
1707 .alignas = AlignAs.abiAlign(error_ty, target),
1705 .alignas = AlignAs.abiAlign(error_ty, mod),
17081706 };
17091707 self.initAnon(kind, fwd_idx, 2);
17101708 } else self.init(switch (kind) {
......@@ -1733,7 +1731,7 @@ pub const CType = extern union {
17331731 };
17341732 _ = try lookup.typeToIndex(info.return_type, param_kind);
17351733 for (info.param_types) |param_type| {
1736 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;
1734 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
17371735 _ = try lookup.typeToIndex(param_type, param_kind);
17381736 }
17391737 }
......@@ -1900,16 +1898,16 @@ pub const CType = extern union {
19001898 }
19011899 }
19021900
1903 fn createFromType(store: *Store.Promoted, ty: Type, target: Target, kind: Kind) !CType {
1901 fn createFromType(store: *Store.Promoted, ty: Type, mod: *const Module, kind: Kind) !CType {
19041902 var convert: Convert = undefined;
1905 try convert.initType(ty, kind, .{ .imm = .{ .set = &store.set, .target = target } });
1906 return createFromConvert(store, ty, target, kind, &convert);
1903 try convert.initType(ty, kind, .{ .imm = .{ .set = &store.set, .mod = mod } });
1904 return createFromConvert(store, ty, mod, kind, &convert);
19071905 }
19081906
19091907 fn createFromConvert(
19101908 store: *Store.Promoted,
19111909 ty: Type,
1912 target: Target,
1910 mod: *Module,
19131911 kind: Kind,
19141912 convert: Convert,
19151913 ) !CType {
......@@ -1930,7 +1928,7 @@ pub const CType = extern union {
19301928 .packed_struct,
19311929 .packed_union,
19321930 => {
1933 const zig_ty_tag = ty.zigTypeTag();
1931 const zig_ty_tag = ty.zigTypeTag(mod);
19341932 const fields_len = switch (zig_ty_tag) {
19351933 .Struct => ty.structFieldCount(),
19361934 .Union => ty.unionFields().count(),
......@@ -1941,7 +1939,7 @@ pub const CType = extern union {
19411939 for (0..fields_len) |field_i| {
19421940 const field_ty = ty.structFieldType(field_i);
19431941 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or
1944 !field_ty.hasRuntimeBitsIgnoreComptime()) continue;
1942 !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
19451943 c_fields_len += 1;
19461944 }
19471945
......@@ -1950,7 +1948,7 @@ pub const CType = extern union {
19501948 for (0..fields_len) |field_i| {
19511949 const field_ty = ty.structFieldType(field_i);
19521950 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or
1953 !field_ty.hasRuntimeBitsIgnoreComptime()) continue;
1951 !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
19541952
19551953 defer c_field_i += 1;
19561954 fields_pl[c_field_i] = .{
......@@ -1962,12 +1960,12 @@ pub const CType = extern union {
19621960 .Union => ty.unionFields().keys()[field_i],
19631961 else => unreachable,
19641962 }),
1965 .type = store.set.typeToIndex(field_ty, target, switch (kind) {
1963 .type = store.set.typeToIndex(field_ty, mod, switch (kind) {
19661964 .forward, .forward_parameter => .forward,
19671965 .complete, .parameter, .payload => .complete,
19681966 .global => .global,
19691967 }).?,
1970 .alignas = AlignAs.fieldAlign(ty, field_i, target),
1968 .alignas = AlignAs.fieldAlign(ty, field_i, mod),
19711969 };
19721970 }
19731971
......@@ -2004,7 +2002,7 @@ pub const CType = extern union {
20042002 const struct_pl = try arena.create(Payload.Aggregate);
20052003 struct_pl.* = .{ .base = .{ .tag = t }, .data = .{
20062004 .fields = fields_pl,
2007 .fwd_decl = store.set.typeToIndex(ty, target, .forward).?,
2005 .fwd_decl = store.set.typeToIndex(ty, mod, .forward).?,
20082006 } };
20092007 return initPayload(struct_pl);
20102008 },
......@@ -2026,21 +2024,21 @@ pub const CType = extern union {
20262024
20272025 var c_params_len: usize = 0;
20282026 for (info.param_types) |param_type| {
2029 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;
2027 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
20302028 c_params_len += 1;
20312029 }
20322030
20332031 const params_pl = try arena.alloc(Index, c_params_len);
20342032 var c_param_i: usize = 0;
20352033 for (info.param_types) |param_type| {
2036 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;
2037 params_pl[c_param_i] = store.set.typeToIndex(param_type, target, param_kind).?;
2034 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
2035 params_pl[c_param_i] = store.set.typeToIndex(param_type, mod, param_kind).?;
20382036 c_param_i += 1;
20392037 }
20402038
20412039 const fn_pl = try arena.create(Payload.Function);
20422040 fn_pl.* = .{ .base = .{ .tag = t }, .data = .{
2043 .return_type = store.set.typeToIndex(info.return_type, target, param_kind).?,
2041 .return_type = store.set.typeToIndex(info.return_type, mod, param_kind).?,
20442042 .param_types = params_pl,
20452043 } };
20462044 return initPayload(fn_pl);
......@@ -2067,12 +2065,12 @@ pub const CType = extern union {
20672065 }
20682066
20692067 pub fn eql(self: @This(), ty: Type, cty: CType) bool {
2068 const mod = self.lookup.getModule();
20702069 switch (self.convert.value) {
20712070 .cty => |c| return c.eql(cty),
20722071 .tag => |t| {
20732072 if (t != cty.tag()) return false;
20742073
2075 const target = self.lookup.getTarget();
20762074 switch (t) {
20772075 .fwd_anon_struct,
20782076 .fwd_anon_union,
......@@ -2084,7 +2082,7 @@ pub const CType = extern union {
20842082 ]u8 = undefined;
20852083 const c_fields = cty.cast(Payload.Fields).?.data;
20862084
2087 const zig_ty_tag = ty.zigTypeTag();
2085 const zig_ty_tag = ty.zigTypeTag(mod);
20882086 var c_field_i: usize = 0;
20892087 for (0..switch (zig_ty_tag) {
20902088 .Struct => ty.structFieldCount(),
......@@ -2093,7 +2091,7 @@ pub const CType = extern union {
20932091 }) |field_i| {
20942092 const field_ty = ty.structFieldType(field_i);
20952093 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or
2096 !field_ty.hasRuntimeBitsIgnoreComptime()) continue;
2094 !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
20972095
20982096 defer c_field_i += 1;
20992097 const c_field = &c_fields[c_field_i];
......@@ -2113,7 +2111,7 @@ pub const CType = extern union {
21132111 else => unreachable,
21142112 },
21152113 mem.span(c_field.name),
2116 ) or AlignAs.fieldAlign(ty, field_i, target).@"align" !=
2114 ) or AlignAs.fieldAlign(ty, field_i, mod).@"align" !=
21172115 c_field.alignas.@"align") return false;
21182116 }
21192117 return true;
......@@ -2146,7 +2144,7 @@ pub const CType = extern union {
21462144 .function,
21472145 .varargs_function,
21482146 => {
2149 if (ty.zigTypeTag() != .Fn) return false;
2147 if (ty.zigTypeTag(mod) != .Fn) return false;
21502148
21512149 const info = ty.fnInfo();
21522150 assert(!info.is_generic);
......@@ -2162,7 +2160,7 @@ pub const CType = extern union {
21622160
21632161 var c_param_i: usize = 0;
21642162 for (info.param_types) |param_type| {
2165 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;
2163 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
21662164
21672165 if (c_param_i >= data.param_types.len) return false;
21682166 const param_cty = data.param_types[c_param_i];
......@@ -2202,7 +2200,7 @@ pub const CType = extern union {
22022200 .tag => |t| {
22032201 autoHash(hasher, t);
22042202
2205 const target = self.lookup.getTarget();
2203 const mod = self.lookup.getModule();
22062204 switch (t) {
22072205 .fwd_anon_struct,
22082206 .fwd_anon_union,
......@@ -2211,15 +2209,15 @@ pub const CType = extern union {
22112209 std.fmt.count("f{}", .{std.math.maxInt(usize)})
22122210 ]u8 = undefined;
22132211
2214 const zig_ty_tag = ty.zigTypeTag();
2215 for (0..switch (ty.zigTypeTag()) {
2212 const zig_ty_tag = ty.zigTypeTag(mod);
2213 for (0..switch (ty.zigTypeTag(mod)) {
22162214 .Struct => ty.structFieldCount(),
22172215 .Union => ty.unionFields().count(),
22182216 else => unreachable,
22192217 }) |field_i| {
22202218 const field_ty = ty.structFieldType(field_i);
22212219 if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i)) or
2222 !field_ty.hasRuntimeBitsIgnoreComptime()) continue;
2220 !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
22232221
22242222 self.updateHasherRecurse(hasher, field_ty, switch (self.kind) {
22252223 .forward, .forward_parameter => .forward,
......@@ -2234,7 +2232,7 @@ pub const CType = extern union {
22342232 .Union => ty.unionFields().keys()[field_i],
22352233 else => unreachable,
22362234 });
2237 autoHash(hasher, AlignAs.fieldAlign(ty, field_i, target).@"align");
2235 autoHash(hasher, AlignAs.fieldAlign(ty, field_i, mod).@"align");
22382236 }
22392237 },
22402238
......@@ -2271,7 +2269,7 @@ pub const CType = extern union {
22712269
22722270 self.updateHasherRecurse(hasher, info.return_type, param_kind);
22732271 for (info.param_types) |param_type| {
2274 if (!param_type.hasRuntimeBitsIgnoreComptime()) continue;
2272 if (!param_type.hasRuntimeBitsIgnoreComptime(mod)) continue;
22752273 self.updateHasherRecurse(hasher, param_type, param_kind);
22762274 }
22772275 },
src/codegen/llvm.zig+812-745
......@@ -598,7 +598,7 @@ pub const Object = struct {
598598 };
599599 const llvm_slice_ty = self.context.structType(&type_fields, type_fields.len, .False);
600600 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
601 const slice_alignment = slice_ty.abiAlignment(target);
601 const slice_alignment = slice_ty.abiAlignment(mod);
602602
603603 const error_name_list = mod.error_name_list.items;
604604 const llvm_errors = try mod.gpa.alloc(*llvm.Value, error_name_list.len);
......@@ -880,28 +880,28 @@ pub const Object = struct {
880880
881881 pub fn updateFunc(
882882 o: *Object,
883 module: *Module,
883 mod: *Module,
884884 func: *Module.Fn,
885885 air: Air,
886886 liveness: Liveness,
887887 ) !void {
888888 const decl_index = func.owner_decl;
889 const decl = module.declPtr(decl_index);
890 const target = module.getTarget();
889 const decl = mod.declPtr(decl_index);
890 const target = mod.getTarget();
891891
892892 var dg: DeclGen = .{
893893 .context = o.context,
894894 .object = o,
895 .module = module,
895 .module = mod,
896896 .decl_index = decl_index,
897897 .decl = decl,
898898 .err_msg = null,
899 .gpa = module.gpa,
899 .gpa = mod.gpa,
900900 };
901901
902902 const llvm_func = try dg.resolveLlvmFunction(decl_index);
903903
904 if (module.align_stack_fns.get(func)) |align_info| {
904 if (mod.align_stack_fns.get(func)) |align_info| {
905905 dg.addFnAttrInt(llvm_func, "alignstack", align_info.alignment);
906906 dg.addFnAttr(llvm_func, "noinline");
907907 } else {
......@@ -922,7 +922,7 @@ pub const Object = struct {
922922 }
923923
924924 // TODO: disable this if safety is off for the function scope
925 const ssp_buf_size = module.comp.bin_file.options.stack_protector;
925 const ssp_buf_size = mod.comp.bin_file.options.stack_protector;
926926 if (ssp_buf_size != 0) {
927927 var buf: [12]u8 = undefined;
928928 const arg = std.fmt.bufPrintZ(&buf, "{d}", .{ssp_buf_size}) catch unreachable;
......@@ -931,7 +931,7 @@ pub const Object = struct {
931931 }
932932
933933 // TODO: disable this if safety is off for the function scope
934 if (module.comp.bin_file.options.stack_check) {
934 if (mod.comp.bin_file.options.stack_check) {
935935 dg.addFnAttrString(llvm_func, "probe-stack", "__zig_probe_stack");
936936 } else if (target.os.tag == .uefi) {
937937 dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
......@@ -954,17 +954,17 @@ pub const Object = struct {
954954
955955 // This gets the LLVM values from the function and stores them in `dg.args`.
956956 const fn_info = decl.ty.fnInfo();
957 const sret = firstParamSRet(fn_info, target);
957 const sret = firstParamSRet(fn_info, mod);
958958 const ret_ptr = if (sret) llvm_func.getParam(0) else null;
959959 const gpa = dg.gpa;
960960
961 if (ccAbiPromoteInt(fn_info.cc, target, fn_info.return_type)) |s| switch (s) {
961 if (ccAbiPromoteInt(fn_info.cc, mod, fn_info.return_type)) |s| switch (s) {
962962 .signed => dg.addAttr(llvm_func, 0, "signext"),
963963 .unsigned => dg.addAttr(llvm_func, 0, "zeroext"),
964964 };
965965
966 const err_return_tracing = fn_info.return_type.isError() and
967 module.comp.bin_file.options.error_return_tracing;
966 const err_return_tracing = fn_info.return_type.isError(mod) and
967 mod.comp.bin_file.options.error_return_tracing;
968968
969969 const err_ret_trace = if (err_return_tracing)
970970 llvm_func.getParam(@boolToInt(ret_ptr != null))
......@@ -989,8 +989,8 @@ pub const Object = struct {
989989 const param = llvm_func.getParam(llvm_arg_i);
990990 try args.ensureUnusedCapacity(1);
991991
992 if (isByRef(param_ty)) {
993 const alignment = param_ty.abiAlignment(target);
992 if (isByRef(param_ty, mod)) {
993 const alignment = param_ty.abiAlignment(mod);
994994 const param_llvm_ty = param.typeOf();
995995 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
996996 const store_inst = builder.buildStore(param, arg_ptr);
......@@ -1007,14 +1007,14 @@ pub const Object = struct {
10071007 const param_ty = fn_info.param_types[it.zig_index - 1];
10081008 const param_llvm_ty = try dg.lowerType(param_ty);
10091009 const param = llvm_func.getParam(llvm_arg_i);
1010 const alignment = param_ty.abiAlignment(target);
1010 const alignment = param_ty.abiAlignment(mod);
10111011
10121012 dg.addByRefParamAttrs(llvm_func, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);
10131013 llvm_arg_i += 1;
10141014
10151015 try args.ensureUnusedCapacity(1);
10161016
1017 if (isByRef(param_ty)) {
1017 if (isByRef(param_ty, mod)) {
10181018 args.appendAssumeCapacity(param);
10191019 } else {
10201020 const load_inst = builder.buildLoad(param_llvm_ty, param, "");
......@@ -1026,14 +1026,14 @@ pub const Object = struct {
10261026 const param_ty = fn_info.param_types[it.zig_index - 1];
10271027 const param_llvm_ty = try dg.lowerType(param_ty);
10281028 const param = llvm_func.getParam(llvm_arg_i);
1029 const alignment = param_ty.abiAlignment(target);
1029 const alignment = param_ty.abiAlignment(mod);
10301030
10311031 dg.addArgAttr(llvm_func, llvm_arg_i, "noundef");
10321032 llvm_arg_i += 1;
10331033
10341034 try args.ensureUnusedCapacity(1);
10351035
1036 if (isByRef(param_ty)) {
1036 if (isByRef(param_ty, mod)) {
10371037 args.appendAssumeCapacity(param);
10381038 } else {
10391039 const load_inst = builder.buildLoad(param_llvm_ty, param, "");
......@@ -1048,10 +1048,10 @@ pub const Object = struct {
10481048 llvm_arg_i += 1;
10491049
10501050 const param_llvm_ty = try dg.lowerType(param_ty);
1051 const abi_size = @intCast(c_uint, param_ty.abiSize(target));
1051 const abi_size = @intCast(c_uint, param_ty.abiSize(mod));
10521052 const int_llvm_ty = dg.context.intType(abi_size * 8);
10531053 const alignment = @max(
1054 param_ty.abiAlignment(target),
1054 param_ty.abiAlignment(mod),
10551055 dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
10561056 );
10571057 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
......@@ -1060,7 +1060,7 @@ pub const Object = struct {
10601060
10611061 try args.ensureUnusedCapacity(1);
10621062
1063 if (isByRef(param_ty)) {
1063 if (isByRef(param_ty, mod)) {
10641064 args.appendAssumeCapacity(arg_ptr);
10651065 } else {
10661066 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
......@@ -1078,7 +1078,7 @@ pub const Object = struct {
10781078 dg.addArgAttr(llvm_func, llvm_arg_i, "noalias");
10791079 }
10801080 }
1081 if (param_ty.zigTypeTag() != .Optional) {
1081 if (param_ty.zigTypeTag(mod) != .Optional) {
10821082 dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
10831083 }
10841084 if (!ptr_info.mutable) {
......@@ -1087,7 +1087,7 @@ pub const Object = struct {
10871087 if (ptr_info.@"align" != 0) {
10881088 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
10891089 } else {
1090 const elem_align = @max(ptr_info.pointee_type.abiAlignment(target), 1);
1090 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
10911091 dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
10921092 }
10931093 const ptr_param = llvm_func.getParam(llvm_arg_i);
......@@ -1105,7 +1105,7 @@ pub const Object = struct {
11051105 const field_types = it.llvm_types_buffer[0..it.llvm_types_len];
11061106 const param_ty = fn_info.param_types[it.zig_index - 1];
11071107 const param_llvm_ty = try dg.lowerType(param_ty);
1108 const param_alignment = param_ty.abiAlignment(target);
1108 const param_alignment = param_ty.abiAlignment(mod);
11091109 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target);
11101110 const llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
11111111 for (field_types, 0..) |_, field_i_usize| {
......@@ -1117,7 +1117,7 @@ pub const Object = struct {
11171117 store_inst.setAlignment(target.ptrBitWidth() / 8);
11181118 }
11191119
1120 const is_by_ref = isByRef(param_ty);
1120 const is_by_ref = isByRef(param_ty, mod);
11211121 const loaded = if (is_by_ref) arg_ptr else l: {
11221122 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
11231123 load_inst.setAlignment(param_alignment);
......@@ -1139,11 +1139,11 @@ pub const Object = struct {
11391139 const param = llvm_func.getParam(llvm_arg_i);
11401140 llvm_arg_i += 1;
11411141
1142 const alignment = param_ty.abiAlignment(target);
1142 const alignment = param_ty.abiAlignment(mod);
11431143 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
11441144 _ = builder.buildStore(param, arg_ptr);
11451145
1146 if (isByRef(param_ty)) {
1146 if (isByRef(param_ty, mod)) {
11471147 try args.append(arg_ptr);
11481148 } else {
11491149 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
......@@ -1157,11 +1157,11 @@ pub const Object = struct {
11571157 const param = llvm_func.getParam(llvm_arg_i);
11581158 llvm_arg_i += 1;
11591159
1160 const alignment = param_ty.abiAlignment(target);
1160 const alignment = param_ty.abiAlignment(mod);
11611161 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
11621162 _ = builder.buildStore(param, arg_ptr);
11631163
1164 if (isByRef(param_ty)) {
1164 if (isByRef(param_ty, mod)) {
11651165 try args.append(arg_ptr);
11661166 } else {
11671167 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
......@@ -1180,7 +1180,7 @@ pub const Object = struct {
11801180
11811181 const line_number = decl.src_line + 1;
11821182 const is_internal_linkage = decl.val.tag() != .extern_fn and
1183 !module.decl_exports.contains(decl_index);
1183 !mod.decl_exports.contains(decl_index);
11841184 const noret_bit: c_uint = if (fn_info.return_type.isNoReturn())
11851185 llvm.DIFlags.NoReturn
11861186 else
......@@ -1196,7 +1196,7 @@ pub const Object = struct {
11961196 true, // is definition
11971197 line_number + func.lbrace_line, // scope line
11981198 llvm.DIFlags.StaticMember | noret_bit,
1199 module.comp.bin_file.options.optimize_mode != .Debug,
1199 mod.comp.bin_file.options.optimize_mode != .Debug,
12001200 null, // decl_subprogram
12011201 );
12021202 try dg.object.di_map.put(gpa, decl, subprogram.toNode());
......@@ -1219,7 +1219,7 @@ pub const Object = struct {
12191219 .func_inst_table = .{},
12201220 .llvm_func = llvm_func,
12211221 .blocks = .{},
1222 .single_threaded = module.comp.bin_file.options.single_threaded,
1222 .single_threaded = mod.comp.bin_file.options.single_threaded,
12231223 .di_scope = di_scope,
12241224 .di_file = di_file,
12251225 .base_line = dg.decl.src_line,
......@@ -1232,14 +1232,14 @@ pub const Object = struct {
12321232 fg.genBody(air.getMainBody()) catch |err| switch (err) {
12331233 error.CodegenFail => {
12341234 decl.analysis = .codegen_failure;
1235 try module.failed_decls.put(module.gpa, decl_index, dg.err_msg.?);
1235 try mod.failed_decls.put(mod.gpa, decl_index, dg.err_msg.?);
12361236 dg.err_msg = null;
12371237 return;
12381238 },
12391239 else => |e| return e,
12401240 };
12411241
1242 try o.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
1242 try o.updateDeclExports(mod, decl_index, mod.getDeclExports(decl_index));
12431243 }
12441244
12451245 pub fn updateDecl(self: *Object, module: *Module, decl_index: Module.Decl.Index) !void {
......@@ -1275,37 +1275,40 @@ pub const Object = struct {
12751275
12761276 pub fn updateDeclExports(
12771277 self: *Object,
1278 module: *Module,
1278 mod: *Module,
12791279 decl_index: Module.Decl.Index,
12801280 exports: []const *Module.Export,
12811281 ) !void {
1282 const gpa = mod.gpa;
12821283 // If the module does not already have the function, we ignore this function call
12831284 // because we call `updateDeclExports` at the end of `updateFunc` and `updateDecl`.
12841285 const llvm_global = self.decl_map.get(decl_index) orelse return;
1285 const decl = module.declPtr(decl_index);
1286 const decl = mod.declPtr(decl_index);
12861287 if (decl.isExtern()) {
1287 const is_wasm_fn = module.getTarget().isWasm() and try decl.isFunction();
1288 const is_wasm_fn = mod.getTarget().isWasm() and try decl.isFunction(mod);
12881289 const mangle_name = is_wasm_fn and
12891290 decl.getExternFn().?.lib_name != null and
12901291 !std.mem.eql(u8, std.mem.sliceTo(decl.getExternFn().?.lib_name.?, 0), "c");
12911292 const decl_name = if (mangle_name) name: {
1292 const tmp = try std.fmt.allocPrintZ(module.gpa, "{s}|{s}", .{ decl.name, decl.getExternFn().?.lib_name.? });
1293 const tmp = try std.fmt.allocPrintZ(gpa, "{s}|{s}", .{
1294 decl.name, decl.getExternFn().?.lib_name.?,
1295 });
12931296 break :name tmp.ptr;
12941297 } else decl.name;
1295 defer if (mangle_name) module.gpa.free(std.mem.sliceTo(decl_name, 0));
1298 defer if (mangle_name) gpa.free(std.mem.sliceTo(decl_name, 0));
12961299
12971300 llvm_global.setValueName(decl_name);
12981301 if (self.getLlvmGlobal(decl_name)) |other_global| {
12991302 if (other_global != llvm_global) {
13001303 log.debug("updateDeclExports isExtern()=true setValueName({s}) conflict", .{decl.name});
1301 try self.extern_collisions.put(module.gpa, decl_index, {});
1304 try self.extern_collisions.put(gpa, decl_index, {});
13021305 }
13031306 }
13041307 llvm_global.setUnnamedAddr(.False);
13051308 llvm_global.setLinkage(.External);
1306 if (module.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
1309 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
13071310 if (self.di_map.get(decl)) |di_node| {
1308 if (try decl.isFunction()) {
1311 if (try decl.isFunction(mod)) {
13091312 const di_func = @ptrCast(*llvm.DISubprogram, di_node);
13101313 const linkage_name = llvm.MDString.get(self.context, decl.name, std.mem.len(decl.name));
13111314 di_func.replaceLinkageName(linkage_name);
......@@ -1329,9 +1332,9 @@ pub const Object = struct {
13291332 const exp_name = exports[0].options.name;
13301333 llvm_global.setValueName2(exp_name.ptr, exp_name.len);
13311334 llvm_global.setUnnamedAddr(.False);
1332 if (module.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport);
1335 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport);
13331336 if (self.di_map.get(decl)) |di_node| {
1334 if (try decl.isFunction()) {
1337 if (try decl.isFunction(mod)) {
13351338 const di_func = @ptrCast(*llvm.DISubprogram, di_node);
13361339 const linkage_name = llvm.MDString.get(self.context, exp_name.ptr, exp_name.len);
13371340 di_func.replaceLinkageName(linkage_name);
......@@ -1353,8 +1356,8 @@ pub const Object = struct {
13531356 .protected => llvm_global.setVisibility(.Protected),
13541357 }
13551358 if (exports[0].options.section) |section| {
1356 const section_z = try module.gpa.dupeZ(u8, section);
1357 defer module.gpa.free(section_z);
1359 const section_z = try gpa.dupeZ(u8, section);
1360 defer gpa.free(section_z);
13581361 llvm_global.setSection(section_z);
13591362 }
13601363 if (decl.val.castTag(.variable)) |variable| {
......@@ -1370,8 +1373,8 @@ pub const Object = struct {
13701373 // Until then we iterate over existing aliases and make them point
13711374 // to the correct decl, or otherwise add a new alias. Old aliases are leaked.
13721375 for (exports[1..]) |exp| {
1373 const exp_name_z = try module.gpa.dupeZ(u8, exp.options.name);
1374 defer module.gpa.free(exp_name_z);
1376 const exp_name_z = try gpa.dupeZ(u8, exp.options.name);
1377 defer gpa.free(exp_name_z);
13751378
13761379 if (self.llvm_module.getNamedGlobalAlias(exp_name_z.ptr, exp_name_z.len)) |alias| {
13771380 alias.setAliasee(llvm_global);
......@@ -1385,14 +1388,14 @@ pub const Object = struct {
13851388 }
13861389 }
13871390 } else {
1388 const fqn = try decl.getFullyQualifiedName(module);
1389 defer module.gpa.free(fqn);
1391 const fqn = try decl.getFullyQualifiedName(mod);
1392 defer gpa.free(fqn);
13901393 llvm_global.setValueName2(fqn.ptr, fqn.len);
13911394 llvm_global.setLinkage(.Internal);
1392 if (module.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
1395 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
13931396 llvm_global.setUnnamedAddr(.True);
13941397 if (decl.val.castTag(.variable)) |variable| {
1395 const single_threaded = module.comp.bin_file.options.single_threaded;
1398 const single_threaded = mod.comp.bin_file.options.single_threaded;
13961399 if (variable.data.is_threadlocal and !single_threaded) {
13971400 llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel);
13981401 } else {
......@@ -1479,14 +1482,15 @@ pub const Object = struct {
14791482 const gpa = o.gpa;
14801483 const target = o.target;
14811484 const dib = o.di_builder.?;
1482 switch (ty.zigTypeTag()) {
1485 const mod = o.module;
1486 switch (ty.zigTypeTag(mod)) {
14831487 .Void, .NoReturn => {
14841488 const di_type = dib.createBasicType("void", 0, DW.ATE.signed);
14851489 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
14861490 return di_type;
14871491 },
14881492 .Int => {
1489 const info = ty.intInfo(target);
1493 const info = ty.intInfo(mod);
14901494 assert(info.bits != 0);
14911495 const name = try ty.nameAlloc(gpa, o.module);
14921496 defer gpa.free(name);
......@@ -1494,7 +1498,7 @@ pub const Object = struct {
14941498 .signed => DW.ATE.signed,
14951499 .unsigned => DW.ATE.unsigned,
14961500 };
1497 const di_bits = ty.abiSize(target) * 8; // lldb cannot handle non-byte sized types
1501 const di_bits = ty.abiSize(mod) * 8; // lldb cannot handle non-byte sized types
14981502 const di_type = dib.createBasicType(name, di_bits, dwarf_encoding);
14991503 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
15001504 return di_type;
......@@ -1503,7 +1507,7 @@ pub const Object = struct {
15031507 const owner_decl_index = ty.getOwnerDecl();
15041508 const owner_decl = o.module.declPtr(owner_decl_index);
15051509
1506 if (!ty.hasRuntimeBitsIgnoreComptime()) {
1510 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
15071511 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
15081512 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
15091513 // means we can't use `gop` anymore.
......@@ -1522,9 +1526,8 @@ pub const Object = struct {
15221526 };
15231527 const field_index_val = Value.initPayload(&buf_field_index.base);
15241528
1525 var buffer: Type.Payload.Bits = undefined;
1526 const int_ty = ty.intTagType(&buffer);
1527 const int_info = ty.intInfo(target);
1529 const int_ty = ty.intTagType();
1530 const int_info = ty.intInfo(mod);
15281531 assert(int_info.bits != 0);
15291532
15301533 for (field_names, 0..) |field_name, i| {
......@@ -1536,7 +1539,7 @@ pub const Object = struct {
15361539 const field_int_val = field_index_val.enumToInt(ty, &buf_u64);
15371540
15381541 var bigint_space: Value.BigIntSpace = undefined;
1539 const bigint = field_int_val.toBigInt(&bigint_space, target);
1542 const bigint = field_int_val.toBigInt(&bigint_space, mod);
15401543
15411544 if (bigint.limbs.len == 1) {
15421545 enumerators[i] = dib.createEnumerator(field_name_z, bigint.limbs[0], int_info.signedness == .unsigned);
......@@ -1566,8 +1569,8 @@ pub const Object = struct {
15661569 name,
15671570 di_file,
15681571 owner_decl.src_node + 1,
1569 ty.abiSize(target) * 8,
1570 ty.abiAlignment(target) * 8,
1572 ty.abiSize(mod) * 8,
1573 ty.abiAlignment(mod) * 8,
15711574 enumerators.ptr,
15721575 @intCast(c_int, enumerators.len),
15731576 try o.lowerDebugType(int_ty, .full),
......@@ -1604,7 +1607,7 @@ pub const Object = struct {
16041607 !ptr_info.mutable or
16051608 ptr_info.@"volatile" or
16061609 ptr_info.size == .Many or ptr_info.size == .C or
1607 !ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime())
1610 !ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime(mod))
16081611 {
16091612 var payload: Type.Payload.Pointer = .{
16101613 .data = .{
......@@ -1623,7 +1626,7 @@ pub const Object = struct {
16231626 },
16241627 },
16251628 };
1626 if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime()) {
1629 if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) {
16271630 payload.data.pointee_type = Type.anyopaque;
16281631 }
16291632 const bland_ptr_ty = Type.initPayload(&payload.base);
......@@ -1657,10 +1660,10 @@ pub const Object = struct {
16571660 break :blk fwd_decl;
16581661 };
16591662
1660 const ptr_size = ptr_ty.abiSize(target);
1661 const ptr_align = ptr_ty.abiAlignment(target);
1662 const len_size = len_ty.abiSize(target);
1663 const len_align = len_ty.abiAlignment(target);
1663 const ptr_size = ptr_ty.abiSize(mod);
1664 const ptr_align = ptr_ty.abiAlignment(mod);
1665 const len_size = len_ty.abiSize(mod);
1666 const len_align = len_ty.abiAlignment(mod);
16641667
16651668 var offset: u64 = 0;
16661669 offset += ptr_size;
......@@ -1697,8 +1700,8 @@ pub const Object = struct {
16971700 name.ptr,
16981701 di_file,
16991702 line,
1700 ty.abiSize(target) * 8, // size in bits
1701 ty.abiAlignment(target) * 8, // align in bits
1703 ty.abiSize(mod) * 8, // size in bits
1704 ty.abiAlignment(mod) * 8, // align in bits
17021705 0, // flags
17031706 null, // derived from
17041707 &fields,
......@@ -1719,7 +1722,7 @@ pub const Object = struct {
17191722 const ptr_di_ty = dib.createPointerType(
17201723 elem_di_ty,
17211724 target.ptrBitWidth(),
1722 ty.ptrAlignment(target) * 8,
1725 ty.ptrAlignment(mod) * 8,
17231726 name,
17241727 );
17251728 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
......@@ -1750,8 +1753,8 @@ pub const Object = struct {
17501753 },
17511754 .Array => {
17521755 const array_di_ty = dib.createArrayType(
1753 ty.abiSize(target) * 8,
1754 ty.abiAlignment(target) * 8,
1756 ty.abiSize(mod) * 8,
1757 ty.abiAlignment(mod) * 8,
17551758 try o.lowerDebugType(ty.childType(), .full),
17561759 @intCast(c_int, ty.arrayLen()),
17571760 );
......@@ -1760,14 +1763,14 @@ pub const Object = struct {
17601763 return array_di_ty;
17611764 },
17621765 .Vector => {
1763 const elem_ty = ty.elemType2();
1766 const elem_ty = ty.elemType2(mod);
17641767 // Vector elements cannot be padded since that would make
17651768 // @bitSizOf(elem) * len > @bitSizOf(vec).
17661769 // Neither gdb nor lldb seem to be able to display non-byte sized
17671770 // vectors properly.
1768 const elem_di_type = switch (elem_ty.zigTypeTag()) {
1771 const elem_di_type = switch (elem_ty.zigTypeTag(mod)) {
17691772 .Int => blk: {
1770 const info = elem_ty.intInfo(target);
1773 const info = elem_ty.intInfo(mod);
17711774 assert(info.bits != 0);
17721775 const name = try ty.nameAlloc(gpa, o.module);
17731776 defer gpa.free(name);
......@@ -1782,8 +1785,8 @@ pub const Object = struct {
17821785 };
17831786
17841787 const vector_di_ty = dib.createVectorType(
1785 ty.abiSize(target) * 8,
1786 ty.abiAlignment(target) * 8,
1788 ty.abiSize(mod) * 8,
1789 ty.abiAlignment(mod) * 8,
17871790 elem_di_type,
17881791 ty.vectorLen(),
17891792 );
......@@ -1796,13 +1799,13 @@ pub const Object = struct {
17961799 defer gpa.free(name);
17971800 var buf: Type.Payload.ElemType = undefined;
17981801 const child_ty = ty.optionalChild(&buf);
1799 if (!child_ty.hasRuntimeBitsIgnoreComptime()) {
1802 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
18001803 const di_bits = 8; // lldb cannot handle non-byte sized types
18011804 const di_ty = dib.createBasicType(name, di_bits, DW.ATE.boolean);
18021805 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
18031806 return di_ty;
18041807 }
1805 if (ty.optionalReprIsPayload()) {
1808 if (ty.optionalReprIsPayload(mod)) {
18061809 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);
18071810 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
18081811 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .mod = o.module });
......@@ -1826,10 +1829,10 @@ pub const Object = struct {
18261829 };
18271830
18281831 const non_null_ty = Type.u8;
1829 const payload_size = child_ty.abiSize(target);
1830 const payload_align = child_ty.abiAlignment(target);
1831 const non_null_size = non_null_ty.abiSize(target);
1832 const non_null_align = non_null_ty.abiAlignment(target);
1832 const payload_size = child_ty.abiSize(mod);
1833 const payload_align = child_ty.abiAlignment(mod);
1834 const non_null_size = non_null_ty.abiSize(mod);
1835 const non_null_align = non_null_ty.abiAlignment(mod);
18331836
18341837 var offset: u64 = 0;
18351838 offset += payload_size;
......@@ -1866,8 +1869,8 @@ pub const Object = struct {
18661869 name.ptr,
18671870 di_file,
18681871 line,
1869 ty.abiSize(target) * 8, // size in bits
1870 ty.abiAlignment(target) * 8, // align in bits
1872 ty.abiSize(mod) * 8, // size in bits
1873 ty.abiAlignment(mod) * 8, // align in bits
18711874 0, // flags
18721875 null, // derived from
18731876 &fields,
......@@ -1883,7 +1886,7 @@ pub const Object = struct {
18831886 },
18841887 .ErrorUnion => {
18851888 const payload_ty = ty.errorUnionPayload();
1886 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1889 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
18871890 const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full);
18881891 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
18891892 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .mod = o.module });
......@@ -1907,10 +1910,10 @@ pub const Object = struct {
19071910 break :blk fwd_decl;
19081911 };
19091912
1910 const error_size = Type.anyerror.abiSize(target);
1911 const error_align = Type.anyerror.abiAlignment(target);
1912 const payload_size = payload_ty.abiSize(target);
1913 const payload_align = payload_ty.abiAlignment(target);
1913 const error_size = Type.anyerror.abiSize(mod);
1914 const error_align = Type.anyerror.abiAlignment(mod);
1915 const payload_size = payload_ty.abiSize(mod);
1916 const payload_align = payload_ty.abiAlignment(mod);
19141917
19151918 var error_index: u32 = undefined;
19161919 var payload_index: u32 = undefined;
......@@ -1957,8 +1960,8 @@ pub const Object = struct {
19571960 name.ptr,
19581961 di_file,
19591962 line,
1960 ty.abiSize(target) * 8, // size in bits
1961 ty.abiAlignment(target) * 8, // align in bits
1963 ty.abiSize(mod) * 8, // size in bits
1964 ty.abiAlignment(mod) * 8, // align in bits
19621965 0, // flags
19631966 null, // derived from
19641967 &fields,
......@@ -1988,12 +1991,12 @@ pub const Object = struct {
19881991 const struct_obj = payload.data;
19891992 if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) {
19901993 assert(struct_obj.haveLayout());
1991 const info = struct_obj.backing_int_ty.intInfo(target);
1994 const info = struct_obj.backing_int_ty.intInfo(mod);
19921995 const dwarf_encoding: c_uint = switch (info.signedness) {
19931996 .signed => DW.ATE.signed,
19941997 .unsigned => DW.ATE.unsigned,
19951998 };
1996 const di_bits = ty.abiSize(target) * 8; // lldb cannot handle non-byte sized types
1999 const di_bits = ty.abiSize(mod) * 8; // lldb cannot handle non-byte sized types
19972000 const di_ty = dib.createBasicType(name, di_bits, dwarf_encoding);
19982001 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
19992002 return di_ty;
......@@ -2026,10 +2029,10 @@ pub const Object = struct {
20262029
20272030 for (tuple.types, 0..) |field_ty, i| {
20282031 const field_val = tuple.values[i];
2029 if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue;
2032 if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits(mod)) continue;
20302033
2031 const field_size = field_ty.abiSize(target);
2032 const field_align = field_ty.abiAlignment(target);
2034 const field_size = field_ty.abiSize(mod);
2035 const field_align = field_ty.abiAlignment(mod);
20332036 const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);
20342037 offset = field_offset + field_size;
20352038
......@@ -2057,8 +2060,8 @@ pub const Object = struct {
20572060 name.ptr,
20582061 null, // file
20592062 0, // line
2060 ty.abiSize(target) * 8, // size in bits
2061 ty.abiAlignment(target) * 8, // align in bits
2063 ty.abiSize(mod) * 8, // size in bits
2064 ty.abiAlignment(mod) * 8, // align in bits
20622065 0, // flags
20632066 null, // derived from
20642067 di_fields.items.ptr,
......@@ -2093,7 +2096,7 @@ pub const Object = struct {
20932096 }
20942097 }
20952098
2096 if (!ty.hasRuntimeBitsIgnoreComptime()) {
2099 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
20972100 const owner_decl_index = ty.getOwnerDecl();
20982101 const struct_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
20992102 dib.replaceTemporary(fwd_decl, struct_di_ty);
......@@ -2114,11 +2117,11 @@ pub const Object = struct {
21142117 comptime assert(struct_layout_version == 2);
21152118 var offset: u64 = 0;
21162119
2117 var it = ty.castTag(.@"struct").?.data.runtimeFieldIterator();
2120 var it = ty.castTag(.@"struct").?.data.runtimeFieldIterator(mod);
21182121 while (it.next()) |field_and_index| {
21192122 const field = field_and_index.field;
2120 const field_size = field.ty.abiSize(target);
2121 const field_align = field.alignment(target, layout);
2123 const field_size = field.ty.abiSize(mod);
2124 const field_align = field.alignment(mod, layout);
21222125 const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);
21232126 offset = field_offset + field_size;
21242127
......@@ -2143,8 +2146,8 @@ pub const Object = struct {
21432146 name.ptr,
21442147 null, // file
21452148 0, // line
2146 ty.abiSize(target) * 8, // size in bits
2147 ty.abiAlignment(target) * 8, // align in bits
2149 ty.abiSize(mod) * 8, // size in bits
2150 ty.abiAlignment(mod) * 8, // align in bits
21482151 0, // flags
21492152 null, // derived from
21502153 di_fields.items.ptr,
......@@ -2179,7 +2182,7 @@ pub const Object = struct {
21792182 };
21802183
21812184 const union_obj = ty.cast(Type.Payload.Union).?.data;
2182 if (!union_obj.haveFieldTypes() or !ty.hasRuntimeBitsIgnoreComptime()) {
2185 if (!union_obj.haveFieldTypes() or !ty.hasRuntimeBitsIgnoreComptime(mod)) {
21832186 const union_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
21842187 dib.replaceTemporary(fwd_decl, union_di_ty);
21852188 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
......@@ -2188,7 +2191,7 @@ pub const Object = struct {
21882191 return union_di_ty;
21892192 }
21902193
2191 const layout = ty.unionGetLayout(target);
2194 const layout = ty.unionGetLayout(mod);
21922195
21932196 if (layout.payload_size == 0) {
21942197 const tag_di_ty = try o.lowerDebugType(union_obj.tag_ty, .full);
......@@ -2198,8 +2201,8 @@ pub const Object = struct {
21982201 name.ptr,
21992202 null, // file
22002203 0, // line
2201 ty.abiSize(target) * 8, // size in bits
2202 ty.abiAlignment(target) * 8, // align in bits
2204 ty.abiSize(mod) * 8, // size in bits
2205 ty.abiAlignment(mod) * 8, // align in bits
22032206 0, // flags
22042207 null, // derived from
22052208 &di_fields,
......@@ -2225,10 +2228,10 @@ pub const Object = struct {
22252228 const field_name = kv.key_ptr.*;
22262229 const field = kv.value_ptr.*;
22272230
2228 if (!field.ty.hasRuntimeBitsIgnoreComptime()) continue;
2231 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
22292232
2230 const field_size = field.ty.abiSize(target);
2231 const field_align = field.normalAlignment(target);
2233 const field_size = field.ty.abiSize(mod);
2234 const field_align = field.normalAlignment(mod);
22322235
22332236 const field_name_copy = try gpa.dupeZ(u8, field_name);
22342237 defer gpa.free(field_name_copy);
......@@ -2258,8 +2261,8 @@ pub const Object = struct {
22582261 union_name.ptr,
22592262 null, // file
22602263 0, // line
2261 ty.abiSize(target) * 8, // size in bits
2262 ty.abiAlignment(target) * 8, // align in bits
2264 ty.abiSize(mod) * 8, // size in bits
2265 ty.abiAlignment(mod) * 8, // align in bits
22632266 0, // flags
22642267 di_fields.items.ptr,
22652268 @intCast(c_int, di_fields.items.len),
......@@ -2319,8 +2322,8 @@ pub const Object = struct {
23192322 name.ptr,
23202323 null, // file
23212324 0, // line
2322 ty.abiSize(target) * 8, // size in bits
2323 ty.abiAlignment(target) * 8, // align in bits
2325 ty.abiSize(mod) * 8, // size in bits
2326 ty.abiAlignment(mod) * 8, // align in bits
23242327 0, // flags
23252328 null, // derived from
23262329 &full_di_fields,
......@@ -2341,8 +2344,8 @@ pub const Object = struct {
23412344 defer param_di_types.deinit();
23422345
23432346 // Return type goes first.
2344 if (fn_info.return_type.hasRuntimeBitsIgnoreComptime()) {
2345 const sret = firstParamSRet(fn_info, target);
2347 if (fn_info.return_type.hasRuntimeBitsIgnoreComptime(mod)) {
2348 const sret = firstParamSRet(fn_info, mod);
23462349 const di_ret_ty = if (sret) Type.void else fn_info.return_type;
23472350 try param_di_types.append(try o.lowerDebugType(di_ret_ty, .full));
23482351
......@@ -2358,7 +2361,7 @@ pub const Object = struct {
23582361 try param_di_types.append(try o.lowerDebugType(Type.void, .full));
23592362 }
23602363
2361 if (fn_info.return_type.isError() and
2364 if (fn_info.return_type.isError(mod) and
23622365 o.module.comp.bin_file.options.error_return_tracing)
23632366 {
23642367 var ptr_ty_payload: Type.Payload.ElemType = .{
......@@ -2370,9 +2373,9 @@ pub const Object = struct {
23702373 }
23712374
23722375 for (fn_info.param_types) |param_ty| {
2373 if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue;
2376 if (!param_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
23742377
2375 if (isByRef(param_ty)) {
2378 if (isByRef(param_ty, mod)) {
23762379 var ptr_ty_payload: Type.Payload.ElemType = .{
23772380 .base = .{ .tag = .single_mut_pointer },
23782381 .data = param_ty,
......@@ -2450,7 +2453,7 @@ pub const Object = struct {
24502453
24512454 const stack_trace_str: []const u8 = "StackTrace";
24522455 // buffer is only used for int_type, `builtin` is a struct.
2453 const builtin_ty = mod.declPtr(builtin_decl).val.toType(undefined);
2456 const builtin_ty = mod.declPtr(builtin_decl).val.toType();
24542457 const builtin_namespace = builtin_ty.getNamespace().?;
24552458 const stack_trace_decl_index = builtin_namespace.decls
24562459 .getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .mod = mod }).?;
......@@ -2458,7 +2461,7 @@ pub const Object = struct {
24582461
24592462 // Sema should have ensured that StackTrace was analyzed.
24602463 assert(stack_trace_decl.has_tv);
2461 return stack_trace_decl.val.toType(undefined);
2464 return stack_trace_decl.val.toType();
24622465 }
24632466};
24642467
......@@ -2495,9 +2498,10 @@ pub const DeclGen = struct {
24952498 if (decl.val.castTag(.extern_fn)) |extern_fn| {
24962499 _ = try dg.resolveLlvmFunction(extern_fn.data.owner_decl);
24972500 } else {
2498 const target = dg.module.getTarget();
2501 const mod = dg.module;
2502 const target = mod.getTarget();
24992503 var global = try dg.resolveGlobalDecl(decl_index);
2500 global.setAlignment(decl.getAlignment(target));
2504 global.setAlignment(decl.getAlignment(mod));
25012505 if (decl.@"linksection") |section| global.setSection(section);
25022506 assert(decl.has_tv);
25032507 const init_val = if (decl.val.castTag(.variable)) |payload| init_val: {
......@@ -2569,19 +2573,20 @@ pub const DeclGen = struct {
25692573 /// Note that this can be called before the function's semantic analysis has
25702574 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.
25712575 fn resolveLlvmFunction(dg: *DeclGen, decl_index: Module.Decl.Index) !*llvm.Value {
2572 const decl = dg.module.declPtr(decl_index);
2576 const mod = dg.module;
2577 const decl = mod.declPtr(decl_index);
25732578 const zig_fn_type = decl.ty;
25742579 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index);
25752580 if (gop.found_existing) return gop.value_ptr.*;
25762581
25772582 assert(decl.has_tv);
25782583 const fn_info = zig_fn_type.fnInfo();
2579 const target = dg.module.getTarget();
2580 const sret = firstParamSRet(fn_info, target);
2584 const target = mod.getTarget();
2585 const sret = firstParamSRet(fn_info, mod);
25812586
25822587 const fn_type = try dg.lowerType(zig_fn_type);
25832588
2584 const fqn = try decl.getFullyQualifiedName(dg.module);
2589 const fqn = try decl.getFullyQualifiedName(mod);
25852590 defer dg.gpa.free(fqn);
25862591
25872592 const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
......@@ -2593,7 +2598,7 @@ pub const DeclGen = struct {
25932598 llvm_fn.setLinkage(.Internal);
25942599 llvm_fn.setUnnamedAddr(.True);
25952600 } else {
2596 if (dg.module.getTarget().isWasm()) {
2601 if (target.isWasm()) {
25972602 dg.addFnAttrString(llvm_fn, "wasm-import-name", std.mem.sliceTo(decl.name, 0));
25982603 if (decl.getExternFn().?.lib_name) |lib_name| {
25992604 const module_name = std.mem.sliceTo(lib_name, 0);
......@@ -2612,8 +2617,8 @@ pub const DeclGen = struct {
26122617 llvm_fn.addSretAttr(raw_llvm_ret_ty);
26132618 }
26142619
2615 const err_return_tracing = fn_info.return_type.isError() and
2616 dg.module.comp.bin_file.options.error_return_tracing;
2620 const err_return_tracing = fn_info.return_type.isError(mod) and
2621 mod.comp.bin_file.options.error_return_tracing;
26172622
26182623 if (err_return_tracing) {
26192624 dg.addArgAttr(llvm_fn, @boolToInt(sret), "nonnull");
......@@ -2656,14 +2661,14 @@ pub const DeclGen = struct {
26562661 .byval => {
26572662 const param_index = it.zig_index - 1;
26582663 const param_ty = fn_info.param_types[param_index];
2659 if (!isByRef(param_ty)) {
2664 if (!isByRef(param_ty, mod)) {
26602665 dg.addByValParamAttrs(llvm_fn, param_ty, param_index, fn_info, it.llvm_index - 1);
26612666 }
26622667 },
26632668 .byref => {
26642669 const param_ty = fn_info.param_types[it.zig_index - 1];
26652670 const param_llvm_ty = try dg.lowerType(param_ty);
2666 const alignment = param_ty.abiAlignment(target);
2671 const alignment = param_ty.abiAlignment(mod);
26672672 dg.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
26682673 },
26692674 .byref_mut => {
......@@ -2784,12 +2789,13 @@ pub const DeclGen = struct {
27842789
27852790 fn lowerType(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type {
27862791 const llvm_ty = try lowerTypeInner(dg, t);
2792 const mod = dg.module;
27872793 if (std.debug.runtime_safety and false) check: {
2788 if (t.zigTypeTag() == .Opaque) break :check;
2789 if (!t.hasRuntimeBits()) break :check;
2794 if (t.zigTypeTag(mod) == .Opaque) break :check;
2795 if (!t.hasRuntimeBits(mod)) break :check;
27902796 if (!llvm_ty.isSized().toBool()) break :check;
27912797
2792 const zig_size = t.abiSize(dg.module.getTarget());
2798 const zig_size = t.abiSize(mod);
27932799 const llvm_size = dg.object.target_data.abiSizeOfType(llvm_ty);
27942800 if (llvm_size != zig_size) {
27952801 log.err("when lowering {}, Zig ABI size = {d} but LLVM ABI size = {d}", .{
......@@ -2802,18 +2808,18 @@ pub const DeclGen = struct {
28022808
28032809 fn lowerTypeInner(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type {
28042810 const gpa = dg.gpa;
2805 const target = dg.module.getTarget();
2806 switch (t.zigTypeTag()) {
2811 const mod = dg.module;
2812 const target = mod.getTarget();
2813 switch (t.zigTypeTag(mod)) {
28072814 .Void, .NoReturn => return dg.context.voidType(),
28082815 .Int => {
2809 const info = t.intInfo(target);
2816 const info = t.intInfo(mod);
28102817 assert(info.bits != 0);
28112818 return dg.context.intType(info.bits);
28122819 },
28132820 .Enum => {
2814 var buffer: Type.Payload.Bits = undefined;
2815 const int_ty = t.intTagType(&buffer);
2816 const bit_count = int_ty.intInfo(target).bits;
2821 const int_ty = t.intTagType();
2822 const bit_count = int_ty.intInfo(mod).bits;
28172823 assert(bit_count != 0);
28182824 return dg.context.intType(bit_count);
28192825 },
......@@ -2863,7 +2869,7 @@ pub const DeclGen = struct {
28632869 },
28642870 .Array => {
28652871 const elem_ty = t.childType();
2866 assert(elem_ty.onePossibleValue() == null);
2872 assert(elem_ty.onePossibleValue(mod) == null);
28672873 const elem_llvm_ty = try dg.lowerType(elem_ty);
28682874 const total_len = t.arrayLen() + @boolToInt(t.sentinel() != null);
28692875 return elem_llvm_ty.arrayType(@intCast(c_uint, total_len));
......@@ -2875,11 +2881,11 @@ pub const DeclGen = struct {
28752881 .Optional => {
28762882 var buf: Type.Payload.ElemType = undefined;
28772883 const child_ty = t.optionalChild(&buf);
2878 if (!child_ty.hasRuntimeBitsIgnoreComptime()) {
2884 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
28792885 return dg.context.intType(8);
28802886 }
28812887 const payload_llvm_ty = try dg.lowerType(child_ty);
2882 if (t.optionalReprIsPayload()) {
2888 if (t.optionalReprIsPayload(mod)) {
28832889 return payload_llvm_ty;
28842890 }
28852891
......@@ -2887,8 +2893,8 @@ pub const DeclGen = struct {
28872893 var fields_buf: [3]*llvm.Type = .{
28882894 payload_llvm_ty, dg.context.intType(8), undefined,
28892895 };
2890 const offset = child_ty.abiSize(target) + 1;
2891 const abi_size = t.abiSize(target);
2896 const offset = child_ty.abiSize(mod) + 1;
2897 const abi_size = t.abiSize(mod);
28922898 const padding = @intCast(c_uint, abi_size - offset);
28932899 if (padding == 0) {
28942900 return dg.context.structType(&fields_buf, 2, .False);
......@@ -2898,17 +2904,17 @@ pub const DeclGen = struct {
28982904 },
28992905 .ErrorUnion => {
29002906 const payload_ty = t.errorUnionPayload();
2901 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
2907 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
29022908 return try dg.lowerType(Type.anyerror);
29032909 }
29042910 const llvm_error_type = try dg.lowerType(Type.anyerror);
29052911 const llvm_payload_type = try dg.lowerType(payload_ty);
29062912
2907 const payload_align = payload_ty.abiAlignment(target);
2908 const error_align = Type.anyerror.abiAlignment(target);
2913 const payload_align = payload_ty.abiAlignment(mod);
2914 const error_align = Type.anyerror.abiAlignment(mod);
29092915
2910 const payload_size = payload_ty.abiSize(target);
2911 const error_size = Type.anyerror.abiSize(target);
2916 const payload_size = payload_ty.abiSize(mod);
2917 const error_size = Type.anyerror.abiSize(mod);
29122918
29132919 var fields_buf: [3]*llvm.Type = undefined;
29142920 if (error_align > payload_align) {
......@@ -2964,9 +2970,9 @@ pub const DeclGen = struct {
29642970
29652971 for (tuple.types, 0..) |field_ty, i| {
29662972 const field_val = tuple.values[i];
2967 if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue;
2973 if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits(mod)) continue;
29682974
2969 const field_align = field_ty.abiAlignment(target);
2975 const field_align = field_ty.abiAlignment(mod);
29702976 big_align = @max(big_align, field_align);
29712977 const prev_offset = offset;
29722978 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
......@@ -2979,7 +2985,7 @@ pub const DeclGen = struct {
29792985 const field_llvm_ty = try dg.lowerType(field_ty);
29802986 try llvm_field_types.append(gpa, field_llvm_ty);
29812987
2982 offset += field_ty.abiSize(target);
2988 offset += field_ty.abiSize(mod);
29832989 }
29842990 {
29852991 const prev_offset = offset;
......@@ -3027,11 +3033,11 @@ pub const DeclGen = struct {
30273033 var big_align: u32 = 1;
30283034 var any_underaligned_fields = false;
30293035
3030 var it = struct_obj.runtimeFieldIterator();
3036 var it = struct_obj.runtimeFieldIterator(mod);
30313037 while (it.next()) |field_and_index| {
30323038 const field = field_and_index.field;
3033 const field_align = field.alignment(target, struct_obj.layout);
3034 const field_ty_align = field.ty.abiAlignment(target);
3039 const field_align = field.alignment(mod, struct_obj.layout);
3040 const field_ty_align = field.ty.abiAlignment(mod);
30353041 any_underaligned_fields = any_underaligned_fields or
30363042 field_align < field_ty_align;
30373043 big_align = @max(big_align, field_align);
......@@ -3046,7 +3052,7 @@ pub const DeclGen = struct {
30463052 const field_llvm_ty = try dg.lowerType(field.ty);
30473053 try llvm_field_types.append(gpa, field_llvm_ty);
30483054
3049 offset += field.ty.abiSize(target);
3055 offset += field.ty.abiSize(mod);
30503056 }
30513057 {
30523058 const prev_offset = offset;
......@@ -3074,11 +3080,11 @@ pub const DeclGen = struct {
30743080 // reference, we need to copy it here.
30753081 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
30763082
3077 const layout = t.unionGetLayout(target);
3083 const layout = t.unionGetLayout(mod);
30783084 const union_obj = t.cast(Type.Payload.Union).?.data;
30793085
30803086 if (union_obj.layout == .Packed) {
3081 const bitsize = @intCast(c_uint, t.bitSize(target));
3087 const bitsize = @intCast(c_uint, t.bitSize(mod));
30823088 const int_llvm_ty = dg.context.intType(bitsize);
30833089 gop.value_ptr.* = int_llvm_ty;
30843090 return int_llvm_ty;
......@@ -3155,19 +3161,19 @@ pub const DeclGen = struct {
31553161 }
31563162
31573163 fn lowerTypeFn(dg: *DeclGen, fn_ty: Type) Allocator.Error!*llvm.Type {
3158 const target = dg.module.getTarget();
3164 const mod = dg.module;
31593165 const fn_info = fn_ty.fnInfo();
31603166 const llvm_ret_ty = try lowerFnRetTy(dg, fn_info);
31613167
31623168 var llvm_params = std.ArrayList(*llvm.Type).init(dg.gpa);
31633169 defer llvm_params.deinit();
31643170
3165 if (firstParamSRet(fn_info, target)) {
3171 if (firstParamSRet(fn_info, mod)) {
31663172 try llvm_params.append(dg.context.pointerType(0));
31673173 }
31683174
3169 if (fn_info.return_type.isError() and
3170 dg.module.comp.bin_file.options.error_return_tracing)
3175 if (fn_info.return_type.isError(mod) and
3176 mod.comp.bin_file.options.error_return_tracing)
31713177 {
31723178 var ptr_ty_payload: Type.Payload.ElemType = .{
31733179 .base = .{ .tag = .single_mut_pointer },
......@@ -3189,14 +3195,14 @@ pub const DeclGen = struct {
31893195 },
31903196 .abi_sized_int => {
31913197 const param_ty = fn_info.param_types[it.zig_index - 1];
3192 const abi_size = @intCast(c_uint, param_ty.abiSize(target));
3198 const abi_size = @intCast(c_uint, param_ty.abiSize(mod));
31933199 try llvm_params.append(dg.context.intType(abi_size * 8));
31943200 },
31953201 .slice => {
31963202 const param_ty = fn_info.param_types[it.zig_index - 1];
31973203 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
31983204 var opt_buf: Type.Payload.ElemType = undefined;
3199 const ptr_ty = if (param_ty.zigTypeTag() == .Optional)
3205 const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional)
32003206 param_ty.optionalChild(&opt_buf).slicePtrFieldType(&buf)
32013207 else
32023208 param_ty.slicePtrFieldType(&buf);
......@@ -3215,7 +3221,7 @@ pub const DeclGen = struct {
32153221 },
32163222 .float_array => |count| {
32173223 const param_ty = fn_info.param_types[it.zig_index - 1];
3218 const float_ty = try dg.lowerType(aarch64_c_abi.getFloatArrayType(param_ty).?);
3224 const float_ty = try dg.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?);
32193225 const field_count = @intCast(c_uint, count);
32203226 const arr_ty = float_ty.arrayType(field_count);
32213227 try llvm_params.append(arr_ty);
......@@ -3239,11 +3245,12 @@ pub const DeclGen = struct {
32393245 /// being a zero bit type, but it should still be lowered as an i8 in such case.
32403246 /// There are other similar cases handled here as well.
32413247 fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*llvm.Type {
3242 const lower_elem_ty = switch (elem_ty.zigTypeTag()) {
3248 const mod = dg.module;
3249 const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) {
32433250 .Opaque => true,
32443251 .Fn => !elem_ty.fnInfo().is_generic,
3245 .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(),
3246 else => elem_ty.hasRuntimeBitsIgnoreComptime(),
3252 .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(mod),
3253 else => elem_ty.hasRuntimeBitsIgnoreComptime(mod),
32473254 };
32483255 const llvm_elem_ty = if (lower_elem_ty)
32493256 try dg.lowerType(elem_ty)
......@@ -3262,9 +3269,9 @@ pub const DeclGen = struct {
32623269 const llvm_type = try dg.lowerType(tv.ty);
32633270 return llvm_type.getUndef();
32643271 }
3265 const target = dg.module.getTarget();
3266
3267 switch (tv.ty.zigTypeTag()) {
3272 const mod = dg.module;
3273 const target = mod.getTarget();
3274 switch (tv.ty.zigTypeTag(mod)) {
32683275 .Bool => {
32693276 const llvm_type = try dg.lowerType(tv.ty);
32703277 return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull();
......@@ -3276,8 +3283,8 @@ pub const DeclGen = struct {
32763283 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
32773284 else => {
32783285 var bigint_space: Value.BigIntSpace = undefined;
3279 const bigint = tv.val.toBigInt(&bigint_space, target);
3280 const int_info = tv.ty.intInfo(target);
3286 const bigint = tv.val.toBigInt(&bigint_space, mod);
3287 const int_info = tv.ty.intInfo(mod);
32813288 assert(int_info.bits != 0);
32823289 const llvm_type = dg.context.intType(int_info.bits);
32833290
......@@ -3304,9 +3311,9 @@ pub const DeclGen = struct {
33043311 const int_val = tv.enumToInt(&int_buffer);
33053312
33063313 var bigint_space: Value.BigIntSpace = undefined;
3307 const bigint = int_val.toBigInt(&bigint_space, target);
3314 const bigint = int_val.toBigInt(&bigint_space, mod);
33083315
3309 const int_info = tv.ty.intInfo(target);
3316 const int_info = tv.ty.intInfo(mod);
33103317 const llvm_type = dg.context.intType(int_info.bits);
33113318
33123319 const unsigned_val = v: {
......@@ -3408,7 +3415,7 @@ pub const DeclGen = struct {
34083415 },
34093416 .int_u64, .one, .int_big_positive, .lazy_align, .lazy_size => {
34103417 const llvm_usize = try dg.lowerType(Type.usize);
3411 const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(target), .False);
3418 const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(mod), .False);
34123419 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));
34133420 },
34143421 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
......@@ -3439,7 +3446,7 @@ pub const DeclGen = struct {
34393446 const str_lit = tv.val.castTag(.str_lit).?.data;
34403447 const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
34413448 if (tv.ty.sentinel()) |sent_val| {
3442 const byte = @intCast(u8, sent_val.toUnsignedInt(target));
3449 const byte = @intCast(u8, sent_val.toUnsignedInt(mod));
34433450 if (byte == 0 and bytes.len > 0) {
34443451 return dg.context.constString(
34453452 bytes.ptr,
......@@ -3549,13 +3556,13 @@ pub const DeclGen = struct {
35493556 const payload_ty = tv.ty.optionalChild(&buf);
35503557
35513558 const llvm_i8 = dg.context.intType(8);
3552 const is_pl = !tv.val.isNull();
3559 const is_pl = !tv.val.isNull(mod);
35533560 const non_null_bit = if (is_pl) llvm_i8.constInt(1, .False) else llvm_i8.constNull();
3554 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3561 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
35553562 return non_null_bit;
35563563 }
35573564 const llvm_ty = try dg.lowerType(tv.ty);
3558 if (tv.ty.optionalReprIsPayload()) {
3565 if (tv.ty.optionalReprIsPayload(mod)) {
35593566 if (tv.val.castTag(.opt_payload)) |payload| {
35603567 return dg.lowerValue(.{ .ty = payload_ty, .val = payload.data });
35613568 } else if (is_pl) {
......@@ -3564,7 +3571,7 @@ pub const DeclGen = struct {
35643571 return llvm_ty.constNull();
35653572 }
35663573 }
3567 assert(payload_ty.zigTypeTag() != .Fn);
3574 assert(payload_ty.zigTypeTag(mod) != .Fn);
35683575
35693576 const llvm_field_count = llvm_ty.countStructElementTypes();
35703577 var fields_buf: [3]*llvm.Value = undefined;
......@@ -3607,14 +3614,14 @@ pub const DeclGen = struct {
36073614 const payload_type = tv.ty.errorUnionPayload();
36083615 const is_pl = tv.val.errorUnionIsPayload();
36093616
3610 if (!payload_type.hasRuntimeBitsIgnoreComptime()) {
3617 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
36113618 // We use the error type directly as the type.
36123619 const err_val = if (!is_pl) tv.val else Value.initTag(.zero);
36133620 return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val });
36143621 }
36153622
3616 const payload_align = payload_type.abiAlignment(target);
3617 const error_align = Type.anyerror.abiAlignment(target);
3623 const payload_align = payload_type.abiAlignment(mod);
3624 const error_align = Type.anyerror.abiAlignment(mod);
36183625 const llvm_error_value = try dg.lowerValue(.{
36193626 .ty = Type.anyerror,
36203627 .val = if (is_pl) Value.initTag(.zero) else tv.val,
......@@ -3661,9 +3668,9 @@ pub const DeclGen = struct {
36613668
36623669 for (tuple.types, 0..) |field_ty, i| {
36633670 if (tuple.values[i].tag() != .unreachable_value) continue;
3664 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
3671 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
36653672
3666 const field_align = field_ty.abiAlignment(target);
3673 const field_align = field_ty.abiAlignment(mod);
36673674 big_align = @max(big_align, field_align);
36683675 const prev_offset = offset;
36693676 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
......@@ -3685,7 +3692,7 @@ pub const DeclGen = struct {
36853692
36863693 llvm_fields.appendAssumeCapacity(field_llvm_val);
36873694
3688 offset += field_ty.abiSize(target);
3695 offset += field_ty.abiSize(mod);
36893696 }
36903697 {
36913698 const prev_offset = offset;
......@@ -3715,7 +3722,7 @@ pub const DeclGen = struct {
37153722
37163723 if (struct_obj.layout == .Packed) {
37173724 assert(struct_obj.haveLayout());
3718 const big_bits = struct_obj.backing_int_ty.bitSize(target);
3725 const big_bits = struct_obj.backing_int_ty.bitSize(mod);
37193726 const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits));
37203727 const fields = struct_obj.fields.values();
37213728 comptime assert(Type.packed_struct_layout_version == 2);
......@@ -3723,15 +3730,15 @@ pub const DeclGen = struct {
37233730 var running_bits: u16 = 0;
37243731 for (field_vals, 0..) |field_val, i| {
37253732 const field = fields[i];
3726 if (!field.ty.hasRuntimeBitsIgnoreComptime()) continue;
3733 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
37273734
37283735 const non_int_val = try dg.lowerValue(.{
37293736 .ty = field.ty,
37303737 .val = field_val,
37313738 });
3732 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
3739 const ty_bit_size = @intCast(u16, field.ty.bitSize(mod));
37333740 const small_int_ty = dg.context.intType(ty_bit_size);
3734 const small_int_val = if (field.ty.isPtrAtRuntime())
3741 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
37353742 non_int_val.constPtrToInt(small_int_ty)
37363743 else
37373744 non_int_val.constBitCast(small_int_ty);
......@@ -3756,10 +3763,10 @@ pub const DeclGen = struct {
37563763 var big_align: u32 = 0;
37573764 var need_unnamed = false;
37583765
3759 var it = struct_obj.runtimeFieldIterator();
3766 var it = struct_obj.runtimeFieldIterator(mod);
37603767 while (it.next()) |field_and_index| {
37613768 const field = field_and_index.field;
3762 const field_align = field.alignment(target, struct_obj.layout);
3769 const field_align = field.alignment(mod, struct_obj.layout);
37633770 big_align = @max(big_align, field_align);
37643771 const prev_offset = offset;
37653772 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
......@@ -3781,7 +3788,7 @@ pub const DeclGen = struct {
37813788
37823789 llvm_fields.appendAssumeCapacity(field_llvm_val);
37833790
3784 offset += field.ty.abiSize(target);
3791 offset += field.ty.abiSize(mod);
37853792 }
37863793 {
37873794 const prev_offset = offset;
......@@ -3810,7 +3817,7 @@ pub const DeclGen = struct {
38103817 const llvm_union_ty = try dg.lowerType(tv.ty);
38113818 const tag_and_val = tv.val.castTag(.@"union").?.data;
38123819
3813 const layout = tv.ty.unionGetLayout(target);
3820 const layout = tv.ty.unionGetLayout(mod);
38143821
38153822 if (layout.payload_size == 0) {
38163823 return lowerValue(dg, .{
......@@ -3824,12 +3831,12 @@ pub const DeclGen = struct {
38243831
38253832 const field_ty = union_obj.fields.values()[field_index].ty;
38263833 if (union_obj.layout == .Packed) {
3827 if (!field_ty.hasRuntimeBits())
3834 if (!field_ty.hasRuntimeBits(mod))
38283835 return llvm_union_ty.constNull();
38293836 const non_int_val = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });
3830 const ty_bit_size = @intCast(u16, field_ty.bitSize(target));
3837 const ty_bit_size = @intCast(u16, field_ty.bitSize(mod));
38313838 const small_int_ty = dg.context.intType(ty_bit_size);
3832 const small_int_val = if (field_ty.isPtrAtRuntime())
3839 const small_int_val = if (field_ty.isPtrAtRuntime(mod))
38333840 non_int_val.constPtrToInt(small_int_ty)
38343841 else
38353842 non_int_val.constBitCast(small_int_ty);
......@@ -3842,13 +3849,13 @@ pub const DeclGen = struct {
38423849 // must pointer cast to the expected type before accessing the union.
38433850 var need_unnamed: bool = layout.most_aligned_field != field_index;
38443851 const payload = p: {
3845 if (!field_ty.hasRuntimeBitsIgnoreComptime()) {
3852 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {
38463853 const padding_len = @intCast(c_uint, layout.payload_size);
38473854 break :p dg.context.intType(8).arrayType(padding_len).getUndef();
38483855 }
38493856 const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });
38503857 need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field);
3851 const field_size = field_ty.abiSize(target);
3858 const field_size = field_ty.abiSize(mod);
38523859 if (field_size == layout.payload_size) {
38533860 break :p field;
38543861 }
......@@ -4012,7 +4019,8 @@ pub const DeclGen = struct {
40124019 }
40134020
40144021 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
4015 const target = dg.module.getTarget();
4022 const mod = dg.module;
4023 const target = mod.getTarget();
40164024 switch (ptr_val.tag()) {
40174025 .decl_ref_mut => {
40184026 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;
......@@ -4045,13 +4053,13 @@ pub const DeclGen = struct {
40454053
40464054 const field_index = @intCast(u32, field_ptr.field_index);
40474055 const llvm_u32 = dg.context.intType(32);
4048 switch (parent_ty.zigTypeTag()) {
4056 switch (parent_ty.zigTypeTag(mod)) {
40494057 .Union => {
40504058 if (parent_ty.containerLayout() == .Packed) {
40514059 return parent_llvm_ptr;
40524060 }
40534061
4054 const layout = parent_ty.unionGetLayout(target);
4062 const layout = parent_ty.unionGetLayout(mod);
40554063 if (layout.payload_size == 0) {
40564064 // In this case a pointer to the union and a pointer to any
40574065 // (void) payload is the same.
......@@ -4077,8 +4085,8 @@ pub const DeclGen = struct {
40774085 const prev_bits = b: {
40784086 var b: usize = 0;
40794087 for (parent_ty.structFields().values()[0..field_index]) |field| {
4080 if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue;
4081 b += @intCast(usize, field.ty.bitSize(target));
4088 if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
4089 b += @intCast(usize, field.ty.bitSize(mod));
40824090 }
40834091 break :b b;
40844092 };
......@@ -4091,14 +4099,14 @@ pub const DeclGen = struct {
40914099 var ty_buf: Type.Payload.Pointer = undefined;
40924100
40934101 const parent_llvm_ty = try dg.lowerType(parent_ty);
4094 if (llvmFieldIndex(parent_ty, field_index, target, &ty_buf)) |llvm_field_index| {
4102 if (llvmFieldIndex(parent_ty, field_index, mod, &ty_buf)) |llvm_field_index| {
40954103 const indices: [2]*llvm.Value = .{
40964104 llvm_u32.constInt(0, .False),
40974105 llvm_u32.constInt(llvm_field_index, .False),
40984106 };
40994107 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
41004108 } else {
4101 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False);
4109 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
41024110 const indices: [1]*llvm.Value = .{llvm_index};
41034111 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
41044112 }
......@@ -4132,8 +4140,8 @@ pub const DeclGen = struct {
41324140 var buf: Type.Payload.ElemType = undefined;
41334141
41344142 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);
4135 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or
4136 payload_ty.optionalReprIsPayload())
4143 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
4144 payload_ty.optionalReprIsPayload(mod))
41374145 {
41384146 // In this case, we represent pointer to optional the same as pointer
41394147 // to the payload.
......@@ -4153,13 +4161,13 @@ pub const DeclGen = struct {
41534161 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, true);
41544162
41554163 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
4156 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
4164 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
41574165 // In this case, we represent pointer to error union the same as pointer
41584166 // to the payload.
41594167 return parent_llvm_ptr;
41604168 }
41614169
4162 const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1;
4170 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
41634171 const llvm_u32 = dg.context.intType(32);
41644172 const indices: [2]*llvm.Value = .{
41654173 llvm_u32.constInt(0, .False),
......@@ -4177,12 +4185,13 @@ pub const DeclGen = struct {
41774185 tv: TypedValue,
41784186 decl_index: Module.Decl.Index,
41794187 ) Error!*llvm.Value {
4188 const mod = self.module;
41804189 if (tv.ty.isSlice()) {
41814190 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
41824191 const ptr_ty = tv.ty.slicePtrFieldType(&buf);
41834192 var slice_len: Value.Payload.U64 = .{
41844193 .base = .{ .tag = .int_u64 },
4185 .data = tv.val.sliceLen(self.module),
4194 .data = tv.val.sliceLen(mod),
41864195 };
41874196 const fields: [2]*llvm.Value = .{
41884197 try self.lowerValue(.{
......@@ -4202,7 +4211,7 @@ pub const DeclGen = struct {
42024211 // const bar = foo;
42034212 // ... &bar;
42044213 // `bar` is just an alias and we actually want to lower a reference to `foo`.
4205 const decl = self.module.declPtr(decl_index);
4214 const decl = mod.declPtr(decl_index);
42064215 if (decl.val.castTag(.function)) |func| {
42074216 if (func.data.owner_decl != decl_index) {
42084217 return self.lowerDeclRefValue(tv, func.data.owner_decl);
......@@ -4213,21 +4222,21 @@ pub const DeclGen = struct {
42134222 }
42144223 }
42154224
4216 const is_fn_body = decl.ty.zigTypeTag() == .Fn;
4217 if ((!is_fn_body and !decl.ty.hasRuntimeBits()) or
4225 const is_fn_body = decl.ty.zigTypeTag(mod) == .Fn;
4226 if ((!is_fn_body and !decl.ty.hasRuntimeBits(mod)) or
42184227 (is_fn_body and decl.ty.fnInfo().is_generic))
42194228 {
42204229 return self.lowerPtrToVoid(tv.ty);
42214230 }
42224231
4223 self.module.markDeclAlive(decl);
4232 mod.markDeclAlive(decl);
42244233
42254234 const llvm_decl_val = if (is_fn_body)
42264235 try self.resolveLlvmFunction(decl_index)
42274236 else
42284237 try self.resolveGlobalDecl(decl_index);
42294238
4230 const target = self.module.getTarget();
4239 const target = mod.getTarget();
42314240 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
42324241 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
42334242 const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: {
......@@ -4236,7 +4245,7 @@ pub const DeclGen = struct {
42364245 } else llvm_decl_val;
42374246
42384247 const llvm_type = try self.lowerType(tv.ty);
4239 if (tv.ty.zigTypeTag() == .Int) {
4248 if (tv.ty.zigTypeTag(mod) == .Int) {
42404249 return llvm_val.constPtrToInt(llvm_type);
42414250 } else {
42424251 return llvm_val.constBitCast(llvm_type);
......@@ -4338,21 +4347,20 @@ pub const DeclGen = struct {
43384347 /// RMW exchange of floating-point values is bitcasted to same-sized integer
43394348 /// types to work around a LLVM deficiency when targeting ARM/AArch64.
43404349 fn getAtomicAbiType(dg: *DeclGen, ty: Type, is_rmw_xchg: bool) ?*llvm.Type {
4341 const target = dg.module.getTarget();
4342 var buffer: Type.Payload.Bits = undefined;
4343 const int_ty = switch (ty.zigTypeTag()) {
4350 const mod = dg.module;
4351 const int_ty = switch (ty.zigTypeTag(mod)) {
43444352 .Int => ty,
4345 .Enum => ty.intTagType(&buffer),
4353 .Enum => ty.intTagType(),
43464354 .Float => {
43474355 if (!is_rmw_xchg) return null;
4348 return dg.context.intType(@intCast(c_uint, ty.abiSize(target) * 8));
4356 return dg.context.intType(@intCast(c_uint, ty.abiSize(mod) * 8));
43494357 },
43504358 .Bool => return dg.context.intType(8),
43514359 else => return null,
43524360 };
4353 const bit_count = int_ty.intInfo(target).bits;
4361 const bit_count = int_ty.intInfo(mod).bits;
43544362 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {
4355 return dg.context.intType(@intCast(c_uint, int_ty.abiSize(target) * 8));
4363 return dg.context.intType(@intCast(c_uint, int_ty.abiSize(mod) * 8));
43564364 } else {
43574365 return null;
43584366 }
......@@ -4366,15 +4374,15 @@ pub const DeclGen = struct {
43664374 fn_info: Type.Payload.Function.Data,
43674375 llvm_arg_i: u32,
43684376 ) void {
4369 const target = dg.module.getTarget();
4370 if (param_ty.isPtrAtRuntime()) {
4377 const mod = dg.module;
4378 if (param_ty.isPtrAtRuntime(mod)) {
43714379 const ptr_info = param_ty.ptrInfo().data;
43724380 if (math.cast(u5, param_index)) |i| {
43734381 if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {
43744382 dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias");
43754383 }
43764384 }
4377 if (!param_ty.isPtrLikeOptional() and !ptr_info.@"allowzero") {
4385 if (!param_ty.isPtrLikeOptional(mod) and !ptr_info.@"allowzero") {
43784386 dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
43794387 }
43804388 if (!ptr_info.mutable) {
......@@ -4383,13 +4391,10 @@ pub const DeclGen = struct {
43834391 if (ptr_info.@"align" != 0) {
43844392 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", ptr_info.@"align");
43854393 } else {
4386 const elem_align = @max(
4387 ptr_info.pointee_type.abiAlignment(target),
4388 1,
4389 );
4394 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
43904395 dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
43914396 }
4392 } else if (ccAbiPromoteInt(fn_info.cc, target, param_ty)) |s| switch (s) {
4397 } else if (ccAbiPromoteInt(fn_info.cc, mod, param_ty)) |s| switch (s) {
43934398 .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),
43944399 .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),
43954400 };
......@@ -4490,9 +4495,10 @@ pub const FuncGen = struct {
44904495 const gop = try self.func_inst_table.getOrPut(self.dg.gpa, inst);
44914496 if (gop.found_existing) return gop.value_ptr.*;
44924497
4498 const mod = self.dg.module;
44934499 const llvm_val = try self.resolveValue(.{
44944500 .ty = self.air.typeOf(inst),
4495 .val = self.air.value(inst).?,
4501 .val = self.air.value(inst, mod).?,
44964502 });
44974503 gop.value_ptr.* = llvm_val;
44984504 return llvm_val;
......@@ -4500,11 +4506,12 @@ pub const FuncGen = struct {
45004506
45014507 fn resolveValue(self: *FuncGen, tv: TypedValue) !*llvm.Value {
45024508 const llvm_val = try self.dg.lowerValue(tv);
4503 if (!isByRef(tv.ty)) return llvm_val;
4509 const mod = self.dg.module;
4510 if (!isByRef(tv.ty, mod)) return llvm_val;
45044511
45054512 // We have an LLVM value but we need to create a global constant and
45064513 // set the value as its initializer, and then return a pointer to the global.
4507 const target = self.dg.module.getTarget();
4514 const target = mod.getTarget();
45084515 const llvm_wanted_addrspace = toLlvmAddressSpace(.generic, target);
45094516 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(.generic, target);
45104517 const global = self.dg.object.llvm_module.addGlobalInAddressSpace(llvm_val.typeOf(), "", llvm_actual_addrspace);
......@@ -4512,7 +4519,7 @@ pub const FuncGen = struct {
45124519 global.setLinkage(.Private);
45134520 global.setGlobalConstant(.True);
45144521 global.setUnnamedAddr(.True);
4515 global.setAlignment(tv.ty.abiAlignment(target));
4522 global.setAlignment(tv.ty.abiAlignment(mod));
45164523 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)
45174524 global.constAddrSpaceCast(self.context.pointerType(llvm_wanted_addrspace))
45184525 else
......@@ -4775,7 +4782,8 @@ pub const FuncGen = struct {
47754782 const extra = self.air.extraData(Air.Call, pl_op.payload);
47764783 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
47774784 const callee_ty = self.air.typeOf(pl_op.operand);
4778 const zig_fn_ty = switch (callee_ty.zigTypeTag()) {
4785 const mod = self.dg.module;
4786 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
47794787 .Fn => callee_ty,
47804788 .Pointer => callee_ty.childType(),
47814789 else => unreachable,
......@@ -4783,20 +4791,20 @@ pub const FuncGen = struct {
47834791 const fn_info = zig_fn_ty.fnInfo();
47844792 const return_type = fn_info.return_type;
47854793 const llvm_fn = try self.resolveInst(pl_op.operand);
4786 const target = self.dg.module.getTarget();
4787 const sret = firstParamSRet(fn_info, target);
4794 const target = mod.getTarget();
4795 const sret = firstParamSRet(fn_info, mod);
47884796
47894797 var llvm_args = std.ArrayList(*llvm.Value).init(self.gpa);
47904798 defer llvm_args.deinit();
47914799
47924800 const ret_ptr = if (!sret) null else blk: {
47934801 const llvm_ret_ty = try self.dg.lowerType(return_type);
4794 const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(target));
4802 const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod));
47954803 try llvm_args.append(ret_ptr);
47964804 break :blk ret_ptr;
47974805 };
47984806
4799 const err_return_tracing = fn_info.return_type.isError() and
4807 const err_return_tracing = fn_info.return_type.isError(mod) and
48004808 self.dg.module.comp.bin_file.options.error_return_tracing;
48014809 if (err_return_tracing) {
48024810 try llvm_args.append(self.err_ret_trace.?);
......@@ -4810,8 +4818,8 @@ pub const FuncGen = struct {
48104818 const param_ty = self.air.typeOf(arg);
48114819 const llvm_arg = try self.resolveInst(arg);
48124820 const llvm_param_ty = try self.dg.lowerType(param_ty);
4813 if (isByRef(param_ty)) {
4814 const alignment = param_ty.abiAlignment(target);
4821 if (isByRef(param_ty, mod)) {
4822 const alignment = param_ty.abiAlignment(mod);
48154823 const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, "");
48164824 load_inst.setAlignment(alignment);
48174825 try llvm_args.append(load_inst);
......@@ -4823,10 +4831,10 @@ pub const FuncGen = struct {
48234831 const arg = args[it.zig_index - 1];
48244832 const param_ty = self.air.typeOf(arg);
48254833 const llvm_arg = try self.resolveInst(arg);
4826 if (isByRef(param_ty)) {
4834 if (isByRef(param_ty, mod)) {
48274835 try llvm_args.append(llvm_arg);
48284836 } else {
4829 const alignment = param_ty.abiAlignment(target);
4837 const alignment = param_ty.abiAlignment(mod);
48304838 const param_llvm_ty = llvm_arg.typeOf();
48314839 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);
48324840 const store_inst = self.builder.buildStore(llvm_arg, arg_ptr);
......@@ -4839,10 +4847,10 @@ pub const FuncGen = struct {
48394847 const param_ty = self.air.typeOf(arg);
48404848 const llvm_arg = try self.resolveInst(arg);
48414849
4842 const alignment = param_ty.abiAlignment(target);
4850 const alignment = param_ty.abiAlignment(mod);
48434851 const param_llvm_ty = try self.dg.lowerType(param_ty);
48444852 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);
4845 if (isByRef(param_ty)) {
4853 if (isByRef(param_ty, mod)) {
48464854 const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");
48474855 load_inst.setAlignment(alignment);
48484856
......@@ -4859,11 +4867,11 @@ pub const FuncGen = struct {
48594867 const arg = args[it.zig_index - 1];
48604868 const param_ty = self.air.typeOf(arg);
48614869 const llvm_arg = try self.resolveInst(arg);
4862 const abi_size = @intCast(c_uint, param_ty.abiSize(target));
4870 const abi_size = @intCast(c_uint, param_ty.abiSize(mod));
48634871 const int_llvm_ty = self.context.intType(abi_size * 8);
48644872
4865 if (isByRef(param_ty)) {
4866 const alignment = param_ty.abiAlignment(target);
4873 if (isByRef(param_ty, mod)) {
4874 const alignment = param_ty.abiAlignment(mod);
48674875 const load_inst = self.builder.buildLoad(int_llvm_ty, llvm_arg, "");
48684876 load_inst.setAlignment(alignment);
48694877 try llvm_args.append(load_inst);
......@@ -4871,7 +4879,7 @@ pub const FuncGen = struct {
48714879 // LLVM does not allow bitcasting structs so we must allocate
48724880 // a local, store as one type, and then load as another type.
48734881 const alignment = @max(
4874 param_ty.abiAlignment(target),
4882 param_ty.abiAlignment(mod),
48754883 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
48764884 );
48774885 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);
......@@ -4896,11 +4904,11 @@ pub const FuncGen = struct {
48964904 const param_ty = self.air.typeOf(arg);
48974905 const llvm_types = it.llvm_types_buffer[0..it.llvm_types_len];
48984906 const llvm_arg = try self.resolveInst(arg);
4899 const is_by_ref = isByRef(param_ty);
4907 const is_by_ref = isByRef(param_ty, mod);
49004908 const arg_ptr = if (is_by_ref) llvm_arg else p: {
49014909 const p = self.buildAlloca(llvm_arg.typeOf(), null);
49024910 const store_inst = self.builder.buildStore(llvm_arg, p);
4903 store_inst.setAlignment(param_ty.abiAlignment(target));
4911 store_inst.setAlignment(param_ty.abiAlignment(mod));
49044912 break :p p;
49054913 };
49064914
......@@ -4924,17 +4932,17 @@ pub const FuncGen = struct {
49244932 const arg = args[it.zig_index - 1];
49254933 const arg_ty = self.air.typeOf(arg);
49264934 var llvm_arg = try self.resolveInst(arg);
4927 if (!isByRef(arg_ty)) {
4935 if (!isByRef(arg_ty, mod)) {
49284936 const p = self.buildAlloca(llvm_arg.typeOf(), null);
49294937 const store_inst = self.builder.buildStore(llvm_arg, p);
4930 store_inst.setAlignment(arg_ty.abiAlignment(target));
4938 store_inst.setAlignment(arg_ty.abiAlignment(mod));
49314939 llvm_arg = store_inst;
49324940 }
49334941
4934 const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?);
4942 const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?);
49354943 const array_llvm_ty = float_ty.arrayType(count);
49364944
4937 const alignment = arg_ty.abiAlignment(target);
4945 const alignment = arg_ty.abiAlignment(mod);
49384946 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
49394947 load_inst.setAlignment(alignment);
49404948 try llvm_args.append(load_inst);
......@@ -4944,15 +4952,15 @@ pub const FuncGen = struct {
49444952 const arg = args[it.zig_index - 1];
49454953 const arg_ty = self.air.typeOf(arg);
49464954 var llvm_arg = try self.resolveInst(arg);
4947 if (!isByRef(arg_ty)) {
4955 if (!isByRef(arg_ty, mod)) {
49484956 const p = self.buildAlloca(llvm_arg.typeOf(), null);
49494957 const store_inst = self.builder.buildStore(llvm_arg, p);
4950 store_inst.setAlignment(arg_ty.abiAlignment(target));
4958 store_inst.setAlignment(arg_ty.abiAlignment(mod));
49514959 llvm_arg = store_inst;
49524960 }
49534961
49544962 const array_llvm_ty = self.context.intType(elem_size).arrayType(arr_len);
4955 const alignment = arg_ty.abiAlignment(target);
4963 const alignment = arg_ty.abiAlignment(mod);
49564964 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
49574965 load_inst.setAlignment(alignment);
49584966 try llvm_args.append(load_inst);
......@@ -4969,7 +4977,7 @@ pub const FuncGen = struct {
49694977 "",
49704978 );
49714979
4972 if (callee_ty.zigTypeTag() == .Pointer) {
4980 if (callee_ty.zigTypeTag(mod) == .Pointer) {
49734981 // Add argument attributes for function pointer calls.
49744982 it = iterateParamTypes(self.dg, fn_info);
49754983 it.llvm_index += @boolToInt(sret);
......@@ -4978,7 +4986,7 @@ pub const FuncGen = struct {
49784986 .byval => {
49794987 const param_index = it.zig_index - 1;
49804988 const param_ty = fn_info.param_types[param_index];
4981 if (!isByRef(param_ty)) {
4989 if (!isByRef(param_ty, mod)) {
49824990 self.dg.addByValParamAttrs(call, param_ty, param_index, fn_info, it.llvm_index - 1);
49834991 }
49844992 },
......@@ -4986,7 +4994,7 @@ pub const FuncGen = struct {
49864994 const param_index = it.zig_index - 1;
49874995 const param_ty = fn_info.param_types[param_index];
49884996 const param_llvm_ty = try self.dg.lowerType(param_ty);
4989 const alignment = param_ty.abiAlignment(target);
4997 const alignment = param_ty.abiAlignment(mod);
49904998 self.dg.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
49914999 },
49925000 .byref_mut => {
......@@ -5013,7 +5021,7 @@ pub const FuncGen = struct {
50135021 self.dg.addArgAttr(call, llvm_arg_i, "noalias");
50145022 }
50155023 }
5016 if (param_ty.zigTypeTag() != .Optional) {
5024 if (param_ty.zigTypeTag(mod) != .Optional) {
50175025 self.dg.addArgAttr(call, llvm_arg_i, "nonnull");
50185026 }
50195027 if (!ptr_info.mutable) {
......@@ -5022,7 +5030,7 @@ pub const FuncGen = struct {
50225030 if (ptr_info.@"align" != 0) {
50235031 self.dg.addArgAttrInt(call, llvm_arg_i, "align", ptr_info.@"align");
50245032 } else {
5025 const elem_align = @max(ptr_info.pointee_type.abiAlignment(target), 1);
5033 const elem_align = @max(ptr_info.pointee_type.abiAlignment(mod), 1);
50265034 self.dg.addArgAttrInt(call, llvm_arg_i, "align", elem_align);
50275035 }
50285036 },
......@@ -5033,7 +5041,7 @@ pub const FuncGen = struct {
50335041 return null;
50345042 }
50355043
5036 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime()) {
5044 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(mod)) {
50375045 return null;
50385046 }
50395047
......@@ -5041,12 +5049,12 @@ pub const FuncGen = struct {
50415049
50425050 if (ret_ptr) |rp| {
50435051 call.setCallSret(llvm_ret_ty);
5044 if (isByRef(return_type)) {
5052 if (isByRef(return_type, mod)) {
50455053 return rp;
50465054 } else {
50475055 // our by-ref status disagrees with sret so we must load.
50485056 const loaded = self.builder.buildLoad(llvm_ret_ty, rp, "");
5049 loaded.setAlignment(return_type.abiAlignment(target));
5057 loaded.setAlignment(return_type.abiAlignment(mod));
50505058 return loaded;
50515059 }
50525060 }
......@@ -5061,7 +5069,7 @@ pub const FuncGen = struct {
50615069 const rp = self.buildAlloca(llvm_ret_ty, alignment);
50625070 const store_inst = self.builder.buildStore(call, rp);
50635071 store_inst.setAlignment(alignment);
5064 if (isByRef(return_type)) {
5072 if (isByRef(return_type, mod)) {
50655073 return rp;
50665074 } else {
50675075 const load_inst = self.builder.buildLoad(llvm_ret_ty, rp, "");
......@@ -5070,10 +5078,10 @@ pub const FuncGen = struct {
50705078 }
50715079 }
50725080
5073 if (isByRef(return_type)) {
5081 if (isByRef(return_type, mod)) {
50745082 // our by-ref status disagrees with sret so we must allocate, store,
50755083 // and return the allocation pointer.
5076 const alignment = return_type.abiAlignment(target);
5084 const alignment = return_type.abiAlignment(mod);
50775085 const rp = self.buildAlloca(llvm_ret_ty, alignment);
50785086 const store_inst = self.builder.buildStore(call, rp);
50795087 store_inst.setAlignment(alignment);
......@@ -5084,6 +5092,7 @@ pub const FuncGen = struct {
50845092 }
50855093
50865094 fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5095 const mod = self.dg.module;
50875096 const un_op = self.air.instructions.items(.data)[inst].un_op;
50885097 const ret_ty = self.air.typeOf(un_op);
50895098 if (self.ret_ptr) |ret_ptr| {
......@@ -5098,8 +5107,8 @@ pub const FuncGen = struct {
50985107 return null;
50995108 }
51005109 const fn_info = self.dg.decl.ty.fnInfo();
5101 if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {
5102 if (fn_info.return_type.isError()) {
5110 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5111 if (fn_info.return_type.isError(mod)) {
51035112 // Functions with an empty error set are emitted with an error code
51045113 // return type and return zero so they can be function pointers coerced
51055114 // to functions that return anyerror.
......@@ -5113,10 +5122,9 @@ pub const FuncGen = struct {
51135122
51145123 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
51155124 const operand = try self.resolveInst(un_op);
5116 const target = self.dg.module.getTarget();
5117 const alignment = ret_ty.abiAlignment(target);
5125 const alignment = ret_ty.abiAlignment(mod);
51185126
5119 if (isByRef(ret_ty)) {
5127 if (isByRef(ret_ty, mod)) {
51205128 // operand is a pointer however self.ret_ptr is null so that means
51215129 // we need to return a value.
51225130 const load_inst = self.builder.buildLoad(abi_ret_ty, operand, "");
......@@ -5145,8 +5153,9 @@ pub const FuncGen = struct {
51455153 const ptr_ty = self.air.typeOf(un_op);
51465154 const ret_ty = ptr_ty.childType();
51475155 const fn_info = self.dg.decl.ty.fnInfo();
5148 if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {
5149 if (fn_info.return_type.isError()) {
5156 const mod = self.dg.module;
5157 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5158 if (fn_info.return_type.isError(mod)) {
51505159 // Functions with an empty error set are emitted with an error code
51515160 // return type and return zero so they can be function pointers coerced
51525161 // to functions that return anyerror.
......@@ -5162,10 +5171,9 @@ pub const FuncGen = struct {
51625171 return null;
51635172 }
51645173 const ptr = try self.resolveInst(un_op);
5165 const target = self.dg.module.getTarget();
51665174 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
51675175 const loaded = self.builder.buildLoad(abi_ret_ty, ptr, "");
5168 loaded.setAlignment(ret_ty.abiAlignment(target));
5176 loaded.setAlignment(ret_ty.abiAlignment(mod));
51695177 _ = self.builder.buildRet(loaded);
51705178 return null;
51715179 }
......@@ -5184,9 +5192,9 @@ pub const FuncGen = struct {
51845192 const src_list = try self.resolveInst(ty_op.operand);
51855193 const va_list_ty = self.air.getRefType(ty_op.ty);
51865194 const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);
5195 const mod = self.dg.module;
51875196
5188 const target = self.dg.module.getTarget();
5189 const result_alignment = va_list_ty.abiAlignment(target);
5197 const result_alignment = va_list_ty.abiAlignment(mod);
51905198 const dest_list = self.buildAlloca(llvm_va_list_ty, result_alignment);
51915199
51925200 const llvm_fn_name = "llvm.va_copy";
......@@ -5202,7 +5210,7 @@ pub const FuncGen = struct {
52025210 const args: [2]*llvm.Value = .{ dest_list, src_list };
52035211 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
52045212
5205 if (isByRef(va_list_ty)) {
5213 if (isByRef(va_list_ty, mod)) {
52065214 return dest_list;
52075215 } else {
52085216 const loaded = self.builder.buildLoad(llvm_va_list_ty, dest_list, "");
......@@ -5227,11 +5235,11 @@ pub const FuncGen = struct {
52275235 }
52285236
52295237 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5238 const mod = self.dg.module;
52305239 const va_list_ty = self.air.typeOfIndex(inst);
52315240 const llvm_va_list_ty = try self.dg.lowerType(va_list_ty);
52325241
5233 const target = self.dg.module.getTarget();
5234 const result_alignment = va_list_ty.abiAlignment(target);
5242 const result_alignment = va_list_ty.abiAlignment(mod);
52355243 const list = self.buildAlloca(llvm_va_list_ty, result_alignment);
52365244
52375245 const llvm_fn_name = "llvm.va_start";
......@@ -5243,7 +5251,7 @@ pub const FuncGen = struct {
52435251 const args: [1]*llvm.Value = .{list};
52445252 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
52455253
5246 if (isByRef(va_list_ty)) {
5254 if (isByRef(va_list_ty, mod)) {
52475255 return list;
52485256 } else {
52495257 const loaded = self.builder.buildLoad(llvm_va_list_ty, list, "");
......@@ -5292,23 +5300,23 @@ pub const FuncGen = struct {
52925300 operand_ty: Type,
52935301 op: math.CompareOperator,
52945302 ) Allocator.Error!*llvm.Value {
5295 var int_buffer: Type.Payload.Bits = undefined;
52965303 var opt_buffer: Type.Payload.ElemType = undefined;
52975304
5298 const scalar_ty = operand_ty.scalarType();
5299 const int_ty = switch (scalar_ty.zigTypeTag()) {
5300 .Enum => scalar_ty.intTagType(&int_buffer),
5305 const mod = self.dg.module;
5306 const scalar_ty = operand_ty.scalarType(mod);
5307 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {
5308 .Enum => scalar_ty.intTagType(),
53015309 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,
53025310 .Optional => blk: {
53035311 const payload_ty = operand_ty.optionalChild(&opt_buffer);
5304 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or
5305 operand_ty.optionalReprIsPayload())
5312 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or
5313 operand_ty.optionalReprIsPayload(mod))
53065314 {
53075315 break :blk operand_ty;
53085316 }
53095317 // We need to emit instructions to check for equality/inequality
53105318 // of optionals that are not pointers.
5311 const is_by_ref = isByRef(scalar_ty);
5319 const is_by_ref = isByRef(scalar_ty, mod);
53125320 const opt_llvm_ty = try self.dg.lowerType(scalar_ty);
53135321 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);
53145322 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);
......@@ -5375,7 +5383,7 @@ pub const FuncGen = struct {
53755383 .Float => return self.buildFloatCmp(op, operand_ty, .{ lhs, rhs }),
53765384 else => unreachable,
53775385 };
5378 const is_signed = int_ty.isSignedInt();
5386 const is_signed = int_ty.isSignedInt(mod);
53795387 const operation: llvm.IntPredicate = switch (op) {
53805388 .eq => .EQ,
53815389 .neq => .NE,
......@@ -5393,6 +5401,7 @@ pub const FuncGen = struct {
53935401 const body = self.air.extra[extra.end..][0..extra.data.body_len];
53945402 const inst_ty = self.air.typeOfIndex(inst);
53955403 const parent_bb = self.context.createBasicBlock("Block");
5404 const mod = self.dg.module;
53965405
53975406 if (inst_ty.isNoReturn()) {
53985407 try self.genBody(body);
......@@ -5414,8 +5423,8 @@ pub const FuncGen = struct {
54145423 self.builder.positionBuilderAtEnd(parent_bb);
54155424
54165425 // Create a phi node only if the block returns a value.
5417 const is_body = inst_ty.zigTypeTag() == .Fn;
5418 if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime()) return null;
5426 const is_body = inst_ty.zigTypeTag(mod) == .Fn;
5427 if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
54195428
54205429 const raw_llvm_ty = try self.dg.lowerType(inst_ty);
54215430
......@@ -5424,7 +5433,7 @@ pub const FuncGen = struct {
54245433 // a pointer to it. LLVM IR allows the call instruction to use function bodies instead
54255434 // of function pointers, however the phi makes it a runtime value and therefore
54265435 // the LLVM type has to be wrapped in a pointer.
5427 if (is_body or isByRef(inst_ty)) {
5436 if (is_body or isByRef(inst_ty, mod)) {
54285437 break :ty self.context.pointerType(0);
54295438 }
54305439 break :ty raw_llvm_ty;
......@@ -5445,7 +5454,8 @@ pub const FuncGen = struct {
54455454
54465455 // Add the values to the lists only if the break provides a value.
54475456 const operand_ty = self.air.typeOf(branch.operand);
5448 if (operand_ty.hasRuntimeBitsIgnoreComptime() or operand_ty.zigTypeTag() == .Fn) {
5457 const mod = self.dg.module;
5458 if (operand_ty.hasRuntimeBitsIgnoreComptime(mod) or operand_ty.zigTypeTag(mod) == .Fn) {
54495459 const val = try self.resolveInst(branch.operand);
54505460
54515461 // For the phi node, we need the basic blocks and the values of the
......@@ -5481,6 +5491,7 @@ pub const FuncGen = struct {
54815491 }
54825492
54835493 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5494 const mod = self.dg.module;
54845495 const inst = body_tail[0];
54855496 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
54865497 const err_union = try self.resolveInst(pl_op.operand);
......@@ -5488,7 +5499,7 @@ pub const FuncGen = struct {
54885499 const body = self.air.extra[extra.end..][0..extra.data.body_len];
54895500 const err_union_ty = self.air.typeOf(pl_op.operand);
54905501 const payload_ty = self.air.typeOfIndex(inst);
5491 const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;
5502 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;
54925503 const is_unused = self.liveness.isUnused(inst);
54935504 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);
54945505 }
......@@ -5512,9 +5523,9 @@ pub const FuncGen = struct {
55125523 can_elide_load: bool,
55135524 is_unused: bool,
55145525 ) !?*llvm.Value {
5526 const mod = fg.dg.module;
55155527 const payload_ty = err_union_ty.errorUnionPayload();
5516 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
5517 const target = fg.dg.module.getTarget();
5528 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
55185529 const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);
55195530
55205531 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
......@@ -5529,8 +5540,8 @@ pub const FuncGen = struct {
55295540 err_union;
55305541 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
55315542 }
5532 const err_field_index = errUnionErrorOffset(payload_ty, target);
5533 if (operand_is_ptr or isByRef(err_union_ty)) {
5543 const err_field_index = errUnionErrorOffset(payload_ty, mod);
5544 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
55345545 const err_field_ptr = fg.builder.buildStructGEP(err_union_llvm_ty, err_union, err_field_index, "");
55355546 // TODO add alignment to this load
55365547 const loaded = fg.builder.buildLoad(err_set_ty, err_field_ptr, "");
......@@ -5555,30 +5566,31 @@ pub const FuncGen = struct {
55555566 if (!payload_has_bits) {
55565567 return if (operand_is_ptr) err_union else null;
55575568 }
5558 const offset = errUnionPayloadOffset(payload_ty, target);
5569 const offset = errUnionPayloadOffset(payload_ty, mod);
55595570 if (operand_is_ptr) {
55605571 return fg.builder.buildStructGEP(err_union_llvm_ty, err_union, offset, "");
5561 } else if (isByRef(err_union_ty)) {
5572 } else if (isByRef(err_union_ty, mod)) {
55625573 const payload_ptr = fg.builder.buildStructGEP(err_union_llvm_ty, err_union, offset, "");
5563 if (isByRef(payload_ty)) {
5574 if (isByRef(payload_ty, mod)) {
55645575 if (can_elide_load)
55655576 return payload_ptr;
55665577
5567 return fg.loadByRef(payload_ptr, payload_ty, payload_ty.abiAlignment(target), false);
5578 return fg.loadByRef(payload_ptr, payload_ty, payload_ty.abiAlignment(mod), false);
55685579 }
55695580 const load_inst = fg.builder.buildLoad(err_union_llvm_ty.structGetTypeAtIndex(offset), payload_ptr, "");
5570 load_inst.setAlignment(payload_ty.abiAlignment(target));
5581 load_inst.setAlignment(payload_ty.abiAlignment(mod));
55715582 return load_inst;
55725583 }
55735584 return fg.builder.buildExtractValue(err_union, offset, "");
55745585 }
55755586
55765587 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5588 const mod = self.dg.module;
55775589 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
55785590 const cond = try self.resolveInst(pl_op.operand);
55795591 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
55805592 const else_block = self.context.appendBasicBlock(self.llvm_func, "Else");
5581 const target = self.dg.module.getTarget();
5593 const target = mod.getTarget();
55825594 const llvm_usize = self.context.intType(target.ptrBitWidth());
55835595 const cond_int = if (cond.typeOf().getTypeKind() == .Pointer)
55845596 self.builder.buildPtrToInt(cond, llvm_usize, "")
......@@ -5645,6 +5657,7 @@ pub const FuncGen = struct {
56455657 }
56465658
56475659 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5660 const mod = self.dg.module;
56485661 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
56495662 const operand_ty = self.air.typeOf(ty_op.operand);
56505663 const array_ty = operand_ty.childType();
......@@ -5652,7 +5665,7 @@ pub const FuncGen = struct {
56525665 const len = llvm_usize.constInt(array_ty.arrayLen(), .False);
56535666 const slice_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
56545667 const operand = try self.resolveInst(ty_op.operand);
5655 if (!array_ty.hasRuntimeBitsIgnoreComptime()) {
5668 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
56565669 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");
56575670 return self.builder.buildInsertValue(partial, len, 1, "");
56585671 }
......@@ -5666,30 +5679,31 @@ pub const FuncGen = struct {
56665679 }
56675680
56685681 fn airIntToFloat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5682 const mod = self.dg.module;
56695683 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
56705684
56715685 const operand = try self.resolveInst(ty_op.operand);
56725686 const operand_ty = self.air.typeOf(ty_op.operand);
5673 const operand_scalar_ty = operand_ty.scalarType();
5687 const operand_scalar_ty = operand_ty.scalarType(mod);
56745688
56755689 const dest_ty = self.air.typeOfIndex(inst);
5676 const dest_scalar_ty = dest_ty.scalarType();
5690 const dest_scalar_ty = dest_ty.scalarType(mod);
56775691 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
5678 const target = self.dg.module.getTarget();
5692 const target = mod.getTarget();
56795693
56805694 if (intrinsicsAllowed(dest_scalar_ty, target)) {
5681 if (operand_scalar_ty.isSignedInt()) {
5695 if (operand_scalar_ty.isSignedInt(mod)) {
56825696 return self.builder.buildSIToFP(operand, dest_llvm_ty, "");
56835697 } else {
56845698 return self.builder.buildUIToFP(operand, dest_llvm_ty, "");
56855699 }
56865700 }
56875701
5688 const operand_bits = @intCast(u16, operand_scalar_ty.bitSize(target));
5702 const operand_bits = @intCast(u16, operand_scalar_ty.bitSize(mod));
56895703 const rt_int_bits = compilerRtIntBits(operand_bits);
56905704 const rt_int_ty = self.context.intType(rt_int_bits);
56915705 var extended = e: {
5692 if (operand_scalar_ty.isSignedInt()) {
5706 if (operand_scalar_ty.isSignedInt(mod)) {
56935707 break :e self.builder.buildSExtOrBitCast(operand, rt_int_ty, "");
56945708 } else {
56955709 break :e self.builder.buildZExtOrBitCast(operand, rt_int_ty, "");
......@@ -5698,7 +5712,7 @@ pub const FuncGen = struct {
56985712 const dest_bits = dest_scalar_ty.floatBits(target);
56995713 const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits);
57005714 const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits);
5701 const sign_prefix = if (operand_scalar_ty.isSignedInt()) "" else "un";
5715 const sign_prefix = if (operand_scalar_ty.isSignedInt(mod)) "" else "un";
57025716 var fn_name_buf: [64]u8 = undefined;
57035717 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__float{s}{s}i{s}f", .{
57045718 sign_prefix,
......@@ -5724,27 +5738,28 @@ pub const FuncGen = struct {
57245738 fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
57255739 self.builder.setFastMath(want_fast_math);
57265740
5727 const target = self.dg.module.getTarget();
5741 const mod = self.dg.module;
5742 const target = mod.getTarget();
57285743 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
57295744
57305745 const operand = try self.resolveInst(ty_op.operand);
57315746 const operand_ty = self.air.typeOf(ty_op.operand);
5732 const operand_scalar_ty = operand_ty.scalarType();
5747 const operand_scalar_ty = operand_ty.scalarType(mod);
57335748
57345749 const dest_ty = self.air.typeOfIndex(inst);
5735 const dest_scalar_ty = dest_ty.scalarType();
5750 const dest_scalar_ty = dest_ty.scalarType(mod);
57365751 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
57375752
57385753 if (intrinsicsAllowed(operand_scalar_ty, target)) {
57395754 // TODO set fast math flag
5740 if (dest_scalar_ty.isSignedInt()) {
5755 if (dest_scalar_ty.isSignedInt(mod)) {
57415756 return self.builder.buildFPToSI(operand, dest_llvm_ty, "");
57425757 } else {
57435758 return self.builder.buildFPToUI(operand, dest_llvm_ty, "");
57445759 }
57455760 }
57465761
5747 const rt_int_bits = compilerRtIntBits(@intCast(u16, dest_scalar_ty.bitSize(target)));
5762 const rt_int_bits = compilerRtIntBits(@intCast(u16, dest_scalar_ty.bitSize(mod)));
57485763 const ret_ty = self.context.intType(rt_int_bits);
57495764 const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: {
57505765 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
......@@ -5756,7 +5771,7 @@ pub const FuncGen = struct {
57565771 const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits);
57575772
57585773 const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits);
5759 const sign_prefix = if (dest_scalar_ty.isSignedInt()) "" else "uns";
5774 const sign_prefix = if (dest_scalar_ty.isSignedInt(mod)) "" else "uns";
57605775
57615776 var fn_name_buf: [64]u8 = undefined;
57625777 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{
......@@ -5786,13 +5801,14 @@ pub const FuncGen = struct {
57865801 }
57875802
57885803 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: *llvm.Value, ty: Type) *llvm.Value {
5789 const target = fg.dg.module.getTarget();
5804 const mod = fg.dg.module;
5805 const target = mod.getTarget();
57905806 const llvm_usize_ty = fg.context.intType(target.ptrBitWidth());
57915807 switch (ty.ptrSize()) {
57925808 .Slice => {
57935809 const len = fg.builder.buildExtractValue(ptr, 1, "");
57945810 const elem_ty = ty.childType();
5795 const abi_size = elem_ty.abiSize(target);
5811 const abi_size = elem_ty.abiSize(mod);
57965812 if (abi_size == 1) return len;
57975813 const abi_size_llvm_val = llvm_usize_ty.constInt(abi_size, .False);
57985814 return fg.builder.buildMul(len, abi_size_llvm_val, "");
......@@ -5800,7 +5816,7 @@ pub const FuncGen = struct {
58005816 .One => {
58015817 const array_ty = ty.childType();
58025818 const elem_ty = array_ty.childType();
5803 const abi_size = elem_ty.abiSize(target);
5819 const abi_size = elem_ty.abiSize(mod);
58045820 return llvm_usize_ty.constInt(array_ty.arrayLen() * abi_size, .False);
58055821 },
58065822 .Many, .C => unreachable,
......@@ -5823,6 +5839,7 @@ pub const FuncGen = struct {
58235839 }
58245840
58255841 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5842 const mod = self.dg.module;
58265843 const inst = body_tail[0];
58275844 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
58285845 const slice_ty = self.air.typeOf(bin_op.lhs);
......@@ -5833,12 +5850,11 @@ pub const FuncGen = struct {
58335850 const base_ptr = self.builder.buildExtractValue(slice, 0, "");
58345851 const indices: [1]*llvm.Value = .{index};
58355852 const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
5836 if (isByRef(elem_ty)) {
5853 if (isByRef(elem_ty, mod)) {
58375854 if (self.canElideLoad(body_tail))
58385855 return ptr;
58395856
5840 const target = self.dg.module.getTarget();
5841 return self.loadByRef(ptr, elem_ty, elem_ty.abiAlignment(target), false);
5857 return self.loadByRef(ptr, elem_ty, elem_ty.abiAlignment(mod), false);
58425858 }
58435859
58445860 return self.load(ptr, slice_ty);
......@@ -5858,6 +5874,7 @@ pub const FuncGen = struct {
58585874 }
58595875
58605876 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5877 const mod = self.dg.module;
58615878 const inst = body_tail[0];
58625879
58635880 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
......@@ -5866,15 +5883,14 @@ pub const FuncGen = struct {
58665883 const rhs = try self.resolveInst(bin_op.rhs);
58675884 const array_llvm_ty = try self.dg.lowerType(array_ty);
58685885 const elem_ty = array_ty.childType();
5869 if (isByRef(array_ty)) {
5886 if (isByRef(array_ty, mod)) {
58705887 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
5871 if (isByRef(elem_ty)) {
5888 if (isByRef(elem_ty, mod)) {
58725889 const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, "");
58735890 if (canElideLoad(self, body_tail))
58745891 return elem_ptr;
58755892
5876 const target = self.dg.module.getTarget();
5877 return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(target), false);
5893 return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false);
58785894 } else {
58795895 const lhs_index = Air.refToIndex(bin_op.lhs).?;
58805896 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
......@@ -5901,6 +5917,7 @@ pub const FuncGen = struct {
59015917 }
59025918
59035919 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5920 const mod = self.dg.module;
59045921 const inst = body_tail[0];
59055922 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
59065923 const ptr_ty = self.air.typeOf(bin_op.lhs);
......@@ -5917,23 +5934,23 @@ pub const FuncGen = struct {
59175934 const indices: [1]*llvm.Value = .{rhs};
59185935 break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
59195936 };
5920 if (isByRef(elem_ty)) {
5937 if (isByRef(elem_ty, mod)) {
59215938 if (self.canElideLoad(body_tail))
59225939 return ptr;
59235940
5924 const target = self.dg.module.getTarget();
5925 return self.loadByRef(ptr, elem_ty, elem_ty.abiAlignment(target), false);
5941 return self.loadByRef(ptr, elem_ty, elem_ty.abiAlignment(mod), false);
59265942 }
59275943
59285944 return self.load(ptr, ptr_ty);
59295945 }
59305946
59315947 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5948 const mod = self.dg.module;
59325949 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
59335950 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
59345951 const ptr_ty = self.air.typeOf(bin_op.lhs);
59355952 const elem_ty = ptr_ty.childType();
5936 if (!elem_ty.hasRuntimeBitsIgnoreComptime()) return self.dg.lowerPtrToVoid(ptr_ty);
5953 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
59375954
59385955 const base_ptr = try self.resolveInst(bin_op.lhs);
59395956 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -5972,6 +5989,7 @@ pub const FuncGen = struct {
59725989 }
59735990
59745991 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
5992 const mod = self.dg.module;
59755993 const inst = body_tail[0];
59765994 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
59775995 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
......@@ -5979,29 +5997,28 @@ pub const FuncGen = struct {
59795997 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
59805998 const field_index = struct_field.field_index;
59815999 const field_ty = struct_ty.structFieldType(field_index);
5982 if (!field_ty.hasRuntimeBitsIgnoreComptime()) {
6000 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {
59836001 return null;
59846002 }
5985 const target = self.dg.module.getTarget();
59866003
5987 if (!isByRef(struct_ty)) {
5988 assert(!isByRef(field_ty));
5989 switch (struct_ty.zigTypeTag()) {
6004 if (!isByRef(struct_ty, mod)) {
6005 assert(!isByRef(field_ty, mod));
6006 switch (struct_ty.zigTypeTag(mod)) {
59906007 .Struct => switch (struct_ty.containerLayout()) {
59916008 .Packed => {
59926009 const struct_obj = struct_ty.castTag(.@"struct").?.data;
5993 const bit_offset = struct_obj.packedFieldBitOffset(target, field_index);
6010 const bit_offset = struct_obj.packedFieldBitOffset(mod, field_index);
59946011 const containing_int = struct_llvm_val;
59956012 const shift_amt = containing_int.typeOf().constInt(bit_offset, .False);
59966013 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
59976014 const elem_llvm_ty = try self.dg.lowerType(field_ty);
5998 if (field_ty.zigTypeTag() == .Float or field_ty.zigTypeTag() == .Vector) {
5999 const elem_bits = @intCast(c_uint, field_ty.bitSize(target));
6015 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
6016 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
60006017 const same_size_int = self.context.intType(elem_bits);
60016018 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
60026019 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
6003 } else if (field_ty.isPtrAtRuntime()) {
6004 const elem_bits = @intCast(c_uint, field_ty.bitSize(target));
6020 } else if (field_ty.isPtrAtRuntime(mod)) {
6021 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
60056022 const same_size_int = self.context.intType(elem_bits);
60066023 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
60076024 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
......@@ -6010,7 +6027,7 @@ pub const FuncGen = struct {
60106027 },
60116028 else => {
60126029 var ptr_ty_buf: Type.Payload.Pointer = undefined;
6013 const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf).?;
6030 const llvm_field_index = llvmFieldIndex(struct_ty, field_index, mod, &ptr_ty_buf).?;
60146031 return self.builder.buildExtractValue(struct_llvm_val, llvm_field_index, "");
60156032 },
60166033 },
......@@ -6018,13 +6035,13 @@ pub const FuncGen = struct {
60186035 assert(struct_ty.containerLayout() == .Packed);
60196036 const containing_int = struct_llvm_val;
60206037 const elem_llvm_ty = try self.dg.lowerType(field_ty);
6021 if (field_ty.zigTypeTag() == .Float or field_ty.zigTypeTag() == .Vector) {
6022 const elem_bits = @intCast(c_uint, field_ty.bitSize(target));
6038 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
6039 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
60236040 const same_size_int = self.context.intType(elem_bits);
60246041 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
60256042 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
6026 } else if (field_ty.isPtrAtRuntime()) {
6027 const elem_bits = @intCast(c_uint, field_ty.bitSize(target));
6043 } else if (field_ty.isPtrAtRuntime(mod)) {
6044 const elem_bits = @intCast(c_uint, field_ty.bitSize(mod));
60286045 const same_size_int = self.context.intType(elem_bits);
60296046 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
60306047 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
......@@ -6035,30 +6052,30 @@ pub const FuncGen = struct {
60356052 }
60366053 }
60376054
6038 switch (struct_ty.zigTypeTag()) {
6055 switch (struct_ty.zigTypeTag(mod)) {
60396056 .Struct => {
60406057 assert(struct_ty.containerLayout() != .Packed);
60416058 var ptr_ty_buf: Type.Payload.Pointer = undefined;
6042 const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf).?;
6059 const llvm_field_index = llvmFieldIndex(struct_ty, field_index, mod, &ptr_ty_buf).?;
60436060 const struct_llvm_ty = try self.dg.lowerType(struct_ty);
60446061 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");
60456062 const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);
6046 if (isByRef(field_ty)) {
6063 if (isByRef(field_ty, mod)) {
60476064 if (canElideLoad(self, body_tail))
60486065 return field_ptr;
60496066
6050 return self.loadByRef(field_ptr, field_ty, ptr_ty_buf.data.alignment(target), false);
6067 return self.loadByRef(field_ptr, field_ty, ptr_ty_buf.data.alignment(mod), false);
60516068 } else {
60526069 return self.load(field_ptr, field_ptr_ty);
60536070 }
60546071 },
60556072 .Union => {
60566073 const union_llvm_ty = try self.dg.lowerType(struct_ty);
6057 const layout = struct_ty.unionGetLayout(target);
6074 const layout = struct_ty.unionGetLayout(mod);
60586075 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
60596076 const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");
60606077 const llvm_field_ty = try self.dg.lowerType(field_ty);
6061 if (isByRef(field_ty)) {
6078 if (isByRef(field_ty, mod)) {
60626079 if (canElideLoad(self, body_tail))
60636080 return field_ptr;
60646081
......@@ -6072,6 +6089,7 @@ pub const FuncGen = struct {
60726089 }
60736090
60746091 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6092 const mod = self.dg.module;
60756093 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
60766094 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
60776095
......@@ -6079,7 +6097,7 @@ pub const FuncGen = struct {
60796097
60806098 const target = self.dg.module.getTarget();
60816099 const parent_ty = self.air.getRefType(ty_pl.ty).childType();
6082 const field_offset = parent_ty.structFieldOffset(extra.field_index, target);
6100 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);
60836101
60846102 const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));
60856103 if (field_offset == 0) {
......@@ -6119,12 +6137,13 @@ pub const FuncGen = struct {
61196137 }
61206138
61216139 fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6140 const mod = self.dg.module;
61226141 const dib = self.dg.object.di_builder orelse return null;
61236142 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
61246143
61256144 const func = self.air.values[ty_pl.payload].castTag(.function).?.data;
61266145 const decl_index = func.owner_decl;
6127 const decl = self.dg.module.declPtr(decl_index);
6146 const decl = mod.declPtr(decl_index);
61286147 const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);
61296148 self.di_file = di_file;
61306149 const line_number = decl.src_line + 1;
......@@ -6136,22 +6155,41 @@ pub const FuncGen = struct {
61366155 .base_line = self.base_line,
61376156 });
61386157
6139 const fqn = try decl.getFullyQualifiedName(self.dg.module);
6158 const fqn = try decl.getFullyQualifiedName(mod);
61406159 defer self.gpa.free(fqn);
61416160
6142 const is_internal_linkage = !self.dg.module.decl_exports.contains(decl_index);
6161 const is_internal_linkage = !mod.decl_exports.contains(decl_index);
6162 var fn_ty_pl: Type.Payload.Function = .{
6163 .base = .{ .tag = .function },
6164 .data = .{
6165 .param_types = &.{},
6166 .comptime_params = undefined,
6167 .return_type = Type.void,
6168 .alignment = 0,
6169 .noalias_bits = 0,
6170 .cc = .Unspecified,
6171 .is_var_args = false,
6172 .is_generic = false,
6173 .is_noinline = false,
6174 .align_is_generic = false,
6175 .cc_is_generic = false,
6176 .section_is_generic = false,
6177 .addrspace_is_generic = false,
6178 },
6179 };
6180 const fn_ty = Type.initPayload(&fn_ty_pl.base);
61436181 const subprogram = dib.createFunction(
61446182 di_file.toScope(),
61456183 decl.name,
61466184 fqn,
61476185 di_file,
61486186 line_number,
6149 try self.dg.object.lowerDebugType(Type.initTag(.fn_void_no_args), .full),
6187 try self.dg.object.lowerDebugType(fn_ty, .full),
61506188 is_internal_linkage,
61516189 true, // is definition
61526190 line_number + func.lbrace_line, // scope line
61536191 llvm.DIFlags.StaticMember,
6154 self.dg.module.comp.bin_file.options.optimize_mode != .Debug,
6192 mod.comp.bin_file.options.optimize_mode != .Debug,
61556193 null, // decl_subprogram
61566194 );
61576195
......@@ -6243,10 +6281,11 @@ pub const FuncGen = struct {
62436281 null;
62446282 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);
62456283 const insert_block = self.builder.getInsertBlock();
6246 if (isByRef(operand_ty)) {
6284 const mod = self.dg.module;
6285 if (isByRef(operand_ty, mod)) {
62476286 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);
62486287 } else if (self.dg.module.comp.bin_file.options.optimize_mode == .Debug) {
6249 const alignment = operand_ty.abiAlignment(self.dg.module.getTarget());
6288 const alignment = operand_ty.abiAlignment(mod);
62506289 const alloca = self.buildAlloca(operand.typeOf(), alignment);
62516290 const store_inst = self.builder.buildStore(operand, alloca);
62526291 store_inst.setAlignment(alignment);
......@@ -6294,7 +6333,8 @@ pub const FuncGen = struct {
62946333 // This stores whether we need to add an elementtype attribute and
62956334 // if so, the element type itself.
62966335 const llvm_param_attrs = try arena.alloc(?*llvm.Type, max_param_count);
6297 const target = self.dg.module.getTarget();
6336 const mod = self.dg.module;
6337 const target = mod.getTarget();
62986338
62996339 var llvm_ret_i: usize = 0;
63006340 var llvm_param_i: usize = 0;
......@@ -6322,7 +6362,7 @@ pub const FuncGen = struct {
63226362 if (output != .none) {
63236363 const output_inst = try self.resolveInst(output);
63246364 const output_ty = self.air.typeOf(output);
6325 assert(output_ty.zigTypeTag() == .Pointer);
6365 assert(output_ty.zigTypeTag(mod) == .Pointer);
63266366 const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType());
63276367
63286368 if (llvm_ret_indirect[i]) {
......@@ -6376,13 +6416,13 @@ pub const FuncGen = struct {
63766416 const arg_llvm_value = try self.resolveInst(input);
63776417 const arg_ty = self.air.typeOf(input);
63786418 var llvm_elem_ty: ?*llvm.Type = null;
6379 if (isByRef(arg_ty)) {
6419 if (isByRef(arg_ty, mod)) {
63806420 llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty);
63816421 if (constraintAllowsMemory(constraint)) {
63826422 llvm_param_values[llvm_param_i] = arg_llvm_value;
63836423 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
63846424 } else {
6385 const alignment = arg_ty.abiAlignment(target);
6425 const alignment = arg_ty.abiAlignment(mod);
63866426 const arg_llvm_ty = try self.dg.lowerType(arg_ty);
63876427 const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, "");
63886428 load_inst.setAlignment(alignment);
......@@ -6394,7 +6434,7 @@ pub const FuncGen = struct {
63946434 llvm_param_values[llvm_param_i] = arg_llvm_value;
63956435 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
63966436 } else {
6397 const alignment = arg_ty.abiAlignment(target);
6437 const alignment = arg_ty.abiAlignment(mod);
63986438 const arg_ptr = self.buildAlloca(arg_llvm_value.typeOf(), alignment);
63996439 const store_inst = self.builder.buildStore(arg_llvm_value, arg_ptr);
64006440 store_inst.setAlignment(alignment);
......@@ -6599,7 +6639,7 @@ pub const FuncGen = struct {
65996639 const output_ptr_ty = self.air.typeOf(output);
66006640
66016641 const store_inst = self.builder.buildStore(output_value, output_ptr);
6602 store_inst.setAlignment(output_ptr_ty.ptrAlignment(target));
6642 store_inst.setAlignment(output_ptr_ty.ptrAlignment(mod));
66036643 } else {
66046644 ret_val = output_value;
66056645 }
......@@ -6622,7 +6662,8 @@ pub const FuncGen = struct {
66226662 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
66236663 var buf: Type.Payload.ElemType = undefined;
66246664 const payload_ty = optional_ty.optionalChild(&buf);
6625 if (optional_ty.optionalReprIsPayload()) {
6665 const mod = self.dg.module;
6666 if (optional_ty.optionalReprIsPayload(mod)) {
66266667 const loaded = if (operand_is_ptr)
66276668 self.builder.buildLoad(optional_llvm_ty, operand, "")
66286669 else
......@@ -6638,7 +6679,7 @@ pub const FuncGen = struct {
66386679
66396680 comptime assert(optional_layout_version == 3);
66406681
6641 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6682 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
66426683 const loaded = if (operand_is_ptr)
66436684 self.builder.buildLoad(optional_llvm_ty, operand, "")
66446685 else
......@@ -6647,7 +6688,7 @@ pub const FuncGen = struct {
66476688 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
66486689 }
66496690
6650 const is_by_ref = operand_is_ptr or isByRef(optional_ty);
6691 const is_by_ref = operand_is_ptr or isByRef(optional_ty, mod);
66516692 const non_null_bit = self.optIsNonNull(optional_llvm_ty, operand, is_by_ref);
66526693 if (pred == .EQ) {
66536694 return self.builder.buildNot(non_null_bit, "");
......@@ -6662,6 +6703,7 @@ pub const FuncGen = struct {
66626703 op: llvm.IntPredicate,
66636704 operand_is_ptr: bool,
66646705 ) !?*llvm.Value {
6706 const mod = self.dg.module;
66656707 const un_op = self.air.instructions.items(.data)[inst].un_op;
66666708 const operand = try self.resolveInst(un_op);
66676709 const operand_ty = self.air.typeOf(un_op);
......@@ -6679,7 +6721,7 @@ pub const FuncGen = struct {
66796721 }
66806722 }
66816723
6682 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6724 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
66836725 const loaded = if (operand_is_ptr)
66846726 self.builder.buildLoad(try self.dg.lowerType(err_union_ty), operand, "")
66856727 else
......@@ -6687,10 +6729,9 @@ pub const FuncGen = struct {
66876729 return self.builder.buildICmp(op, loaded, zero, "");
66886730 }
66896731
6690 const target = self.dg.module.getTarget();
6691 const err_field_index = errUnionErrorOffset(payload_ty, target);
6732 const err_field_index = errUnionErrorOffset(payload_ty, mod);
66926733
6693 if (operand_is_ptr or isByRef(err_union_ty)) {
6734 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
66946735 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
66956736 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, "");
66966737 const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, "");
......@@ -6702,17 +6743,18 @@ pub const FuncGen = struct {
67026743 }
67036744
67046745 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6746 const mod = self.dg.module;
67056747 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67066748 const operand = try self.resolveInst(ty_op.operand);
67076749 const optional_ty = self.air.typeOf(ty_op.operand).childType();
67086750 var buf: Type.Payload.ElemType = undefined;
67096751 const payload_ty = optional_ty.optionalChild(&buf);
6710 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6752 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
67116753 // We have a pointer to a zero-bit value and we need to return
67126754 // a pointer to a zero-bit value.
67136755 return operand;
67146756 }
6715 if (optional_ty.optionalReprIsPayload()) {
6757 if (optional_ty.optionalReprIsPayload(mod)) {
67166758 // The payload and the optional are the same value.
67176759 return operand;
67186760 }
......@@ -6723,18 +6765,19 @@ pub const FuncGen = struct {
67236765 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
67246766 comptime assert(optional_layout_version == 3);
67256767
6768 const mod = self.dg.module;
67266769 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67276770 const operand = try self.resolveInst(ty_op.operand);
67286771 const optional_ty = self.air.typeOf(ty_op.operand).childType();
67296772 var buf: Type.Payload.ElemType = undefined;
67306773 const payload_ty = optional_ty.optionalChild(&buf);
67316774 const non_null_bit = self.context.intType(8).constInt(1, .False);
6732 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6775 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
67336776 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
67346777 _ = self.builder.buildStore(non_null_bit, operand);
67356778 return operand;
67366779 }
6737 if (optional_ty.optionalReprIsPayload()) {
6780 if (optional_ty.optionalReprIsPayload(mod)) {
67386781 // The payload and the optional are the same value.
67396782 // Setting to non-null will be done when the payload is set.
67406783 return operand;
......@@ -6754,20 +6797,21 @@ pub const FuncGen = struct {
67546797 }
67556798
67566799 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
6800 const mod = self.dg.module;
67576801 const inst = body_tail[0];
67586802 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67596803 const operand = try self.resolveInst(ty_op.operand);
67606804 const optional_ty = self.air.typeOf(ty_op.operand);
67616805 const payload_ty = self.air.typeOfIndex(inst);
6762 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return null;
6806 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
67636807
6764 if (optional_ty.optionalReprIsPayload()) {
6808 if (optional_ty.optionalReprIsPayload(mod)) {
67656809 // Payload value is the same as the optional value.
67666810 return operand;
67676811 }
67686812
67696813 const opt_llvm_ty = try self.dg.lowerType(optional_ty);
6770 const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;
6814 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;
67716815 return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load);
67726816 }
67736817
......@@ -6776,6 +6820,7 @@ pub const FuncGen = struct {
67766820 body_tail: []const Air.Inst.Index,
67776821 operand_is_ptr: bool,
67786822 ) !?*llvm.Value {
6823 const mod = self.dg.module;
67796824 const inst = body_tail[0];
67806825 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67816826 const operand = try self.resolveInst(ty_op.operand);
......@@ -6783,25 +6828,24 @@ pub const FuncGen = struct {
67836828 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
67846829 const result_ty = self.air.typeOfIndex(inst);
67856830 const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;
6786 const target = self.dg.module.getTarget();
67876831
6788 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6832 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
67896833 return if (operand_is_ptr) operand else null;
67906834 }
6791 const offset = errUnionPayloadOffset(payload_ty, target);
6835 const offset = errUnionPayloadOffset(payload_ty, mod);
67926836 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
67936837 if (operand_is_ptr) {
67946838 return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
6795 } else if (isByRef(err_union_ty)) {
6839 } else if (isByRef(err_union_ty, mod)) {
67966840 const payload_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
6797 if (isByRef(payload_ty)) {
6841 if (isByRef(payload_ty, mod)) {
67986842 if (self.canElideLoad(body_tail))
67996843 return payload_ptr;
68006844
6801 return self.loadByRef(payload_ptr, payload_ty, payload_ty.abiAlignment(target), false);
6845 return self.loadByRef(payload_ptr, payload_ty, payload_ty.abiAlignment(mod), false);
68026846 }
68036847 const load_inst = self.builder.buildLoad(err_union_llvm_ty.structGetTypeAtIndex(offset), payload_ptr, "");
6804 load_inst.setAlignment(payload_ty.abiAlignment(target));
6848 load_inst.setAlignment(payload_ty.abiAlignment(mod));
68056849 return load_inst;
68066850 }
68076851 return self.builder.buildExtractValue(operand, offset, "");
......@@ -6812,6 +6856,7 @@ pub const FuncGen = struct {
68126856 inst: Air.Inst.Index,
68136857 operand_is_ptr: bool,
68146858 ) !?*llvm.Value {
6859 const mod = self.dg.module;
68156860 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
68166861 const operand = try self.resolveInst(ty_op.operand);
68176862 const operand_ty = self.air.typeOf(ty_op.operand);
......@@ -6828,15 +6873,14 @@ pub const FuncGen = struct {
68286873 const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror);
68296874
68306875 const payload_ty = err_union_ty.errorUnionPayload();
6831 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6876 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
68326877 if (!operand_is_ptr) return operand;
68336878 return self.builder.buildLoad(err_set_llvm_ty, operand, "");
68346879 }
68356880
6836 const target = self.dg.module.getTarget();
6837 const offset = errUnionErrorOffset(payload_ty, target);
6881 const offset = errUnionErrorOffset(payload_ty, mod);
68386882
6839 if (operand_is_ptr or isByRef(err_union_ty)) {
6883 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
68406884 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
68416885 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
68426886 return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, "");
......@@ -6846,30 +6890,30 @@ pub const FuncGen = struct {
68466890 }
68476891
68486892 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6893 const mod = self.dg.module;
68496894 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
68506895 const operand = try self.resolveInst(ty_op.operand);
68516896 const err_union_ty = self.air.typeOf(ty_op.operand).childType();
68526897
68536898 const payload_ty = err_union_ty.errorUnionPayload();
68546899 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });
6855 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6900 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
68566901 _ = self.builder.buildStore(non_error_val, operand);
68576902 return operand;
68586903 }
6859 const target = self.dg.module.getTarget();
68606904 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
68616905 {
6862 const error_offset = errUnionErrorOffset(payload_ty, target);
6906 const error_offset = errUnionErrorOffset(payload_ty, mod);
68636907 // First set the non-error value.
68646908 const non_null_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, error_offset, "");
68656909 const store_inst = self.builder.buildStore(non_error_val, non_null_ptr);
6866 store_inst.setAlignment(Type.anyerror.abiAlignment(target));
6910 store_inst.setAlignment(Type.anyerror.abiAlignment(mod));
68676911 }
68686912 // Then return the payload pointer (only if it is used).
68696913 if (self.liveness.isUnused(inst))
68706914 return null;
68716915
6872 const payload_offset = errUnionPayloadOffset(payload_ty, target);
6916 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
68736917 return self.builder.buildStructGEP(err_union_llvm_ty, operand, payload_offset, "");
68746918 }
68756919
......@@ -6885,15 +6929,14 @@ pub const FuncGen = struct {
68856929 }
68866930
68876931 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6888 const target = self.dg.module.getTarget();
6889
68906932 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
68916933 //const struct_ty = try self.resolveInst(ty_pl.ty);
68926934 const struct_ty = self.air.getRefType(ty_pl.ty);
68936935 const field_index = ty_pl.payload;
68946936
68956937 var ptr_ty_buf: Type.Payload.Pointer = undefined;
6896 const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf).?;
6938 const mod = self.dg.module;
6939 const llvm_field_index = llvmFieldIndex(struct_ty, field_index, mod, &ptr_ty_buf).?;
68976940 const struct_llvm_ty = try self.dg.lowerType(struct_ty);
68986941 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field_index, "");
68996942 const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);
......@@ -6901,20 +6944,20 @@ pub const FuncGen = struct {
69016944 }
69026945
69036946 fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6947 const mod = self.dg.module;
69046948 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
69056949 const payload_ty = self.air.typeOf(ty_op.operand);
69066950 const non_null_bit = self.context.intType(8).constInt(1, .False);
69076951 comptime assert(optional_layout_version == 3);
6908 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return non_null_bit;
6952 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;
69096953 const operand = try self.resolveInst(ty_op.operand);
69106954 const optional_ty = self.air.typeOfIndex(inst);
6911 if (optional_ty.optionalReprIsPayload()) {
6955 if (optional_ty.optionalReprIsPayload(mod)) {
69126956 return operand;
69136957 }
69146958 const llvm_optional_ty = try self.dg.lowerType(optional_ty);
6915 if (isByRef(optional_ty)) {
6916 const target = self.dg.module.getTarget();
6917 const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(target));
6959 if (isByRef(optional_ty, mod)) {
6960 const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod));
69186961 const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");
69196962 var ptr_ty_payload: Type.Payload.ElemType = .{
69206963 .base = .{ .tag = .single_mut_pointer },
......@@ -6931,24 +6974,24 @@ pub const FuncGen = struct {
69316974 }
69326975
69336976 fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
6977 const mod = self.dg.module;
69346978 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
69356979 const err_un_ty = self.air.typeOfIndex(inst);
69366980 const operand = try self.resolveInst(ty_op.operand);
69376981 const payload_ty = self.air.typeOf(ty_op.operand);
6938 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6982 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
69396983 return operand;
69406984 }
69416985 const ok_err_code = (try self.dg.lowerType(Type.anyerror)).constNull();
69426986 const err_un_llvm_ty = try self.dg.lowerType(err_un_ty);
69436987
6944 const target = self.dg.module.getTarget();
6945 const payload_offset = errUnionPayloadOffset(payload_ty, target);
6946 const error_offset = errUnionErrorOffset(payload_ty, target);
6947 if (isByRef(err_un_ty)) {
6948 const result_ptr = self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(target));
6988 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
6989 const error_offset = errUnionErrorOffset(payload_ty, mod);
6990 if (isByRef(err_un_ty, mod)) {
6991 const result_ptr = self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(mod));
69496992 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");
69506993 const store_inst = self.builder.buildStore(ok_err_code, err_ptr);
6951 store_inst.setAlignment(Type.anyerror.abiAlignment(target));
6994 store_inst.setAlignment(Type.anyerror.abiAlignment(mod));
69526995 const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, "");
69536996 var ptr_ty_payload: Type.Payload.ElemType = .{
69546997 .base = .{ .tag = .single_mut_pointer },
......@@ -6964,23 +7007,23 @@ pub const FuncGen = struct {
69647007 }
69657008
69667009 fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7010 const mod = self.dg.module;
69677011 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
69687012 const err_un_ty = self.air.typeOfIndex(inst);
69697013 const payload_ty = err_un_ty.errorUnionPayload();
69707014 const operand = try self.resolveInst(ty_op.operand);
6971 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
7015 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
69727016 return operand;
69737017 }
69747018 const err_un_llvm_ty = try self.dg.lowerType(err_un_ty);
69757019
6976 const target = self.dg.module.getTarget();
6977 const payload_offset = errUnionPayloadOffset(payload_ty, target);
6978 const error_offset = errUnionErrorOffset(payload_ty, target);
6979 if (isByRef(err_un_ty)) {
6980 const result_ptr = self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(target));
7020 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
7021 const error_offset = errUnionErrorOffset(payload_ty, mod);
7022 if (isByRef(err_un_ty, mod)) {
7023 const result_ptr = self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(mod));
69817024 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");
69827025 const store_inst = self.builder.buildStore(operand, err_ptr);
6983 store_inst.setAlignment(Type.anyerror.abiAlignment(target));
7026 store_inst.setAlignment(Type.anyerror.abiAlignment(mod));
69847027 const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, "");
69857028 var ptr_ty_payload: Type.Payload.ElemType = .{
69867029 .base = .{ .tag = .single_mut_pointer },
......@@ -7021,6 +7064,7 @@ pub const FuncGen = struct {
70217064 }
70227065
70237066 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7067 const mod = self.dg.module;
70247068 const data = self.air.instructions.items(.data)[inst].vector_store_elem;
70257069 const extra = self.air.extraData(Air.Bin, data.payload).data;
70267070
......@@ -7032,8 +7076,7 @@ pub const FuncGen = struct {
70327076 const loaded_vector = blk: {
70337077 const elem_llvm_ty = try self.dg.lowerType(vector_ptr_ty.childType());
70347078 const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, "");
7035 const target = self.dg.module.getTarget();
7036 load_inst.setAlignment(vector_ptr_ty.ptrAlignment(target));
7079 load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod));
70377080 load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr()));
70387081 break :blk load_inst;
70397082 };
......@@ -7043,24 +7086,26 @@ pub const FuncGen = struct {
70437086 }
70447087
70457088 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7089 const mod = self.dg.module;
70467090 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
70477091 const lhs = try self.resolveInst(bin_op.lhs);
70487092 const rhs = try self.resolveInst(bin_op.rhs);
7049 const scalar_ty = self.air.typeOfIndex(inst).scalarType();
7093 const scalar_ty = self.air.typeOfIndex(inst).scalarType(mod);
70507094
70517095 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, scalar_ty, 2, .{ lhs, rhs });
7052 if (scalar_ty.isSignedInt()) return self.builder.buildSMin(lhs, rhs, "");
7096 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSMin(lhs, rhs, "");
70537097 return self.builder.buildUMin(lhs, rhs, "");
70547098 }
70557099
70567100 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7101 const mod = self.dg.module;
70577102 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
70587103 const lhs = try self.resolveInst(bin_op.lhs);
70597104 const rhs = try self.resolveInst(bin_op.rhs);
7060 const scalar_ty = self.air.typeOfIndex(inst).scalarType();
7105 const scalar_ty = self.air.typeOfIndex(inst).scalarType(mod);
70617106
70627107 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, scalar_ty, 2, .{ lhs, rhs });
7063 if (scalar_ty.isSignedInt()) return self.builder.buildSMax(lhs, rhs, "");
7108 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSMax(lhs, rhs, "");
70647109 return self.builder.buildUMax(lhs, rhs, "");
70657110 }
70667111
......@@ -7081,14 +7126,15 @@ pub const FuncGen = struct {
70817126 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
70827127 self.builder.setFastMath(want_fast_math);
70837128
7129 const mod = self.dg.module;
70847130 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
70857131 const lhs = try self.resolveInst(bin_op.lhs);
70867132 const rhs = try self.resolveInst(bin_op.rhs);
70877133 const inst_ty = self.air.typeOfIndex(inst);
7088 const scalar_ty = inst_ty.scalarType();
7134 const scalar_ty = inst_ty.scalarType(mod);
70897135
70907136 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.add, inst_ty, 2, .{ lhs, rhs });
7091 if (scalar_ty.isSignedInt()) return self.builder.buildNSWAdd(lhs, rhs, "");
7137 if (scalar_ty.isSignedInt(mod)) return self.builder.buildNSWAdd(lhs, rhs, "");
70927138 return self.builder.buildNUWAdd(lhs, rhs, "");
70937139 }
70947140
......@@ -7103,14 +7149,15 @@ pub const FuncGen = struct {
71037149 }
71047150
71057151 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7152 const mod = self.dg.module;
71067153 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
71077154 const lhs = try self.resolveInst(bin_op.lhs);
71087155 const rhs = try self.resolveInst(bin_op.rhs);
71097156 const inst_ty = self.air.typeOfIndex(inst);
7110 const scalar_ty = inst_ty.scalarType();
7157 const scalar_ty = inst_ty.scalarType(mod);
71117158
71127159 if (scalar_ty.isAnyFloat()) return self.todo("saturating float add", .{});
7113 if (scalar_ty.isSignedInt()) return self.builder.buildSAddSat(lhs, rhs, "");
7160 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSAddSat(lhs, rhs, "");
71147161
71157162 return self.builder.buildUAddSat(lhs, rhs, "");
71167163 }
......@@ -7118,14 +7165,15 @@ pub const FuncGen = struct {
71187165 fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
71197166 self.builder.setFastMath(want_fast_math);
71207167
7168 const mod = self.dg.module;
71217169 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
71227170 const lhs = try self.resolveInst(bin_op.lhs);
71237171 const rhs = try self.resolveInst(bin_op.rhs);
71247172 const inst_ty = self.air.typeOfIndex(inst);
7125 const scalar_ty = inst_ty.scalarType();
7173 const scalar_ty = inst_ty.scalarType(mod);
71267174
71277175 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.sub, inst_ty, 2, .{ lhs, rhs });
7128 if (scalar_ty.isSignedInt()) return self.builder.buildNSWSub(lhs, rhs, "");
7176 if (scalar_ty.isSignedInt(mod)) return self.builder.buildNSWSub(lhs, rhs, "");
71297177 return self.builder.buildNUWSub(lhs, rhs, "");
71307178 }
71317179
......@@ -7140,28 +7188,30 @@ pub const FuncGen = struct {
71407188 }
71417189
71427190 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7191 const mod = self.dg.module;
71437192 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
71447193 const lhs = try self.resolveInst(bin_op.lhs);
71457194 const rhs = try self.resolveInst(bin_op.rhs);
71467195 const inst_ty = self.air.typeOfIndex(inst);
7147 const scalar_ty = inst_ty.scalarType();
7196 const scalar_ty = inst_ty.scalarType(mod);
71487197
71497198 if (scalar_ty.isAnyFloat()) return self.todo("saturating float sub", .{});
7150 if (scalar_ty.isSignedInt()) return self.builder.buildSSubSat(lhs, rhs, "");
7199 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSSubSat(lhs, rhs, "");
71517200 return self.builder.buildUSubSat(lhs, rhs, "");
71527201 }
71537202
71547203 fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
71557204 self.builder.setFastMath(want_fast_math);
71567205
7206 const mod = self.dg.module;
71577207 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
71587208 const lhs = try self.resolveInst(bin_op.lhs);
71597209 const rhs = try self.resolveInst(bin_op.rhs);
71607210 const inst_ty = self.air.typeOfIndex(inst);
7161 const scalar_ty = inst_ty.scalarType();
7211 const scalar_ty = inst_ty.scalarType(mod);
71627212
71637213 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.mul, inst_ty, 2, .{ lhs, rhs });
7164 if (scalar_ty.isSignedInt()) return self.builder.buildNSWMul(lhs, rhs, "");
7214 if (scalar_ty.isSignedInt(mod)) return self.builder.buildNSWMul(lhs, rhs, "");
71657215 return self.builder.buildNUWMul(lhs, rhs, "");
71667216 }
71677217
......@@ -7176,14 +7226,15 @@ pub const FuncGen = struct {
71767226 }
71777227
71787228 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7229 const mod = self.dg.module;
71797230 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
71807231 const lhs = try self.resolveInst(bin_op.lhs);
71817232 const rhs = try self.resolveInst(bin_op.rhs);
71827233 const inst_ty = self.air.typeOfIndex(inst);
7183 const scalar_ty = inst_ty.scalarType();
7234 const scalar_ty = inst_ty.scalarType(mod);
71847235
71857236 if (scalar_ty.isAnyFloat()) return self.todo("saturating float mul", .{});
7186 if (scalar_ty.isSignedInt()) return self.builder.buildSMulFixSat(lhs, rhs, "");
7237 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSMulFixSat(lhs, rhs, "");
71877238 return self.builder.buildUMulFixSat(lhs, rhs, "");
71887239 }
71897240
......@@ -7201,38 +7252,39 @@ pub const FuncGen = struct {
72017252 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
72027253 self.builder.setFastMath(want_fast_math);
72037254
7255 const mod = self.dg.module;
72047256 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
72057257 const lhs = try self.resolveInst(bin_op.lhs);
72067258 const rhs = try self.resolveInst(bin_op.rhs);
72077259 const inst_ty = self.air.typeOfIndex(inst);
7208 const scalar_ty = inst_ty.scalarType();
7260 const scalar_ty = inst_ty.scalarType(mod);
72097261
72107262 if (scalar_ty.isRuntimeFloat()) {
72117263 const result = try self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });
72127264 return self.buildFloatOp(.trunc, inst_ty, 1, .{result});
72137265 }
7214 if (scalar_ty.isSignedInt()) return self.builder.buildSDiv(lhs, rhs, "");
7266 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSDiv(lhs, rhs, "");
72157267 return self.builder.buildUDiv(lhs, rhs, "");
72167268 }
72177269
72187270 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
72197271 self.builder.setFastMath(want_fast_math);
72207272
7273 const mod = self.dg.module;
72217274 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
72227275 const lhs = try self.resolveInst(bin_op.lhs);
72237276 const rhs = try self.resolveInst(bin_op.rhs);
72247277 const inst_ty = self.air.typeOfIndex(inst);
7225 const scalar_ty = inst_ty.scalarType();
7278 const scalar_ty = inst_ty.scalarType(mod);
72267279
72277280 if (scalar_ty.isRuntimeFloat()) {
72287281 const result = try self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });
72297282 return self.buildFloatOp(.floor, inst_ty, 1, .{result});
72307283 }
7231 if (scalar_ty.isSignedInt()) {
7232 const target = self.dg.module.getTarget();
7284 if (scalar_ty.isSignedInt(mod)) {
72337285 const inst_llvm_ty = try self.dg.lowerType(inst_ty);
7234 const scalar_bit_size_minus_one = scalar_ty.bitSize(target) - 1;
7235 const bit_size_minus_one = if (inst_ty.zigTypeTag() == .Vector) const_vector: {
7286 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
7287 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
72367288 const vec_len = inst_ty.vectorLen();
72377289 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
72387290
......@@ -7258,40 +7310,43 @@ pub const FuncGen = struct {
72587310 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
72597311 self.builder.setFastMath(want_fast_math);
72607312
7313 const mod = self.dg.module;
72617314 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
72627315 const lhs = try self.resolveInst(bin_op.lhs);
72637316 const rhs = try self.resolveInst(bin_op.rhs);
72647317 const inst_ty = self.air.typeOfIndex(inst);
7265 const scalar_ty = inst_ty.scalarType();
7318 const scalar_ty = inst_ty.scalarType(mod);
72667319
72677320 if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });
7268 if (scalar_ty.isSignedInt()) return self.builder.buildExactSDiv(lhs, rhs, "");
7321 if (scalar_ty.isSignedInt(mod)) return self.builder.buildExactSDiv(lhs, rhs, "");
72697322 return self.builder.buildExactUDiv(lhs, rhs, "");
72707323 }
72717324
72727325 fn airRem(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
72737326 self.builder.setFastMath(want_fast_math);
72747327
7328 const mod = self.dg.module;
72757329 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
72767330 const lhs = try self.resolveInst(bin_op.lhs);
72777331 const rhs = try self.resolveInst(bin_op.rhs);
72787332 const inst_ty = self.air.typeOfIndex(inst);
7279 const scalar_ty = inst_ty.scalarType();
7333 const scalar_ty = inst_ty.scalarType(mod);
72807334
72817335 if (scalar_ty.isRuntimeFloat()) return self.buildFloatOp(.fmod, inst_ty, 2, .{ lhs, rhs });
7282 if (scalar_ty.isSignedInt()) return self.builder.buildSRem(lhs, rhs, "");
7336 if (scalar_ty.isSignedInt(mod)) return self.builder.buildSRem(lhs, rhs, "");
72837337 return self.builder.buildURem(lhs, rhs, "");
72847338 }
72857339
72867340 fn airMod(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
72877341 self.builder.setFastMath(want_fast_math);
72887342
7343 const mod = self.dg.module;
72897344 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
72907345 const lhs = try self.resolveInst(bin_op.lhs);
72917346 const rhs = try self.resolveInst(bin_op.rhs);
72927347 const inst_ty = self.air.typeOfIndex(inst);
72937348 const inst_llvm_ty = try self.dg.lowerType(inst_ty);
7294 const scalar_ty = inst_ty.scalarType();
7349 const scalar_ty = inst_ty.scalarType(mod);
72957350
72967351 if (scalar_ty.isRuntimeFloat()) {
72977352 const a = try self.buildFloatOp(.fmod, inst_ty, 2, .{ lhs, rhs });
......@@ -7301,10 +7356,9 @@ pub const FuncGen = struct {
73017356 const ltz = try self.buildFloatCmp(.lt, inst_ty, .{ lhs, zero });
73027357 return self.builder.buildSelect(ltz, c, a, "");
73037358 }
7304 if (scalar_ty.isSignedInt()) {
7305 const target = self.dg.module.getTarget();
7306 const scalar_bit_size_minus_one = scalar_ty.bitSize(target) - 1;
7307 const bit_size_minus_one = if (inst_ty.zigTypeTag() == .Vector) const_vector: {
7359 if (scalar_ty.isSignedInt(mod)) {
7360 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
7361 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
73087362 const vec_len = inst_ty.vectorLen();
73097363 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
73107364
......@@ -7386,6 +7440,7 @@ pub const FuncGen = struct {
73867440 signed_intrinsic: []const u8,
73877441 unsigned_intrinsic: []const u8,
73887442 ) !?*llvm.Value {
7443 const mod = self.dg.module;
73897444 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
73907445 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
73917446
......@@ -7393,16 +7448,14 @@ pub const FuncGen = struct {
73937448 const rhs = try self.resolveInst(extra.rhs);
73947449
73957450 const lhs_ty = self.air.typeOf(extra.lhs);
7396 const scalar_ty = lhs_ty.scalarType();
7451 const scalar_ty = lhs_ty.scalarType(mod);
73977452 const dest_ty = self.air.typeOfIndex(inst);
73987453
7399 const intrinsic_name = if (scalar_ty.isSignedInt()) signed_intrinsic else unsigned_intrinsic;
7454 const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
74007455
74017456 const llvm_lhs_ty = try self.dg.lowerType(lhs_ty);
74027457 const llvm_dest_ty = try self.dg.lowerType(dest_ty);
74037458
7404 const tg = self.dg.module.getTarget();
7405
74067459 const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});
74077460 const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, "");
74087461
......@@ -7410,12 +7463,11 @@ pub const FuncGen = struct {
74107463 const overflow_bit = self.builder.buildExtractValue(result_struct, 1, "");
74117464
74127465 var ty_buf: Type.Payload.Pointer = undefined;
7413 const result_index = llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?;
7414 const overflow_index = llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?;
7466 const result_index = llvmFieldIndex(dest_ty, 0, mod, &ty_buf).?;
7467 const overflow_index = llvmFieldIndex(dest_ty, 1, mod, &ty_buf).?;
74157468
7416 if (isByRef(dest_ty)) {
7417 const target = self.dg.module.getTarget();
7418 const result_alignment = dest_ty.abiAlignment(target);
7469 if (isByRef(dest_ty, mod)) {
7470 const result_alignment = dest_ty.abiAlignment(mod);
74197471 const alloca_inst = self.buildAlloca(llvm_dest_ty, result_alignment);
74207472 {
74217473 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");
......@@ -7486,8 +7538,9 @@ pub const FuncGen = struct {
74867538 ty: Type,
74877539 params: [2]*llvm.Value,
74887540 ) !*llvm.Value {
7541 const mod = self.dg.module;
74897542 const target = self.dg.module.getTarget();
7490 const scalar_ty = ty.scalarType();
7543 const scalar_ty = ty.scalarType(mod);
74917544 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
74927545
74937546 if (intrinsicsAllowed(scalar_ty, target)) {
......@@ -7531,7 +7584,7 @@ pub const FuncGen = struct {
75317584 .gte => .SGE,
75327585 };
75337586
7534 if (ty.zigTypeTag() == .Vector) {
7587 if (ty.zigTypeTag(mod) == .Vector) {
75357588 const vec_len = ty.vectorLen();
75367589 const vector_result_ty = llvm_i32.vectorType(vec_len);
75377590
......@@ -7587,8 +7640,9 @@ pub const FuncGen = struct {
75877640 comptime params_len: usize,
75887641 params: [params_len]*llvm.Value,
75897642 ) !*llvm.Value {
7590 const target = self.dg.module.getTarget();
7591 const scalar_ty = ty.scalarType();
7643 const mod = self.dg.module;
7644 const target = mod.getTarget();
7645 const scalar_ty = ty.scalarType(mod);
75927646 const llvm_ty = try self.dg.lowerType(ty);
75937647 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
75947648
......@@ -7615,7 +7669,7 @@ pub const FuncGen = struct {
76157669 const one = int_llvm_ty.constInt(1, .False);
76167670 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);
76177671 const sign_mask = one.constShl(shift_amt);
7618 const result = if (ty.zigTypeTag() == .Vector) blk: {
7672 const result = if (ty.zigTypeTag(mod) == .Vector) blk: {
76197673 const splat_sign_mask = self.builder.buildVectorSplat(ty.vectorLen(), sign_mask, "");
76207674 const cast_ty = int_llvm_ty.vectorType(ty.vectorLen());
76217675 const bitcasted_operand = self.builder.buildBitCast(params[0], cast_ty, "");
......@@ -7662,7 +7716,7 @@ pub const FuncGen = struct {
76627716 .libc => |fn_name| b: {
76637717 const param_types = [3]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty, scalar_llvm_ty };
76647718 const libc_fn = self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty);
7665 if (ty.zigTypeTag() == .Vector) {
7719 if (ty.zigTypeTag(mod) == .Vector) {
76667720 const result = llvm_ty.getUndef();
76677721 return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen());
76687722 }
......@@ -7686,6 +7740,7 @@ pub const FuncGen = struct {
76867740 }
76877741
76887742 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7743 const mod = self.dg.module;
76897744 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
76907745 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
76917746
......@@ -7694,21 +7749,19 @@ pub const FuncGen = struct {
76947749
76957750 const lhs_ty = self.air.typeOf(extra.lhs);
76967751 const rhs_ty = self.air.typeOf(extra.rhs);
7697 const lhs_scalar_ty = lhs_ty.scalarType();
7698 const rhs_scalar_ty = rhs_ty.scalarType();
7752 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7753 const rhs_scalar_ty = rhs_ty.scalarType(mod);
76997754
77007755 const dest_ty = self.air.typeOfIndex(inst);
77017756 const llvm_dest_ty = try self.dg.lowerType(dest_ty);
77027757
7703 const tg = self.dg.module.getTarget();
7704
7705 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_scalar_ty.bitSize(tg))
7758 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
77067759 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")
77077760 else
77087761 rhs;
77097762
77107763 const result = self.builder.buildShl(lhs, casted_rhs, "");
7711 const reconstructed = if (lhs_scalar_ty.isSignedInt())
7764 const reconstructed = if (lhs_scalar_ty.isSignedInt(mod))
77127765 self.builder.buildAShr(result, casted_rhs, "")
77137766 else
77147767 self.builder.buildLShr(result, casted_rhs, "");
......@@ -7716,12 +7769,11 @@ pub const FuncGen = struct {
77167769 const overflow_bit = self.builder.buildICmp(.NE, lhs, reconstructed, "");
77177770
77187771 var ty_buf: Type.Payload.Pointer = undefined;
7719 const result_index = llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?;
7720 const overflow_index = llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?;
7772 const result_index = llvmFieldIndex(dest_ty, 0, mod, &ty_buf).?;
7773 const overflow_index = llvmFieldIndex(dest_ty, 1, mod, &ty_buf).?;
77217774
7722 if (isByRef(dest_ty)) {
7723 const target = self.dg.module.getTarget();
7724 const result_alignment = dest_ty.abiAlignment(target);
7775 if (isByRef(dest_ty, mod)) {
7776 const result_alignment = dest_ty.abiAlignment(mod);
77257777 const alloca_inst = self.buildAlloca(llvm_dest_ty, result_alignment);
77267778 {
77277779 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");
......@@ -7763,6 +7815,7 @@ pub const FuncGen = struct {
77637815 }
77647816
77657817 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7818 const mod = self.dg.module;
77667819 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
77677820
77687821 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7770,20 +7823,19 @@ pub const FuncGen = struct {
77707823
77717824 const lhs_ty = self.air.typeOf(bin_op.lhs);
77727825 const rhs_ty = self.air.typeOf(bin_op.rhs);
7773 const lhs_scalar_ty = lhs_ty.scalarType();
7774 const rhs_scalar_ty = rhs_ty.scalarType();
7826 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7827 const rhs_scalar_ty = rhs_ty.scalarType(mod);
77757828
7776 const tg = self.dg.module.getTarget();
7777
7778 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_scalar_ty.bitSize(tg))
7829 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
77797830 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")
77807831 else
77817832 rhs;
7782 if (lhs_scalar_ty.isSignedInt()) return self.builder.buildNSWShl(lhs, casted_rhs, "");
7833 if (lhs_scalar_ty.isSignedInt(mod)) return self.builder.buildNSWShl(lhs, casted_rhs, "");
77837834 return self.builder.buildNUWShl(lhs, casted_rhs, "");
77847835 }
77857836
77867837 fn airShl(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7838 const mod = self.dg.module;
77877839 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
77887840
77897841 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7791,12 +7843,10 @@ pub const FuncGen = struct {
77917843
77927844 const lhs_type = self.air.typeOf(bin_op.lhs);
77937845 const rhs_type = self.air.typeOf(bin_op.rhs);
7794 const lhs_scalar_ty = lhs_type.scalarType();
7795 const rhs_scalar_ty = rhs_type.scalarType();
7796
7797 const tg = self.dg.module.getTarget();
7846 const lhs_scalar_ty = lhs_type.scalarType(mod);
7847 const rhs_scalar_ty = rhs_type.scalarType(mod);
77987848
7799 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_scalar_ty.bitSize(tg))
7849 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
78007850 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_type), "")
78017851 else
78027852 rhs;
......@@ -7804,6 +7854,7 @@ pub const FuncGen = struct {
78047854 }
78057855
78067856 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7857 const mod = self.dg.module;
78077858 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
78087859
78097860 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7811,17 +7862,16 @@ pub const FuncGen = struct {
78117862
78127863 const lhs_ty = self.air.typeOf(bin_op.lhs);
78137864 const rhs_ty = self.air.typeOf(bin_op.rhs);
7814 const lhs_scalar_ty = lhs_ty.scalarType();
7815 const rhs_scalar_ty = rhs_ty.scalarType();
7816 const tg = self.dg.module.getTarget();
7817 const lhs_bits = lhs_scalar_ty.bitSize(tg);
7865 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7866 const rhs_scalar_ty = rhs_ty.scalarType(mod);
7867 const lhs_bits = lhs_scalar_ty.bitSize(mod);
78187868
7819 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_bits)
7869 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_bits)
78207870 self.builder.buildZExt(rhs, lhs.typeOf(), "")
78217871 else
78227872 rhs;
78237873
7824 const result = if (lhs_scalar_ty.isSignedInt())
7874 const result = if (lhs_scalar_ty.isSignedInt(mod))
78257875 self.builder.buildSShlSat(lhs, casted_rhs, "")
78267876 else
78277877 self.builder.buildUShlSat(lhs, casted_rhs, "");
......@@ -7834,7 +7884,7 @@ pub const FuncGen = struct {
78347884 const lhs_scalar_llvm_ty = try self.dg.lowerType(lhs_scalar_ty);
78357885 const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False);
78367886 const lhs_max = lhs_scalar_llvm_ty.constAllOnes();
7837 if (rhs_ty.zigTypeTag() == .Vector) {
7887 if (rhs_ty.zigTypeTag(mod) == .Vector) {
78387888 const vec_len = rhs_ty.vectorLen();
78397889 const bits_vec = self.builder.buildVectorSplat(vec_len, bits, "");
78407890 const lhs_max_vec = self.builder.buildVectorSplat(vec_len, lhs_max, "");
......@@ -7847,6 +7897,7 @@ pub const FuncGen = struct {
78477897 }
78487898
78497899 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !?*llvm.Value {
7900 const mod = self.dg.module;
78507901 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
78517902
78527903 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7854,16 +7905,14 @@ pub const FuncGen = struct {
78547905
78557906 const lhs_ty = self.air.typeOf(bin_op.lhs);
78567907 const rhs_ty = self.air.typeOf(bin_op.rhs);
7857 const lhs_scalar_ty = lhs_ty.scalarType();
7858 const rhs_scalar_ty = rhs_ty.scalarType();
7859
7860 const tg = self.dg.module.getTarget();
7908 const lhs_scalar_ty = lhs_ty.scalarType(mod);
7909 const rhs_scalar_ty = rhs_ty.scalarType(mod);
78617910
7862 const casted_rhs = if (rhs_scalar_ty.bitSize(tg) < lhs_scalar_ty.bitSize(tg))
7911 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
78637912 self.builder.buildZExt(rhs, try self.dg.lowerType(lhs_ty), "")
78647913 else
78657914 rhs;
7866 const is_signed_int = lhs_scalar_ty.isSignedInt();
7915 const is_signed_int = lhs_scalar_ty.isSignedInt(mod);
78677916
78687917 if (is_exact) {
78697918 if (is_signed_int) {
......@@ -7881,14 +7930,14 @@ pub const FuncGen = struct {
78817930 }
78827931
78837932 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7884 const target = self.dg.module.getTarget();
7933 const mod = self.dg.module;
78857934 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
78867935 const dest_ty = self.air.typeOfIndex(inst);
7887 const dest_info = dest_ty.intInfo(target);
7936 const dest_info = dest_ty.intInfo(mod);
78887937 const dest_llvm_ty = try self.dg.lowerType(dest_ty);
78897938 const operand = try self.resolveInst(ty_op.operand);
78907939 const operand_ty = self.air.typeOf(ty_op.operand);
7891 const operand_info = operand_ty.intInfo(target);
7940 const operand_info = operand_ty.intInfo(mod);
78927941
78937942 if (operand_info.bits < dest_info.bits) {
78947943 switch (operand_info.signedness) {
......@@ -7910,11 +7959,12 @@ pub const FuncGen = struct {
79107959 }
79117960
79127961 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7962 const mod = self.dg.module;
79137963 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
79147964 const operand = try self.resolveInst(ty_op.operand);
79157965 const operand_ty = self.air.typeOf(ty_op.operand);
79167966 const dest_ty = self.air.typeOfIndex(inst);
7917 const target = self.dg.module.getTarget();
7967 const target = mod.getTarget();
79187968 const dest_bits = dest_ty.floatBits(target);
79197969 const src_bits = operand_ty.floatBits(target);
79207970
......@@ -7939,11 +7989,12 @@ pub const FuncGen = struct {
79397989 }
79407990
79417991 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7992 const mod = self.dg.module;
79427993 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
79437994 const operand = try self.resolveInst(ty_op.operand);
79447995 const operand_ty = self.air.typeOf(ty_op.operand);
79457996 const dest_ty = self.air.typeOfIndex(inst);
7946 const target = self.dg.module.getTarget();
7997 const target = mod.getTarget();
79477998 const dest_bits = dest_ty.floatBits(target);
79487999 const src_bits = operand_ty.floatBits(target);
79498000
......@@ -7985,10 +8036,10 @@ pub const FuncGen = struct {
79858036 }
79868037
79878038 fn bitCast(self: *FuncGen, operand: *llvm.Value, operand_ty: Type, inst_ty: Type) !*llvm.Value {
7988 const operand_is_ref = isByRef(operand_ty);
7989 const result_is_ref = isByRef(inst_ty);
8039 const mod = self.dg.module;
8040 const operand_is_ref = isByRef(operand_ty, mod);
8041 const result_is_ref = isByRef(inst_ty, mod);
79908042 const llvm_dest_ty = try self.dg.lowerType(inst_ty);
7991 const target = self.dg.module.getTarget();
79928043
79938044 if (operand_is_ref and result_is_ref) {
79948045 // They are both pointers, so just return the same opaque pointer :)
......@@ -8001,20 +8052,20 @@ pub const FuncGen = struct {
80018052 return self.builder.buildZExtOrBitCast(operand, llvm_dest_ty, "");
80028053 }
80038054
8004 if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) {
8055 if (operand_ty.zigTypeTag(mod) == .Int and inst_ty.isPtrAtRuntime(mod)) {
80058056 return self.builder.buildIntToPtr(operand, llvm_dest_ty, "");
80068057 }
80078058
8008 if (operand_ty.zigTypeTag() == .Vector and inst_ty.zigTypeTag() == .Array) {
8059 if (operand_ty.zigTypeTag(mod) == .Vector and inst_ty.zigTypeTag(mod) == .Array) {
80098060 const elem_ty = operand_ty.childType();
80108061 if (!result_is_ref) {
80118062 return self.dg.todo("implement bitcast vector to non-ref array", .{});
80128063 }
80138064 const array_ptr = self.buildAlloca(llvm_dest_ty, null);
8014 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;
8065 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;
80158066 if (bitcast_ok) {
80168067 const llvm_store = self.builder.buildStore(operand, array_ptr);
8017 llvm_store.setAlignment(inst_ty.abiAlignment(target));
8068 llvm_store.setAlignment(inst_ty.abiAlignment(mod));
80188069 } else {
80198070 // If the ABI size of the element type is not evenly divisible by size in bits;
80208071 // a simple bitcast will not work, and we fall back to extractelement.
......@@ -8033,19 +8084,19 @@ pub const FuncGen = struct {
80338084 }
80348085 }
80358086 return array_ptr;
8036 } else if (operand_ty.zigTypeTag() == .Array and inst_ty.zigTypeTag() == .Vector) {
8087 } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) {
80378088 const elem_ty = operand_ty.childType();
80388089 const llvm_vector_ty = try self.dg.lowerType(inst_ty);
80398090 if (!operand_is_ref) {
80408091 return self.dg.todo("implement bitcast non-ref array to vector", .{});
80418092 }
80428093
8043 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;
8094 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;
80448095 if (bitcast_ok) {
80458096 const vector = self.builder.buildLoad(llvm_vector_ty, operand, "");
80468097 // The array is aligned to the element's alignment, while the vector might have a completely
80478098 // different alignment. This means we need to enforce the alignment of this load.
8048 vector.setAlignment(elem_ty.abiAlignment(target));
8099 vector.setAlignment(elem_ty.abiAlignment(mod));
80498100 return vector;
80508101 } else {
80518102 // If the ABI size of the element type is not evenly divisible by size in bits;
......@@ -8073,12 +8124,12 @@ pub const FuncGen = struct {
80738124
80748125 if (operand_is_ref) {
80758126 const load_inst = self.builder.buildLoad(llvm_dest_ty, operand, "");
8076 load_inst.setAlignment(operand_ty.abiAlignment(target));
8127 load_inst.setAlignment(operand_ty.abiAlignment(mod));
80778128 return load_inst;
80788129 }
80798130
80808131 if (result_is_ref) {
8081 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));
8132 const alignment = @max(operand_ty.abiAlignment(mod), inst_ty.abiAlignment(mod));
80828133 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);
80838134 const store_inst = self.builder.buildStore(operand, result_ptr);
80848135 store_inst.setAlignment(alignment);
......@@ -8089,7 +8140,7 @@ pub const FuncGen = struct {
80898140 // Both our operand and our result are values, not pointers,
80908141 // but LLVM won't let us bitcast struct values.
80918142 // Therefore, we store operand to alloca, then load for result.
8092 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));
8143 const alignment = @max(operand_ty.abiAlignment(mod), inst_ty.abiAlignment(mod));
80938144 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);
80948145 const store_inst = self.builder.buildStore(operand, result_ptr);
80958146 store_inst.setAlignment(alignment);
......@@ -8118,12 +8169,13 @@ pub const FuncGen = struct {
81188169 }
81198170
81208171 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
8172 const mod = self.dg.module;
81218173 const func = self.dg.decl.getFunction().?;
8122 const lbrace_line = self.dg.module.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
8174 const lbrace_line = mod.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
81238175 const lbrace_col = func.lbrace_column + 1;
81248176 const di_local_var = dib.createParameterVariable(
81258177 self.di_scope.?,
8126 func.getParamName(self.dg.module, src_index).ptr, // TODO test 0 bit args
8178 func.getParamName(mod, src_index).ptr, // TODO test 0 bit args
81278179 self.di_file.?,
81288180 lbrace_line,
81298181 try self.dg.object.lowerDebugType(inst_ty, .full),
......@@ -8134,10 +8186,10 @@ pub const FuncGen = struct {
81348186
81358187 const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null);
81368188 const insert_block = self.builder.getInsertBlock();
8137 if (isByRef(inst_ty)) {
8189 if (isByRef(inst_ty, mod)) {
81388190 _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block);
81398191 } else if (self.dg.module.comp.bin_file.options.optimize_mode == .Debug) {
8140 const alignment = inst_ty.abiAlignment(self.dg.module.getTarget());
8192 const alignment = inst_ty.abiAlignment(mod);
81418193 const alloca = self.buildAlloca(arg_val.typeOf(), alignment);
81428194 const store_inst = self.builder.buildStore(arg_val, alloca);
81438195 store_inst.setAlignment(alignment);
......@@ -8153,22 +8205,22 @@ pub const FuncGen = struct {
81538205 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
81548206 const ptr_ty = self.air.typeOfIndex(inst);
81558207 const pointee_type = ptr_ty.childType();
8156 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime()) return self.dg.lowerPtrToVoid(ptr_ty);
8208 const mod = self.dg.module;
8209 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
81578210
81588211 const pointee_llvm_ty = try self.dg.lowerType(pointee_type);
8159 const target = self.dg.module.getTarget();
8160 const alignment = ptr_ty.ptrAlignment(target);
8212 const alignment = ptr_ty.ptrAlignment(mod);
81618213 return self.buildAlloca(pointee_llvm_ty, alignment);
81628214 }
81638215
81648216 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
81658217 const ptr_ty = self.air.typeOfIndex(inst);
81668218 const ret_ty = ptr_ty.childType();
8167 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return self.dg.lowerPtrToVoid(ptr_ty);
8219 const mod = self.dg.module;
8220 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty);
81688221 if (self.ret_ptr) |ret_ptr| return ret_ptr;
81698222 const ret_llvm_ty = try self.dg.lowerType(ret_ty);
8170 const target = self.dg.module.getTarget();
8171 return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(target));
8223 return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod));
81728224 }
81738225
81748226 /// Use this instead of builder.buildAlloca, because this function makes sure to
......@@ -8182,8 +8234,9 @@ pub const FuncGen = struct {
81828234 const dest_ptr = try self.resolveInst(bin_op.lhs);
81838235 const ptr_ty = self.air.typeOf(bin_op.lhs);
81848236 const operand_ty = ptr_ty.childType();
8237 const mod = self.dg.module;
81858238
8186 const val_is_undef = if (self.air.value(bin_op.rhs)) |val| val.isUndefDeep() else false;
8239 const val_is_undef = if (self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;
81878240 if (val_is_undef) {
81888241 // Even if safety is disabled, we still emit a memset to undefined since it conveys
81898242 // extra information to LLVM. However, safety makes the difference between using
......@@ -8193,13 +8246,12 @@ pub const FuncGen = struct {
81938246 u8_llvm_ty.constInt(0xaa, .False)
81948247 else
81958248 u8_llvm_ty.getUndef();
8196 const target = self.dg.module.getTarget();
8197 const operand_size = operand_ty.abiSize(target);
8249 const operand_size = operand_ty.abiSize(mod);
81988250 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
81998251 const len = usize_llvm_ty.constInt(operand_size, .False);
8200 const dest_ptr_align = ptr_ty.ptrAlignment(target);
8252 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
82018253 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr());
8202 if (safety and self.dg.module.comp.bin_file.options.valgrind) {
8254 if (safety and mod.comp.bin_file.options.valgrind) {
82038255 self.valgrindMarkUndef(dest_ptr, len);
82048256 }
82058257 return null;
......@@ -8230,6 +8282,7 @@ pub const FuncGen = struct {
82308282 }
82318283
82328284 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !?*llvm.Value {
8285 const mod = fg.dg.module;
82338286 const inst = body_tail[0];
82348287 const ty_op = fg.air.instructions.items(.data)[inst].ty_op;
82358288 const ptr_ty = fg.air.typeOf(ty_op.operand);
......@@ -8237,7 +8290,7 @@ pub const FuncGen = struct {
82378290 const ptr = try fg.resolveInst(ty_op.operand);
82388291
82398292 elide: {
8240 if (!isByRef(ptr_info.pointee_type)) break :elide;
8293 if (!isByRef(ptr_info.pointee_type, mod)) break :elide;
82418294 if (!canElideLoad(fg, body_tail)) break :elide;
82428295 return ptr;
82438296 }
......@@ -8261,8 +8314,9 @@ pub const FuncGen = struct {
82618314
82628315 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
82638316 _ = inst;
8317 const mod = self.dg.module;
82648318 const llvm_usize = try self.dg.lowerType(Type.usize);
8265 const target = self.dg.module.getTarget();
8319 const target = mod.getTarget();
82668320 if (!target_util.supportsReturnAddress(target)) {
82678321 // https://github.com/ziglang/zig/issues/11946
82688322 return llvm_usize.constNull();
......@@ -8301,6 +8355,7 @@ pub const FuncGen = struct {
83018355 }
83028356
83038357 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value {
8358 const mod = self.dg.module;
83048359 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
83058360 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
83068361 const ptr = try self.resolveInst(extra.ptr);
......@@ -8310,7 +8365,7 @@ pub const FuncGen = struct {
83108365 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
83118366 if (opt_abi_ty) |abi_ty| {
83128367 // operand needs widening and truncating
8313 if (operand_ty.isSignedInt()) {
8368 if (operand_ty.isSignedInt(mod)) {
83148369 expected_value = self.builder.buildSExt(expected_value, abi_ty, "");
83158370 new_value = self.builder.buildSExt(new_value, abi_ty, "");
83168371 } else {
......@@ -8336,7 +8391,7 @@ pub const FuncGen = struct {
83368391 }
83378392 const success_bit = self.builder.buildExtractValue(result, 1, "");
83388393
8339 if (optional_ty.optionalReprIsPayload()) {
8394 if (optional_ty.optionalReprIsPayload(mod)) {
83408395 return self.builder.buildSelect(success_bit, payload.typeOf().constNull(), payload, "");
83418396 }
83428397
......@@ -8347,13 +8402,14 @@ pub const FuncGen = struct {
83478402 }
83488403
83498404 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8405 const mod = self.dg.module;
83508406 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
83518407 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
83528408 const ptr = try self.resolveInst(pl_op.operand);
83538409 const ptr_ty = self.air.typeOf(pl_op.operand);
83548410 const operand_ty = ptr_ty.elemType();
83558411 const operand = try self.resolveInst(extra.operand);
8356 const is_signed_int = operand_ty.isSignedInt();
8412 const is_signed_int = operand_ty.isSignedInt(mod);
83578413 const is_float = operand_ty.isRuntimeFloat();
83588414 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);
83598415 const ordering = toLlvmAtomicOrdering(extra.ordering());
......@@ -8402,17 +8458,17 @@ pub const FuncGen = struct {
84028458 }
84038459
84048460 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8461 const mod = self.dg.module;
84058462 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;
84068463 const ptr = try self.resolveInst(atomic_load.ptr);
84078464 const ptr_ty = self.air.typeOf(atomic_load.ptr);
84088465 const ptr_info = ptr_ty.ptrInfo().data;
84098466 const elem_ty = ptr_info.pointee_type;
8410 if (!elem_ty.hasRuntimeBitsIgnoreComptime())
8467 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod))
84118468 return null;
84128469 const ordering = toLlvmAtomicOrdering(atomic_load.order);
84138470 const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);
8414 const target = self.dg.module.getTarget();
8415 const ptr_alignment = ptr_info.alignment(target);
8471 const ptr_alignment = ptr_info.alignment(mod);
84168472 const ptr_volatile = llvm.Bool.fromBool(ptr_info.@"volatile");
84178473 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
84188474
......@@ -8436,17 +8492,18 @@ pub const FuncGen = struct {
84368492 inst: Air.Inst.Index,
84378493 ordering: llvm.AtomicOrdering,
84388494 ) !?*llvm.Value {
8495 const mod = self.dg.module;
84398496 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
84408497 const ptr_ty = self.air.typeOf(bin_op.lhs);
84418498 const operand_ty = ptr_ty.childType();
8442 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null;
8499 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null;
84438500 const ptr = try self.resolveInst(bin_op.lhs);
84448501 var element = try self.resolveInst(bin_op.rhs);
84458502 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
84468503
84478504 if (opt_abi_ty) |abi_ty| {
84488505 // operand needs widening
8449 if (operand_ty.isSignedInt()) {
8506 if (operand_ty.isSignedInt(mod)) {
84508507 element = self.builder.buildSExt(element, abi_ty, "");
84518508 } else {
84528509 element = self.builder.buildZExt(element, abi_ty, "");
......@@ -8457,18 +8514,19 @@ pub const FuncGen = struct {
84578514 }
84588515
84598516 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {
8517 const mod = self.dg.module;
84608518 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
84618519 const dest_slice = try self.resolveInst(bin_op.lhs);
84628520 const ptr_ty = self.air.typeOf(bin_op.lhs);
84638521 const elem_ty = self.air.typeOf(bin_op.rhs);
84648522 const module = self.dg.module;
84658523 const target = module.getTarget();
8466 const dest_ptr_align = ptr_ty.ptrAlignment(target);
8524 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
84678525 const u8_llvm_ty = self.context.intType(8);
84688526 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);
84698527 const is_volatile = ptr_ty.isVolatilePtr();
84708528
8471 if (self.air.value(bin_op.rhs)) |elem_val| {
8529 if (self.air.value(bin_op.rhs, mod)) |elem_val| {
84728530 if (elem_val.isUndefDeep()) {
84738531 // Even if safety is disabled, we still emit a memset to undefined since it conveys
84748532 // extra information to LLVM. However, safety makes the difference between using
......@@ -8503,7 +8561,7 @@ pub const FuncGen = struct {
85038561 }
85048562
85058563 const value = try self.resolveInst(bin_op.rhs);
8506 const elem_abi_size = elem_ty.abiSize(target);
8564 const elem_abi_size = elem_ty.abiSize(mod);
85078565
85088566 if (elem_abi_size == 1) {
85098567 // In this case we can take advantage of LLVM's intrinsic.
......@@ -8551,9 +8609,9 @@ pub const FuncGen = struct {
85518609 _ = self.builder.buildCondBr(end, body_block, end_block);
85528610
85538611 self.builder.positionBuilderAtEnd(body_block);
8554 const elem_abi_alignment = elem_ty.abiAlignment(target);
8612 const elem_abi_alignment = elem_ty.abiAlignment(mod);
85558613 const it_ptr_alignment = @min(elem_abi_alignment, dest_ptr_align);
8556 if (isByRef(elem_ty)) {
8614 if (isByRef(elem_ty, mod)) {
85578615 _ = self.builder.buildMemCpy(
85588616 it_ptr,
85598617 it_ptr_alignment,
......@@ -8589,13 +8647,13 @@ pub const FuncGen = struct {
85898647 const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);
85908648 const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);
85918649 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
8650 const mod = self.dg.module;
85928651 const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr();
8593 const target = self.dg.module.getTarget();
85948652 _ = self.builder.buildMemCpy(
85958653 dest_ptr,
8596 dest_ptr_ty.ptrAlignment(target),
8654 dest_ptr_ty.ptrAlignment(mod),
85978655 src_ptr,
8598 src_ptr_ty.ptrAlignment(target),
8656 src_ptr_ty.ptrAlignment(mod),
85998657 len,
86008658 is_volatile,
86018659 );
......@@ -8603,10 +8661,10 @@ pub const FuncGen = struct {
86038661 }
86048662
86058663 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8664 const mod = self.dg.module;
86068665 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
86078666 const un_ty = self.air.typeOf(bin_op.lhs).childType();
8608 const target = self.dg.module.getTarget();
8609 const layout = un_ty.unionGetLayout(target);
8667 const layout = un_ty.unionGetLayout(mod);
86108668 if (layout.tag_size == 0) return null;
86118669 const union_ptr = try self.resolveInst(bin_op.lhs);
86128670 const new_tag = try self.resolveInst(bin_op.rhs);
......@@ -8624,13 +8682,13 @@ pub const FuncGen = struct {
86248682 }
86258683
86268684 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8685 const mod = self.dg.module;
86278686 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
86288687 const un_ty = self.air.typeOf(ty_op.operand);
8629 const target = self.dg.module.getTarget();
8630 const layout = un_ty.unionGetLayout(target);
8688 const layout = un_ty.unionGetLayout(mod);
86318689 if (layout.tag_size == 0) return null;
86328690 const union_handle = try self.resolveInst(ty_op.operand);
8633 if (isByRef(un_ty)) {
8691 if (isByRef(un_ty, mod)) {
86348692 const llvm_un_ty = try self.dg.lowerType(un_ty);
86358693 if (layout.payload_size == 0) {
86368694 return self.builder.buildLoad(llvm_un_ty, union_handle, "");
......@@ -8666,6 +8724,7 @@ pub const FuncGen = struct {
86668724 }
86678725
86688726 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8727 const mod = self.dg.module;
86698728 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
86708729 const operand_ty = self.air.typeOf(ty_op.operand);
86718730 const operand = try self.resolveInst(ty_op.operand);
......@@ -8679,9 +8738,8 @@ pub const FuncGen = struct {
86798738 const result_ty = self.air.typeOfIndex(inst);
86808739 const result_llvm_ty = try self.dg.lowerType(result_ty);
86818740
8682 const target = self.dg.module.getTarget();
8683 const bits = operand_ty.intInfo(target).bits;
8684 const result_bits = result_ty.intInfo(target).bits;
8741 const bits = operand_ty.intInfo(mod).bits;
8742 const result_bits = result_ty.intInfo(mod).bits;
86858743 if (bits > result_bits) {
86868744 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");
86878745 } else if (bits < result_bits) {
......@@ -8692,6 +8750,7 @@ pub const FuncGen = struct {
86928750 }
86938751
86948752 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8753 const mod = self.dg.module;
86958754 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
86968755 const operand_ty = self.air.typeOf(ty_op.operand);
86978756 const operand = try self.resolveInst(ty_op.operand);
......@@ -8704,9 +8763,8 @@ pub const FuncGen = struct {
87048763 const result_ty = self.air.typeOfIndex(inst);
87058764 const result_llvm_ty = try self.dg.lowerType(result_ty);
87068765
8707 const target = self.dg.module.getTarget();
8708 const bits = operand_ty.intInfo(target).bits;
8709 const result_bits = result_ty.intInfo(target).bits;
8766 const bits = operand_ty.intInfo(mod).bits;
8767 const result_bits = result_ty.intInfo(mod).bits;
87108768 if (bits > result_bits) {
87118769 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");
87128770 } else if (bits < result_bits) {
......@@ -8717,10 +8775,10 @@ pub const FuncGen = struct {
87178775 }
87188776
87198777 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value {
8720 const target = self.dg.module.getTarget();
8778 const mod = self.dg.module;
87218779 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
87228780 const operand_ty = self.air.typeOf(ty_op.operand);
8723 var bits = operand_ty.intInfo(target).bits;
8781 var bits = operand_ty.intInfo(mod).bits;
87248782 assert(bits % 8 == 0);
87258783
87268784 var operand = try self.resolveInst(ty_op.operand);
......@@ -8730,7 +8788,7 @@ pub const FuncGen = struct {
87308788 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte
87318789 // The truncated result at the end will be the correct bswap
87328790 const scalar_llvm_ty = self.context.intType(bits + 8);
8733 if (operand_ty.zigTypeTag() == .Vector) {
8791 if (operand_ty.zigTypeTag(mod) == .Vector) {
87348792 const vec_len = operand_ty.vectorLen();
87358793 operand_llvm_ty = scalar_llvm_ty.vectorType(vec_len);
87368794
......@@ -8759,7 +8817,7 @@ pub const FuncGen = struct {
87598817
87608818 const result_ty = self.air.typeOfIndex(inst);
87618819 const result_llvm_ty = try self.dg.lowerType(result_ty);
8762 const result_bits = result_ty.intInfo(target).bits;
8820 const result_bits = result_ty.intInfo(mod).bits;
87638821 if (bits > result_bits) {
87648822 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");
87658823 } else if (bits < result_bits) {
......@@ -8770,6 +8828,7 @@ pub const FuncGen = struct {
87708828 }
87718829
87728830 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8831 const mod = self.dg.module;
87738832 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
87748833 const operand = try self.resolveInst(ty_op.operand);
87758834 const error_set_ty = self.air.getRefType(ty_op.ty);
......@@ -8781,7 +8840,7 @@ pub const FuncGen = struct {
87818840 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
87828841
87838842 for (names) |name| {
8784 const err_int = self.dg.module.global_error_set.get(name).?;
8843 const err_int = mod.global_error_set.get(name).?;
87858844 const this_tag_int_value = int: {
87868845 var tag_val_payload: Value.Payload.U64 = .{
87878846 .base = .{ .tag = .int_u64 },
......@@ -8841,8 +8900,7 @@ pub const FuncGen = struct {
88418900 defer self.gpa.free(fqn);
88428901 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn});
88438902
8844 var int_tag_type_buffer: Type.Payload.Bits = undefined;
8845 const int_tag_ty = enum_ty.intTagType(&int_tag_type_buffer);
8903 const int_tag_ty = enum_ty.intTagType();
88468904 const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};
88478905
88488906 const llvm_ret_ty = try self.dg.lowerType(Type.bool);
......@@ -8923,11 +8981,9 @@ pub const FuncGen = struct {
89238981 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
89248982 const llvm_ret_ty = try self.dg.lowerType(slice_ty);
89258983 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8926 const target = self.dg.module.getTarget();
8927 const slice_alignment = slice_ty.abiAlignment(target);
8984 const slice_alignment = slice_ty.abiAlignment(mod);
89288985
8929 var int_tag_type_buffer: Type.Payload.Bits = undefined;
8930 const int_tag_ty = enum_ty.intTagType(&int_tag_type_buffer);
8986 const int_tag_ty = enum_ty.intTagType();
89318987 const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)};
89328988
89338989 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);
......@@ -9057,6 +9113,7 @@ pub const FuncGen = struct {
90579113 }
90589114
90599115 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9116 const mod = self.dg.module;
90609117 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
90619118 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
90629119 const a = try self.resolveInst(extra.a);
......@@ -9077,11 +9134,11 @@ pub const FuncGen = struct {
90779134
90789135 for (values, 0..) |*val, i| {
90799136 var buf: Value.ElemValueBuffer = undefined;
9080 const elem = mask.elemValueBuffer(self.dg.module, i, &buf);
9137 const elem = mask.elemValueBuffer(mod, i, &buf);
90819138 if (elem.isUndef()) {
90829139 val.* = llvm_i32.getUndef();
90839140 } else {
9084 const int = elem.toSignedInt(self.dg.module.getTarget());
9141 const int = elem.toSignedInt(mod);
90859142 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int + a_len);
90869143 val.* = llvm_i32.constInt(unsigned, .False);
90879144 }
......@@ -9157,7 +9214,8 @@ pub const FuncGen = struct {
91579214
91589215 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value {
91599216 self.builder.setFastMath(want_fast_math);
9160 const target = self.dg.module.getTarget();
9217 const mod = self.dg.module;
9218 const target = mod.getTarget();
91619219
91629220 const reduce = self.air.instructions.items(.data)[inst].reduce;
91639221 const operand = try self.resolveInst(reduce.operand);
......@@ -9168,21 +9226,21 @@ pub const FuncGen = struct {
91689226 .And => return self.builder.buildAndReduce(operand),
91699227 .Or => return self.builder.buildOrReduce(operand),
91709228 .Xor => return self.builder.buildXorReduce(operand),
9171 .Min => switch (scalar_ty.zigTypeTag()) {
9172 .Int => return self.builder.buildIntMinReduce(operand, scalar_ty.isSignedInt()),
9229 .Min => switch (scalar_ty.zigTypeTag(mod)) {
9230 .Int => return self.builder.buildIntMinReduce(operand, scalar_ty.isSignedInt(mod)),
91739231 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
91749232 return self.builder.buildFPMinReduce(operand);
91759233 },
91769234 else => unreachable,
91779235 },
9178 .Max => switch (scalar_ty.zigTypeTag()) {
9179 .Int => return self.builder.buildIntMaxReduce(operand, scalar_ty.isSignedInt()),
9236 .Max => switch (scalar_ty.zigTypeTag(mod)) {
9237 .Int => return self.builder.buildIntMaxReduce(operand, scalar_ty.isSignedInt(mod)),
91809238 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
91819239 return self.builder.buildFPMaxReduce(operand);
91829240 },
91839241 else => unreachable,
91849242 },
9185 .Add => switch (scalar_ty.zigTypeTag()) {
9243 .Add => switch (scalar_ty.zigTypeTag(mod)) {
91869244 .Int => return self.builder.buildAddReduce(operand),
91879245 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
91889246 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
......@@ -9191,7 +9249,7 @@ pub const FuncGen = struct {
91919249 },
91929250 else => unreachable,
91939251 },
9194 .Mul => switch (scalar_ty.zigTypeTag()) {
9252 .Mul => switch (scalar_ty.zigTypeTag(mod)) {
91959253 .Int => return self.builder.buildMulReduce(operand),
91969254 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
91979255 const scalar_llvm_ty = try self.dg.lowerType(scalar_ty);
......@@ -9247,9 +9305,9 @@ pub const FuncGen = struct {
92479305 const len = @intCast(usize, result_ty.arrayLen());
92489306 const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]);
92499307 const llvm_result_ty = try self.dg.lowerType(result_ty);
9250 const target = self.dg.module.getTarget();
9308 const mod = self.dg.module;
92519309
9252 switch (result_ty.zigTypeTag()) {
9310 switch (result_ty.zigTypeTag(mod)) {
92539311 .Vector => {
92549312 const llvm_u32 = self.context.intType(32);
92559313
......@@ -9265,7 +9323,7 @@ pub const FuncGen = struct {
92659323 if (result_ty.containerLayout() == .Packed) {
92669324 const struct_obj = result_ty.castTag(.@"struct").?.data;
92679325 assert(struct_obj.haveLayout());
9268 const big_bits = struct_obj.backing_int_ty.bitSize(target);
9326 const big_bits = struct_obj.backing_int_ty.bitSize(mod);
92699327 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));
92709328 const fields = struct_obj.fields.values();
92719329 comptime assert(Type.packed_struct_layout_version == 2);
......@@ -9273,12 +9331,12 @@ pub const FuncGen = struct {
92739331 var running_bits: u16 = 0;
92749332 for (elements, 0..) |elem, i| {
92759333 const field = fields[i];
9276 if (!field.ty.hasRuntimeBitsIgnoreComptime()) continue;
9334 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
92779335
92789336 const non_int_val = try self.resolveInst(elem);
9279 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
9337 const ty_bit_size = @intCast(u16, field.ty.bitSize(mod));
92809338 const small_int_ty = self.context.intType(ty_bit_size);
9281 const small_int_val = if (field.ty.isPtrAtRuntime())
9339 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
92829340 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
92839341 else
92849342 self.builder.buildBitCast(non_int_val, small_int_ty, "");
......@@ -9296,24 +9354,24 @@ pub const FuncGen = struct {
92969354
92979355 var ptr_ty_buf: Type.Payload.Pointer = undefined;
92989356
9299 if (isByRef(result_ty)) {
9357 if (isByRef(result_ty, mod)) {
93009358 const llvm_u32 = self.context.intType(32);
93019359 // TODO in debug builds init to undef so that the padding will be 0xaa
93029360 // even if we fully populate the fields.
9303 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(target));
9361 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));
93049362
93059363 var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined };
93069364 for (elements, 0..) |elem, i| {
9307 if (result_ty.structFieldValueComptime(i) != null) continue;
9365 if (result_ty.structFieldValueComptime(mod, i) != null) continue;
93089366
93099367 const llvm_elem = try self.resolveInst(elem);
9310 const llvm_i = llvmFieldIndex(result_ty, i, target, &ptr_ty_buf).?;
9368 const llvm_i = llvmFieldIndex(result_ty, i, mod, &ptr_ty_buf).?;
93119369 indices[1] = llvm_u32.constInt(llvm_i, .False);
93129370 const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
93139371 var field_ptr_payload: Type.Payload.Pointer = .{
93149372 .data = .{
93159373 .pointee_type = self.air.typeOf(elem),
9316 .@"align" = result_ty.structFieldAlign(i, target),
9374 .@"align" = result_ty.structFieldAlign(i, mod),
93179375 .@"addrspace" = .generic,
93189376 },
93199377 };
......@@ -9325,20 +9383,20 @@ pub const FuncGen = struct {
93259383 } else {
93269384 var result = llvm_result_ty.getUndef();
93279385 for (elements, 0..) |elem, i| {
9328 if (result_ty.structFieldValueComptime(i) != null) continue;
9386 if (result_ty.structFieldValueComptime(mod, i) != null) continue;
93299387
93309388 const llvm_elem = try self.resolveInst(elem);
9331 const llvm_i = llvmFieldIndex(result_ty, i, target, &ptr_ty_buf).?;
9389 const llvm_i = llvmFieldIndex(result_ty, i, mod, &ptr_ty_buf).?;
93329390 result = self.builder.buildInsertValue(result, llvm_elem, llvm_i, "");
93339391 }
93349392 return result;
93359393 }
93369394 },
93379395 .Array => {
9338 assert(isByRef(result_ty));
9396 assert(isByRef(result_ty, mod));
93399397
93409398 const llvm_usize = try self.dg.lowerType(Type.usize);
9341 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(target));
9399 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));
93429400
93439401 const array_info = result_ty.arrayInfo();
93449402 var elem_ptr_payload: Type.Payload.Pointer = .{
......@@ -9379,22 +9437,22 @@ pub const FuncGen = struct {
93799437 }
93809438
93819439 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9440 const mod = self.dg.module;
93829441 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
93839442 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
93849443 const union_ty = self.air.typeOfIndex(inst);
93859444 const union_llvm_ty = try self.dg.lowerType(union_ty);
9386 const target = self.dg.module.getTarget();
9387 const layout = union_ty.unionGetLayout(target);
9445 const layout = union_ty.unionGetLayout(mod);
93889446 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
93899447
93909448 if (union_obj.layout == .Packed) {
9391 const big_bits = union_ty.bitSize(target);
9449 const big_bits = union_ty.bitSize(mod);
93929450 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));
93939451 const field = union_obj.fields.values()[extra.field_index];
93949452 const non_int_val = try self.resolveInst(extra.init);
9395 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
9453 const ty_bit_size = @intCast(u16, field.ty.bitSize(mod));
93969454 const small_int_ty = self.context.intType(ty_bit_size);
9397 const small_int_val = if (field.ty.isPtrAtRuntime())
9455 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
93989456 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
93999457 else
94009458 self.builder.buildBitCast(non_int_val, small_int_ty, "");
......@@ -9412,16 +9470,16 @@ pub const FuncGen = struct {
94129470 const tag_val = Value.initPayload(&tag_val_payload.base);
94139471 var int_payload: Value.Payload.U64 = undefined;
94149472 const tag_int_val = tag_val.enumToInt(tag_ty, &int_payload);
9415 break :blk tag_int_val.toUnsignedInt(target);
9473 break :blk tag_int_val.toUnsignedInt(mod);
94169474 };
94179475 if (layout.payload_size == 0) {
94189476 if (layout.tag_size == 0) {
94199477 return null;
94209478 }
9421 assert(!isByRef(union_ty));
9479 assert(!isByRef(union_ty, mod));
94229480 return union_llvm_ty.constInt(tag_int, .False);
94239481 }
9424 assert(isByRef(union_ty));
9482 assert(isByRef(union_ty, mod));
94259483 // The llvm type of the alloca will be the named LLVM union type, and will not
94269484 // necessarily match the format that we need, depending on which tag is active.
94279485 // We must construct the correct unnamed struct type here, in order to then set
......@@ -9431,12 +9489,12 @@ pub const FuncGen = struct {
94319489 assert(union_obj.haveFieldTypes());
94329490 const field = union_obj.fields.values()[extra.field_index];
94339491 const field_llvm_ty = try self.dg.lowerType(field.ty);
9434 const field_size = field.ty.abiSize(target);
9435 const field_align = field.normalAlignment(target);
9492 const field_size = field.ty.abiSize(mod);
9493 const field_align = field.normalAlignment(mod);
94369494
94379495 const llvm_union_ty = t: {
94389496 const payload = p: {
9439 if (!field.ty.hasRuntimeBitsIgnoreComptime()) {
9497 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) {
94409498 const padding_len = @intCast(c_uint, layout.payload_size);
94419499 break :p self.context.intType(8).arrayType(padding_len);
94429500 }
......@@ -9511,7 +9569,7 @@ pub const FuncGen = struct {
95119569 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
95129570 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);
95139571 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
9514 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(target));
9572 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod));
95159573 }
95169574
95179575 return result_ptr;
......@@ -9535,7 +9593,8 @@ pub const FuncGen = struct {
95359593 // by the target.
95369594 // To work around this, don't emit llvm.prefetch in this case.
95379595 // See https://bugs.llvm.org/show_bug.cgi?id=21037
9538 const target = self.dg.module.getTarget();
9596 const mod = self.dg.module;
9597 const target = mod.getTarget();
95399598 switch (prefetch.cache) {
95409599 .instruction => switch (target.cpu.arch) {
95419600 .x86_64,
......@@ -9658,8 +9717,9 @@ pub const FuncGen = struct {
96589717 return table;
96599718 }
96609719
9720 const mod = self.dg.module;
96619721 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
9662 const slice_alignment = slice_ty.abiAlignment(self.dg.module.getTarget());
9722 const slice_alignment = slice_ty.abiAlignment(mod);
96639723 const llvm_slice_ptr_ty = self.context.pointerType(0); // TODO: Address space
96649724
96659725 const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table");
......@@ -9703,14 +9763,14 @@ pub const FuncGen = struct {
97039763 ) !*llvm.Value {
97049764 var buf: Type.Payload.ElemType = undefined;
97059765 const payload_ty = opt_ty.optionalChild(&buf);
9766 const mod = fg.dg.module;
97069767
9707 if (isByRef(opt_ty)) {
9768 if (isByRef(opt_ty, mod)) {
97089769 // We have a pointer and we need to return a pointer to the first field.
97099770 const payload_ptr = fg.builder.buildStructGEP(opt_llvm_ty, opt_handle, 0, "");
97109771
9711 const target = fg.dg.module.getTarget();
9712 const payload_alignment = payload_ty.abiAlignment(target);
9713 if (isByRef(payload_ty)) {
9772 const payload_alignment = payload_ty.abiAlignment(mod);
9773 if (isByRef(payload_ty, mod)) {
97149774 if (can_elide_load)
97159775 return payload_ptr;
97169776
......@@ -9722,7 +9782,7 @@ pub const FuncGen = struct {
97229782 return load_inst;
97239783 }
97249784
9725 assert(!isByRef(payload_ty));
9785 assert(!isByRef(payload_ty, mod));
97269786 return fg.builder.buildExtractValue(opt_handle, 0, "");
97279787 }
97289788
......@@ -9734,10 +9794,10 @@ pub const FuncGen = struct {
97349794 ) !?*llvm.Value {
97359795 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
97369796 const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), "");
9797 const mod = self.dg.module;
97379798
9738 if (isByRef(optional_ty)) {
9739 const target = self.dg.module.getTarget();
9740 const payload_alignment = optional_ty.abiAlignment(target);
9799 if (isByRef(optional_ty, mod)) {
9800 const payload_alignment = optional_ty.abiAlignment(mod);
97419801 const alloca_inst = self.buildAlloca(optional_llvm_ty, payload_alignment);
97429802
97439803 {
......@@ -9765,9 +9825,9 @@ pub const FuncGen = struct {
97659825 struct_ptr_ty: Type,
97669826 field_index: u32,
97679827 ) !?*llvm.Value {
9768 const target = self.dg.object.target;
97699828 const struct_ty = struct_ptr_ty.childType();
9770 switch (struct_ty.zigTypeTag()) {
9829 const mod = self.dg.module;
9830 switch (struct_ty.zigTypeTag(mod)) {
97719831 .Struct => switch (struct_ty.containerLayout()) {
97729832 .Packed => {
97739833 const result_ty = self.air.typeOfIndex(inst);
......@@ -9783,7 +9843,7 @@ pub const FuncGen = struct {
97839843
97849844 // We have a pointer to a packed struct field that happens to be byte-aligned.
97859845 // Offset our operand pointer by the correct number of bytes.
9786 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, target);
9846 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod);
97879847 if (byte_offset == 0) return struct_ptr;
97889848 const byte_llvm_ty = self.context.intType(8);
97899849 const llvm_usize = try self.dg.lowerType(Type.usize);
......@@ -9795,7 +9855,7 @@ pub const FuncGen = struct {
97959855 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);
97969856
97979857 var ty_buf: Type.Payload.Pointer = undefined;
9798 if (llvmFieldIndex(struct_ty, field_index, target, &ty_buf)) |llvm_field_index| {
9858 if (llvmFieldIndex(struct_ty, field_index, mod, &ty_buf)) |llvm_field_index| {
97999859 return self.builder.buildStructGEP(struct_llvm_ty, struct_ptr, llvm_field_index, "");
98009860 } else {
98019861 // If we found no index then this means this is a zero sized field at the
......@@ -9803,14 +9863,14 @@ pub const FuncGen = struct {
98039863 // the index to the element at index `1` to get a pointer to the end of
98049864 // the struct.
98059865 const llvm_u32 = self.context.intType(32);
9806 const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False);
9866 const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
98079867 const indices: [1]*llvm.Value = .{llvm_index};
98089868 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");
98099869 }
98109870 },
98119871 },
98129872 .Union => {
9813 const layout = struct_ty.unionGetLayout(target);
9873 const layout = struct_ty.unionGetLayout(mod);
98149874 if (layout.payload_size == 0 or struct_ty.containerLayout() == .Packed) return struct_ptr;
98159875 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
98169876 const union_llvm_ty = try self.dg.lowerType(struct_ty);
......@@ -9835,12 +9895,12 @@ pub const FuncGen = struct {
98359895 ptr_alignment: u32,
98369896 is_volatile: bool,
98379897 ) !*llvm.Value {
9898 const mod = fg.dg.module;
98389899 const pointee_llvm_ty = try fg.dg.lowerType(pointee_type);
9839 const target = fg.dg.module.getTarget();
9840 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target));
9900 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));
98419901 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);
9842 const llvm_usize = fg.context.intType(Type.usize.intInfo(target).bits);
9843 const size_bytes = pointee_type.abiSize(target);
9902 const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits);
9903 const size_bytes = pointee_type.abiSize(mod);
98449904 _ = fg.builder.buildMemCpy(
98459905 result_ptr,
98469906 result_align,
......@@ -9856,11 +9916,11 @@ pub const FuncGen = struct {
98569916 /// alloca and copies the value into it, then returns the alloca instruction.
98579917 /// For isByRef=false types, it creates a load instruction and returns it.
98589918 fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value {
9919 const mod = self.dg.module;
98599920 const info = ptr_ty.ptrInfo().data;
9860 if (!info.pointee_type.hasRuntimeBitsIgnoreComptime()) return null;
9921 if (!info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) return null;
98619922
9862 const target = self.dg.module.getTarget();
9863 const ptr_alignment = info.alignment(target);
9923 const ptr_alignment = info.alignment(mod);
98649924 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());
98659925
98669926 assert(info.vector_index != .runtime);
......@@ -9877,7 +9937,7 @@ pub const FuncGen = struct {
98779937 }
98789938
98799939 if (info.host_size == 0) {
9880 if (isByRef(info.pointee_type)) {
9940 if (isByRef(info.pointee_type, mod)) {
98819941 return self.loadByRef(ptr, info.pointee_type, ptr_alignment, info.@"volatile");
98829942 }
98839943 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
......@@ -9892,13 +9952,13 @@ pub const FuncGen = struct {
98929952 containing_int.setAlignment(ptr_alignment);
98939953 containing_int.setVolatile(ptr_volatile);
98949954
9895 const elem_bits = @intCast(c_uint, ptr_ty.elemType().bitSize(target));
9955 const elem_bits = @intCast(c_uint, ptr_ty.elemType().bitSize(mod));
98969956 const shift_amt = containing_int.typeOf().constInt(info.bit_offset, .False);
98979957 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
98989958 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
98999959
9900 if (isByRef(info.pointee_type)) {
9901 const result_align = info.pointee_type.abiAlignment(target);
9960 if (isByRef(info.pointee_type, mod)) {
9961 const result_align = info.pointee_type.abiAlignment(mod);
99029962 const result_ptr = self.buildAlloca(elem_llvm_ty, result_align);
99039963
99049964 const same_size_int = self.context.intType(elem_bits);
......@@ -9908,13 +9968,13 @@ pub const FuncGen = struct {
99089968 return result_ptr;
99099969 }
99109970
9911 if (info.pointee_type.zigTypeTag() == .Float or info.pointee_type.zigTypeTag() == .Vector) {
9971 if (info.pointee_type.zigTypeTag(mod) == .Float or info.pointee_type.zigTypeTag(mod) == .Vector) {
99129972 const same_size_int = self.context.intType(elem_bits);
99139973 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
99149974 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
99159975 }
99169976
9917 if (info.pointee_type.isPtrAtRuntime()) {
9977 if (info.pointee_type.isPtrAtRuntime(mod)) {
99189978 const same_size_int = self.context.intType(elem_bits);
99199979 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
99209980 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
......@@ -9932,11 +9992,11 @@ pub const FuncGen = struct {
99329992 ) !void {
99339993 const info = ptr_ty.ptrInfo().data;
99349994 const elem_ty = info.pointee_type;
9935 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime()) {
9995 const mod = self.dg.module;
9996 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
99369997 return;
99379998 }
9938 const target = self.dg.module.getTarget();
9939 const ptr_alignment = ptr_ty.ptrAlignment(target);
9999 const ptr_alignment = ptr_ty.ptrAlignment(mod);
994010000 const ptr_volatile = llvm.Bool.fromBool(info.@"volatile");
994110001
994210002 assert(info.vector_index != .runtime);
......@@ -9964,13 +10024,13 @@ pub const FuncGen = struct {
996410024 assert(ordering == .NotAtomic);
996510025 containing_int.setAlignment(ptr_alignment);
996610026 containing_int.setVolatile(ptr_volatile);
9967 const elem_bits = @intCast(c_uint, ptr_ty.elemType().bitSize(target));
10027 const elem_bits = @intCast(c_uint, ptr_ty.elemType().bitSize(mod));
996810028 const containing_int_ty = containing_int.typeOf();
996910029 const shift_amt = containing_int_ty.constInt(info.bit_offset, .False);
997010030 // Convert to equally-sized integer type in order to perform the bit
997110031 // operations on the value to store
997210032 const value_bits_type = self.context.intType(elem_bits);
9973 const value_bits = if (elem_ty.isPtrAtRuntime())
10033 const value_bits = if (elem_ty.isPtrAtRuntime(mod))
997410034 self.builder.buildPtrToInt(elem, value_bits_type, "")
997510035 else
997610036 self.builder.buildBitCast(elem, value_bits_type, "");
......@@ -9991,7 +10051,7 @@ pub const FuncGen = struct {
999110051 store_inst.setVolatile(ptr_volatile);
999210052 return;
999310053 }
9994 if (!isByRef(elem_ty)) {
10054 if (!isByRef(elem_ty, mod)) {
999510055 const store_inst = self.builder.buildStore(elem, ptr);
999610056 store_inst.setOrdering(ordering);
999710057 store_inst.setAlignment(ptr_alignment);
......@@ -9999,13 +10059,13 @@ pub const FuncGen = struct {
999910059 return;
1000010060 }
1000110061 assert(ordering == .NotAtomic);
10002 const size_bytes = elem_ty.abiSize(target);
10062 const size_bytes = elem_ty.abiSize(mod);
1000310063 _ = self.builder.buildMemCpy(
1000410064 ptr,
1000510065 ptr_alignment,
1000610066 elem,
10007 elem_ty.abiAlignment(target),
10008 self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False),
10067 elem_ty.abiAlignment(mod),
10068 self.context.intType(Type.usize.intInfo(mod).bits).constInt(size_bytes, .False),
1000910069 info.@"volatile",
1001010070 );
1001110071 }
......@@ -10030,11 +10090,12 @@ pub const FuncGen = struct {
1003010090 a4: *llvm.Value,
1003110091 a5: *llvm.Value,
1003210092 ) *llvm.Value {
10033 const target = fg.dg.module.getTarget();
10093 const mod = fg.dg.module;
10094 const target = mod.getTarget();
1003410095 if (!target_util.hasValgrindSupport(target)) return default_value;
1003510096
1003610097 const usize_llvm_ty = fg.context.intType(target.ptrBitWidth());
10037 const usize_alignment = @intCast(c_uint, Type.usize.abiSize(target));
10098 const usize_alignment = @intCast(c_uint, Type.usize.abiSize(mod));
1003810099
1003910100 const array_llvm_ty = usize_llvm_ty.arrayType(6);
1004010101 const array_ptr = fg.valgrind_client_request_array orelse a: {
......@@ -10451,7 +10512,7 @@ fn toLlvmGlobalAddressSpace(wanted_address_space: std.builtin.AddressSpace, targ
1045110512fn llvmFieldIndex(
1045210513 ty: Type,
1045310514 field_index: usize,
10454 target: std.Target,
10515 mod: *const Module,
1045510516 ptr_pl_buf: *Type.Payload.Pointer,
1045610517) ?c_uint {
1045710518 // Detects where we inserted extra padding fields so that we can skip
......@@ -10464,9 +10525,9 @@ fn llvmFieldIndex(
1046410525 const tuple = ty.tupleFields();
1046510526 var llvm_field_index: c_uint = 0;
1046610527 for (tuple.types, 0..) |field_ty, i| {
10467 if (tuple.values[i].tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue;
10528 if (tuple.values[i].tag() != .unreachable_value or !field_ty.hasRuntimeBits(mod)) continue;
1046810529
10469 const field_align = field_ty.abiAlignment(target);
10530 const field_align = field_ty.abiAlignment(mod);
1047010531 big_align = @max(big_align, field_align);
1047110532 const prev_offset = offset;
1047210533 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
......@@ -10488,7 +10549,7 @@ fn llvmFieldIndex(
1048810549 }
1048910550
1049010551 llvm_field_index += 1;
10491 offset += field_ty.abiSize(target);
10552 offset += field_ty.abiSize(mod);
1049210553 }
1049310554 return null;
1049410555 }
......@@ -10496,10 +10557,10 @@ fn llvmFieldIndex(
1049610557 assert(layout != .Packed);
1049710558
1049810559 var llvm_field_index: c_uint = 0;
10499 var it = ty.castTag(.@"struct").?.data.runtimeFieldIterator();
10560 var it = ty.castTag(.@"struct").?.data.runtimeFieldIterator(mod);
1050010561 while (it.next()) |field_and_index| {
1050110562 const field = field_and_index.field;
10502 const field_align = field.alignment(target, layout);
10563 const field_align = field.alignment(mod, layout);
1050310564 big_align = @max(big_align, field_align);
1050410565 const prev_offset = offset;
1050510566 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
......@@ -10521,43 +10582,44 @@ fn llvmFieldIndex(
1052110582 }
1052210583
1052310584 llvm_field_index += 1;
10524 offset += field.ty.abiSize(target);
10585 offset += field.ty.abiSize(mod);
1052510586 } else {
1052610587 // We did not find an llvm field that corresponds to this zig field.
1052710588 return null;
1052810589 }
1052910590}
1053010591
10531fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool {
10532 if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime()) return false;
10592fn firstParamSRet(fn_info: Type.Payload.Function.Data, mod: *const Module) bool {
10593 if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime(mod)) return false;
1053310594
10595 const target = mod.getTarget();
1053410596 switch (fn_info.cc) {
10535 .Unspecified, .Inline => return isByRef(fn_info.return_type),
10597 .Unspecified, .Inline => return isByRef(fn_info.return_type, mod),
1053610598 .C => switch (target.cpu.arch) {
1053710599 .mips, .mipsel => return false,
1053810600 .x86_64 => switch (target.os.tag) {
10539 .windows => return x86_64_abi.classifyWindows(fn_info.return_type, target) == .memory,
10540 else => return firstParamSRetSystemV(fn_info.return_type, target),
10601 .windows => return x86_64_abi.classifyWindows(fn_info.return_type, mod) == .memory,
10602 else => return firstParamSRetSystemV(fn_info.return_type, mod),
1054110603 },
10542 .wasm32 => return wasm_c_abi.classifyType(fn_info.return_type, target)[0] == .indirect,
10543 .aarch64, .aarch64_be => return aarch64_c_abi.classifyType(fn_info.return_type, target) == .memory,
10544 .arm, .armeb => switch (arm_c_abi.classifyType(fn_info.return_type, target, .ret)) {
10604 .wasm32 => return wasm_c_abi.classifyType(fn_info.return_type, mod)[0] == .indirect,
10605 .aarch64, .aarch64_be => return aarch64_c_abi.classifyType(fn_info.return_type, mod) == .memory,
10606 .arm, .armeb => switch (arm_c_abi.classifyType(fn_info.return_type, mod, .ret)) {
1054510607 .memory, .i64_array => return true,
1054610608 .i32_array => |size| return size != 1,
1054710609 .byval => return false,
1054810610 },
10549 .riscv32, .riscv64 => return riscv_c_abi.classifyType(fn_info.return_type, target) == .memory,
10611 .riscv32, .riscv64 => return riscv_c_abi.classifyType(fn_info.return_type, mod) == .memory,
1055010612 else => return false, // TODO investigate C ABI for other architectures
1055110613 },
10552 .SysV => return firstParamSRetSystemV(fn_info.return_type, target),
10553 .Win64 => return x86_64_abi.classifyWindows(fn_info.return_type, target) == .memory,
10554 .Stdcall => return !isScalar(fn_info.return_type),
10614 .SysV => return firstParamSRetSystemV(fn_info.return_type, mod),
10615 .Win64 => return x86_64_abi.classifyWindows(fn_info.return_type, mod) == .memory,
10616 .Stdcall => return !isScalar(mod, fn_info.return_type),
1055510617 else => return false,
1055610618 }
1055710619}
1055810620
10559fn firstParamSRetSystemV(ty: Type, target: std.Target) bool {
10560 const class = x86_64_abi.classifySystemV(ty, target, .ret);
10621fn firstParamSRetSystemV(ty: Type, mod: *const Module) bool {
10622 const class = x86_64_abi.classifySystemV(ty, mod, .ret);
1056110623 if (class[0] == .memory) return true;
1056210624 if (class[0] == .x87 and class[2] != .none) return true;
1056310625 return false;
......@@ -10567,20 +10629,21 @@ fn firstParamSRetSystemV(ty: Type, target: std.Target) bool {
1056710629/// completely differently in the function prototype to honor the C ABI, and then
1056810630/// be effectively bitcasted to the actual return type.
1056910631fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
10570 if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime()) {
10632 const mod = dg.module;
10633 if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime(mod)) {
1057110634 // If the return type is an error set or an error union, then we make this
1057210635 // anyerror return type instead, so that it can be coerced into a function
1057310636 // pointer type which has anyerror as the return type.
10574 if (fn_info.return_type.isError()) {
10637 if (fn_info.return_type.isError(mod)) {
1057510638 return dg.lowerType(Type.anyerror);
1057610639 } else {
1057710640 return dg.context.voidType();
1057810641 }
1057910642 }
10580 const target = dg.module.getTarget();
10643 const target = mod.getTarget();
1058110644 switch (fn_info.cc) {
1058210645 .Unspecified, .Inline => {
10583 if (isByRef(fn_info.return_type)) {
10646 if (isByRef(fn_info.return_type, mod)) {
1058410647 return dg.context.voidType();
1058510648 } else {
1058610649 return dg.lowerType(fn_info.return_type);
......@@ -10594,33 +10657,33 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
1059410657 else => return lowerSystemVFnRetTy(dg, fn_info),
1059510658 },
1059610659 .wasm32 => {
10597 if (isScalar(fn_info.return_type)) {
10660 if (isScalar(mod, fn_info.return_type)) {
1059810661 return dg.lowerType(fn_info.return_type);
1059910662 }
10600 const classes = wasm_c_abi.classifyType(fn_info.return_type, target);
10663 const classes = wasm_c_abi.classifyType(fn_info.return_type, mod);
1060110664 if (classes[0] == .indirect or classes[0] == .none) {
1060210665 return dg.context.voidType();
1060310666 }
1060410667
1060510668 assert(classes[0] == .direct and classes[1] == .none);
10606 const scalar_type = wasm_c_abi.scalarType(fn_info.return_type, target);
10607 const abi_size = scalar_type.abiSize(target);
10669 const scalar_type = wasm_c_abi.scalarType(fn_info.return_type, mod);
10670 const abi_size = scalar_type.abiSize(mod);
1060810671 return dg.context.intType(@intCast(c_uint, abi_size * 8));
1060910672 },
1061010673 .aarch64, .aarch64_be => {
10611 switch (aarch64_c_abi.classifyType(fn_info.return_type, target)) {
10674 switch (aarch64_c_abi.classifyType(fn_info.return_type, mod)) {
1061210675 .memory => return dg.context.voidType(),
1061310676 .float_array => return dg.lowerType(fn_info.return_type),
1061410677 .byval => return dg.lowerType(fn_info.return_type),
1061510678 .integer => {
10616 const bit_size = fn_info.return_type.bitSize(target);
10679 const bit_size = fn_info.return_type.bitSize(mod);
1061710680 return dg.context.intType(@intCast(c_uint, bit_size));
1061810681 },
1061910682 .double_integer => return dg.context.intType(64).arrayType(2),
1062010683 }
1062110684 },
1062210685 .arm, .armeb => {
10623 switch (arm_c_abi.classifyType(fn_info.return_type, target, .ret)) {
10686 switch (arm_c_abi.classifyType(fn_info.return_type, mod, .ret)) {
1062410687 .memory, .i64_array => return dg.context.voidType(),
1062510688 .i32_array => |len| if (len == 1) {
1062610689 return dg.context.intType(32);
......@@ -10631,10 +10694,10 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
1063110694 }
1063210695 },
1063310696 .riscv32, .riscv64 => {
10634 switch (riscv_c_abi.classifyType(fn_info.return_type, target)) {
10697 switch (riscv_c_abi.classifyType(fn_info.return_type, mod)) {
1063510698 .memory => return dg.context.voidType(),
1063610699 .integer => {
10637 const bit_size = fn_info.return_type.bitSize(target);
10700 const bit_size = fn_info.return_type.bitSize(mod);
1063810701 return dg.context.intType(@intCast(c_uint, bit_size));
1063910702 },
1064010703 .double_integer => {
......@@ -10654,7 +10717,7 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
1065410717 .Win64 => return lowerWin64FnRetTy(dg, fn_info),
1065510718 .SysV => return lowerSystemVFnRetTy(dg, fn_info),
1065610719 .Stdcall => {
10657 if (isScalar(fn_info.return_type)) {
10720 if (isScalar(mod, fn_info.return_type)) {
1065810721 return dg.lowerType(fn_info.return_type);
1065910722 } else {
1066010723 return dg.context.voidType();
......@@ -10665,13 +10728,13 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
1066510728}
1066610729
1066710730fn lowerWin64FnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
10668 const target = dg.module.getTarget();
10669 switch (x86_64_abi.classifyWindows(fn_info.return_type, target)) {
10731 const mod = dg.module;
10732 switch (x86_64_abi.classifyWindows(fn_info.return_type, mod)) {
1067010733 .integer => {
10671 if (isScalar(fn_info.return_type)) {
10734 if (isScalar(mod, fn_info.return_type)) {
1067210735 return dg.lowerType(fn_info.return_type);
1067310736 } else {
10674 const abi_size = fn_info.return_type.abiSize(target);
10737 const abi_size = fn_info.return_type.abiSize(mod);
1067510738 return dg.context.intType(@intCast(c_uint, abi_size * 8));
1067610739 }
1067710740 },
......@@ -10683,11 +10746,11 @@ fn lowerWin64FnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.T
1068310746}
1068410747
1068510748fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
10686 if (isScalar(fn_info.return_type)) {
10749 const mod = dg.module;
10750 if (isScalar(mod, fn_info.return_type)) {
1068710751 return dg.lowerType(fn_info.return_type);
1068810752 }
10689 const target = dg.module.getTarget();
10690 const classes = x86_64_abi.classifySystemV(fn_info.return_type, target, .ret);
10753 const classes = x86_64_abi.classifySystemV(fn_info.return_type, mod, .ret);
1069110754 if (classes[0] == .memory) {
1069210755 return dg.context.voidType();
1069310756 }
......@@ -10728,7 +10791,7 @@ fn lowerSystemVFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm
1072810791 }
1072910792 }
1073010793 if (classes[0] == .integer and classes[1] == .none) {
10731 const abi_size = fn_info.return_type.abiSize(target);
10794 const abi_size = fn_info.return_type.abiSize(mod);
1073210795 return dg.context.intType(@intCast(c_uint, abi_size * 8));
1073310796 }
1073410797 return dg.context.structType(&llvm_types_buffer, llvm_types_index, .False);
......@@ -10739,7 +10802,6 @@ const ParamTypeIterator = struct {
1073910802 fn_info: Type.Payload.Function.Data,
1074010803 zig_index: u32,
1074110804 llvm_index: u32,
10742 target: std.Target,
1074310805 llvm_types_len: u32,
1074410806 llvm_types_buffer: [8]*llvm.Type,
1074510807 byval_attr: bool,
......@@ -10779,7 +10841,10 @@ const ParamTypeIterator = struct {
1077910841 }
1078010842
1078110843 fn nextInner(it: *ParamTypeIterator, ty: Type) ?Lowering {
10782 if (!ty.hasRuntimeBitsIgnoreComptime()) {
10844 const mod = it.dg.module;
10845 const target = mod.getTarget();
10846
10847 if (!ty.hasRuntimeBitsIgnoreComptime(mod)) {
1078310848 it.zig_index += 1;
1078410849 return .no_bits;
1078510850 }
......@@ -10788,10 +10853,10 @@ const ParamTypeIterator = struct {
1078810853 it.zig_index += 1;
1078910854 it.llvm_index += 1;
1079010855 var buf: Type.Payload.ElemType = undefined;
10791 if (ty.isSlice() or (ty.zigTypeTag() == .Optional and ty.optionalChild(&buf).isSlice())) {
10856 if (ty.isSlice() or (ty.zigTypeTag(mod) == .Optional and ty.optionalChild(&buf).isSlice())) {
1079210857 it.llvm_index += 1;
1079310858 return .slice;
10794 } else if (isByRef(ty)) {
10859 } else if (isByRef(ty, mod)) {
1079510860 return .byref;
1079610861 } else {
1079710862 return .byval;
......@@ -10801,23 +10866,23 @@ const ParamTypeIterator = struct {
1080110866 @panic("TODO implement async function lowering in the LLVM backend");
1080210867 },
1080310868 .C => {
10804 switch (it.target.cpu.arch) {
10869 switch (target.cpu.arch) {
1080510870 .mips, .mipsel => {
1080610871 it.zig_index += 1;
1080710872 it.llvm_index += 1;
1080810873 return .byval;
1080910874 },
10810 .x86_64 => switch (it.target.os.tag) {
10875 .x86_64 => switch (target.os.tag) {
1081110876 .windows => return it.nextWin64(ty),
1081210877 else => return it.nextSystemV(ty),
1081310878 },
1081410879 .wasm32 => {
1081510880 it.zig_index += 1;
1081610881 it.llvm_index += 1;
10817 if (isScalar(ty)) {
10882 if (isScalar(mod, ty)) {
1081810883 return .byval;
1081910884 }
10820 const classes = wasm_c_abi.classifyType(ty, it.target);
10885 const classes = wasm_c_abi.classifyType(ty, mod);
1082110886 if (classes[0] == .indirect) {
1082210887 return .byref;
1082310888 }
......@@ -10826,7 +10891,7 @@ const ParamTypeIterator = struct {
1082610891 .aarch64, .aarch64_be => {
1082710892 it.zig_index += 1;
1082810893 it.llvm_index += 1;
10829 switch (aarch64_c_abi.classifyType(ty, it.target)) {
10894 switch (aarch64_c_abi.classifyType(ty, mod)) {
1083010895 .memory => return .byref_mut,
1083110896 .float_array => |len| return Lowering{ .float_array = len },
1083210897 .byval => return .byval,
......@@ -10841,7 +10906,7 @@ const ParamTypeIterator = struct {
1084110906 .arm, .armeb => {
1084210907 it.zig_index += 1;
1084310908 it.llvm_index += 1;
10844 switch (arm_c_abi.classifyType(ty, it.target, .arg)) {
10909 switch (arm_c_abi.classifyType(ty, mod, .arg)) {
1084510910 .memory => {
1084610911 it.byval_attr = true;
1084710912 return .byref;
......@@ -10857,7 +10922,7 @@ const ParamTypeIterator = struct {
1085710922 if (ty.tag() == .f16) {
1085810923 return .as_u16;
1085910924 }
10860 switch (riscv_c_abi.classifyType(ty, it.target)) {
10925 switch (riscv_c_abi.classifyType(ty, mod)) {
1086110926 .memory => return .byref_mut,
1086210927 .byval => return .byval,
1086310928 .integer => return .abi_sized_int,
......@@ -10878,7 +10943,7 @@ const ParamTypeIterator = struct {
1087810943 it.zig_index += 1;
1087910944 it.llvm_index += 1;
1088010945
10881 if (isScalar(ty)) {
10946 if (isScalar(mod, ty)) {
1088210947 return .byval;
1088310948 } else {
1088410949 it.byval_attr = true;
......@@ -10894,9 +10959,10 @@ const ParamTypeIterator = struct {
1089410959 }
1089510960
1089610961 fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {
10897 switch (x86_64_abi.classifyWindows(ty, it.target)) {
10962 const mod = it.dg.module;
10963 switch (x86_64_abi.classifyWindows(ty, mod)) {
1089810964 .integer => {
10899 if (isScalar(ty)) {
10965 if (isScalar(mod, ty)) {
1090010966 it.zig_index += 1;
1090110967 it.llvm_index += 1;
1090210968 return .byval;
......@@ -10926,14 +10992,15 @@ const ParamTypeIterator = struct {
1092610992 }
1092710993
1092810994 fn nextSystemV(it: *ParamTypeIterator, ty: Type) ?Lowering {
10929 const classes = x86_64_abi.classifySystemV(ty, it.target, .arg);
10995 const mod = it.dg.module;
10996 const classes = x86_64_abi.classifySystemV(ty, mod, .arg);
1093010997 if (classes[0] == .memory) {
1093110998 it.zig_index += 1;
1093210999 it.llvm_index += 1;
1093311000 it.byval_attr = true;
1093411001 return .byref;
1093511002 }
10936 if (isScalar(ty)) {
11003 if (isScalar(mod, ty)) {
1093711004 it.zig_index += 1;
1093811005 it.llvm_index += 1;
1093911006 return .byval;
......@@ -10992,7 +11059,6 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp
1099211059 .fn_info = fn_info,
1099311060 .zig_index = 0,
1099411061 .llvm_index = 0,
10995 .target = dg.module.getTarget(),
1099611062 .llvm_types_buffer = undefined,
1099711063 .llvm_types_len = 0,
1099811064 .byval_attr = false,
......@@ -11001,16 +11067,17 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp
1100111067
1100211068fn ccAbiPromoteInt(
1100311069 cc: std.builtin.CallingConvention,
11004 target: std.Target,
11070 mod: *const Module,
1100511071 ty: Type,
1100611072) ?std.builtin.Signedness {
11073 const target = mod.getTarget();
1100711074 switch (cc) {
1100811075 .Unspecified, .Inline, .Async => return null,
1100911076 else => {},
1101011077 }
11011 const int_info = switch (ty.zigTypeTag()) {
11012 .Bool => Type.u1.intInfo(target),
11013 .Int, .Enum, .ErrorSet => ty.intInfo(target),
11078 const int_info = switch (ty.zigTypeTag(mod)) {
11079 .Bool => Type.u1.intInfo(mod),
11080 .Int, .Enum, .ErrorSet => ty.intInfo(mod),
1101411081 else => return null,
1101511082 };
1101611083 if (int_info.bits <= 16) return int_info.signedness;
......@@ -11039,12 +11106,12 @@ fn ccAbiPromoteInt(
1103911106
1104011107/// This is the one source of truth for whether a type is passed around as an LLVM pointer,
1104111108/// or as an LLVM value.
11042fn isByRef(ty: Type) bool {
11109fn isByRef(ty: Type, mod: *const Module) bool {
1104311110 // For tuples and structs, if there are more than this many non-void
1104411111 // fields, then we make it byref, otherwise byval.
1104511112 const max_fields_byval = 0;
1104611113
11047 switch (ty.zigTypeTag()) {
11114 switch (ty.zigTypeTag(mod)) {
1104811115 .Type,
1104911116 .ComptimeInt,
1105011117 .ComptimeFloat,
......@@ -11067,7 +11134,7 @@ fn isByRef(ty: Type) bool {
1106711134 .AnyFrame,
1106811135 => return false,
1106911136
11070 .Array, .Frame => return ty.hasRuntimeBits(),
11137 .Array, .Frame => return ty.hasRuntimeBits(mod),
1107111138 .Struct => {
1107211139 // Packed structs are represented to LLVM as integers.
1107311140 if (ty.containerLayout() == .Packed) return false;
......@@ -11075,32 +11142,32 @@ fn isByRef(ty: Type) bool {
1107511142 const tuple = ty.tupleFields();
1107611143 var count: usize = 0;
1107711144 for (tuple.values, 0..) |field_val, i| {
11078 if (field_val.tag() != .unreachable_value or !tuple.types[i].hasRuntimeBits()) continue;
11145 if (field_val.tag() != .unreachable_value or !tuple.types[i].hasRuntimeBits(mod)) continue;
1107911146
1108011147 count += 1;
1108111148 if (count > max_fields_byval) return true;
11082 if (isByRef(tuple.types[i])) return true;
11149 if (isByRef(tuple.types[i], mod)) return true;
1108311150 }
1108411151 return false;
1108511152 }
1108611153 var count: usize = 0;
1108711154 const fields = ty.structFields();
1108811155 for (fields.values()) |field| {
11089 if (field.is_comptime or !field.ty.hasRuntimeBits()) continue;
11156 if (field.is_comptime or !field.ty.hasRuntimeBits(mod)) continue;
1109011157
1109111158 count += 1;
1109211159 if (count > max_fields_byval) return true;
11093 if (isByRef(field.ty)) return true;
11160 if (isByRef(field.ty, mod)) return true;
1109411161 }
1109511162 return false;
1109611163 },
1109711164 .Union => switch (ty.containerLayout()) {
1109811165 .Packed => return false,
11099 else => return ty.hasRuntimeBits(),
11166 else => return ty.hasRuntimeBits(mod),
1110011167 },
1110111168 .ErrorUnion => {
1110211169 const payload_ty = ty.errorUnionPayload();
11103 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
11170 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1110411171 return false;
1110511172 }
1110611173 return true;
......@@ -11108,10 +11175,10 @@ fn isByRef(ty: Type) bool {
1110811175 .Optional => {
1110911176 var buf: Type.Payload.ElemType = undefined;
1111011177 const payload_ty = ty.optionalChild(&buf);
11111 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
11178 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1111211179 return false;
1111311180 }
11114 if (ty.optionalReprIsPayload()) {
11181 if (ty.optionalReprIsPayload(mod)) {
1111511182 return false;
1111611183 }
1111711184 return true;
......@@ -11119,8 +11186,8 @@ fn isByRef(ty: Type) bool {
1111911186 }
1112011187}
1112111188
11122fn isScalar(ty: Type) bool {
11123 return switch (ty.zigTypeTag()) {
11189fn isScalar(mod: *const Module, ty: Type) bool {
11190 return switch (ty.zigTypeTag(mod)) {
1112411191 .Void,
1112511192 .Bool,
1112611193 .NoReturn,
......@@ -11304,12 +11371,12 @@ fn buildAllocaInner(
1130411371 return alloca;
1130511372}
1130611373
11307fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u1 {
11308 return @boolToInt(Type.anyerror.abiAlignment(target) > payload_ty.abiAlignment(target));
11374fn errUnionPayloadOffset(payload_ty: Type, mod: *const Module) u1 {
11375 return @boolToInt(Type.anyerror.abiAlignment(mod) > payload_ty.abiAlignment(mod));
1130911376}
1131011377
11311fn errUnionErrorOffset(payload_ty: Type, target: std.Target) u1 {
11312 return @boolToInt(Type.anyerror.abiAlignment(target) <= payload_ty.abiAlignment(target));
11378fn errUnionErrorOffset(payload_ty: Type, mod: *const Module) u1 {
11379 return @boolToInt(Type.anyerror.abiAlignment(mod) <= payload_ty.abiAlignment(mod));
1131311380}
1131411381
1131511382/// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location
src/codegen/spirv.zig+114-94
......@@ -231,9 +231,10 @@ pub const DeclGen = struct {
231231
232232 /// Fetch the result-id for a previously generated instruction or constant.
233233 fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef {
234 if (self.air.value(inst)) |val| {
234 const mod = self.module;
235 if (self.air.value(inst, mod)) |val| {
235236 const ty = self.air.typeOf(inst);
236 if (ty.zigTypeTag() == .Fn) {
237 if (ty.zigTypeTag(mod) == .Fn) {
237238 const fn_decl_index = switch (val.tag()) {
238239 .extern_fn => val.castTag(.extern_fn).?.data.owner_decl,
239240 .function => val.castTag(.function).?.data.owner_decl,
......@@ -340,8 +341,9 @@ pub const DeclGen = struct {
340341 }
341342
342343 fn arithmeticTypeInfo(self: *DeclGen, ty: Type) !ArithmeticTypeInfo {
344 const mod = self.module;
343345 const target = self.getTarget();
344 return switch (ty.zigTypeTag()) {
346 return switch (ty.zigTypeTag(mod)) {
345347 .Bool => ArithmeticTypeInfo{
346348 .bits = 1, // Doesn't matter for this class.
347349 .is_vector = false,
......@@ -355,7 +357,7 @@ pub const DeclGen = struct {
355357 .class = .float,
356358 },
357359 .Int => blk: {
358 const int_info = ty.intInfo(target);
360 const int_info = ty.intInfo(mod);
359361 // TODO: Maybe it's useful to also return this value.
360362 const maybe_backing_bits = self.backingIntBits(int_info.bits);
361363 break :blk ArithmeticTypeInfo{
......@@ -533,21 +535,22 @@ pub const DeclGen = struct {
533535 }
534536
535537 fn addInt(self: *@This(), ty: Type, val: Value) !void {
536 const target = self.dg.getTarget();
537 const int_info = ty.intInfo(target);
538 const mod = self.dg.module;
539 const int_info = ty.intInfo(mod);
538540 const int_bits = switch (int_info.signedness) {
539 .signed => @bitCast(u64, val.toSignedInt(target)),
540 .unsigned => val.toUnsignedInt(target),
541 .signed => @bitCast(u64, val.toSignedInt(mod)),
542 .unsigned => val.toUnsignedInt(mod),
541543 };
542544
543545 // TODO: Swap endianess if the compiler is big endian.
544 const len = ty.abiSize(target);
546 const len = ty.abiSize(mod);
545547 try self.addBytes(std.mem.asBytes(&int_bits)[0..@intCast(usize, len)]);
546548 }
547549
548550 fn addFloat(self: *@This(), ty: Type, val: Value) !void {
551 const mod = self.dg.module;
549552 const target = self.dg.getTarget();
550 const len = ty.abiSize(target);
553 const len = ty.abiSize(mod);
551554
552555 // TODO: Swap endianess if the compiler is big endian.
553556 switch (ty.floatBits(target)) {
......@@ -607,15 +610,15 @@ pub const DeclGen = struct {
607610 }
608611
609612 fn lower(self: *@This(), ty: Type, val: Value) !void {
610 const target = self.dg.getTarget();
611613 const dg = self.dg;
614 const mod = dg.module;
612615
613616 if (val.isUndef()) {
614 const size = ty.abiSize(target);
617 const size = ty.abiSize(mod);
615618 return try self.addUndef(size);
616619 }
617620
618 switch (ty.zigTypeTag()) {
621 switch (ty.zigTypeTag(mod)) {
619622 .Int => try self.addInt(ty, val),
620623 .Float => try self.addFloat(ty, val),
621624 .Bool => try self.addConstBool(val.toBool()),
......@@ -644,7 +647,7 @@ pub const DeclGen = struct {
644647 const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
645648 try self.addBytes(bytes);
646649 if (ty.sentinel()) |sentinel| {
647 try self.addByte(@intCast(u8, sentinel.toUnsignedInt(target)));
650 try self.addByte(@intCast(u8, sentinel.toUnsignedInt(mod)));
648651 }
649652 },
650653 .bytes => {
......@@ -690,13 +693,13 @@ pub const DeclGen = struct {
690693 const struct_begin = self.size;
691694 const field_vals = val.castTag(.aggregate).?.data;
692695 for (struct_ty.fields.values(), 0..) |field, i| {
693 if (field.is_comptime or !field.ty.hasRuntimeBits()) continue;
696 if (field.is_comptime or !field.ty.hasRuntimeBits(mod)) continue;
694697 try self.lower(field.ty, field_vals[i]);
695698
696699 // Add padding if required.
697700 // TODO: Add to type generation as well?
698701 const unpadded_field_end = self.size - struct_begin;
699 const padded_field_end = ty.structFieldOffset(i + 1, target);
702 const padded_field_end = ty.structFieldOffset(i + 1, mod);
700703 const padding = padded_field_end - unpadded_field_end;
701704 try self.addUndef(padding);
702705 }
......@@ -705,13 +708,13 @@ pub const DeclGen = struct {
705708 .Optional => {
706709 var opt_buf: Type.Payload.ElemType = undefined;
707710 const payload_ty = ty.optionalChild(&opt_buf);
708 const has_payload = !val.isNull();
709 const abi_size = ty.abiSize(target);
711 const has_payload = !val.isNull(mod);
712 const abi_size = ty.abiSize(mod);
710713
711 if (!payload_ty.hasRuntimeBits()) {
714 if (!payload_ty.hasRuntimeBits(mod)) {
712715 try self.addConstBool(has_payload);
713716 return;
714 } else if (ty.optionalReprIsPayload()) {
717 } else if (ty.optionalReprIsPayload(mod)) {
715718 // Optional representation is a nullable pointer or slice.
716719 if (val.castTag(.opt_payload)) |payload| {
717720 try self.lower(payload_ty, payload.data);
......@@ -729,7 +732,7 @@ pub const DeclGen = struct {
729732
730733 // Subtract 1 for @sizeOf(bool).
731734 // TODO: Make this not hardcoded.
732 const payload_size = payload_ty.abiSize(target);
735 const payload_size = payload_ty.abiSize(mod);
733736 const padding = abi_size - payload_size - 1;
734737
735738 if (val.castTag(.opt_payload)) |payload| {
......@@ -744,14 +747,13 @@ pub const DeclGen = struct {
744747 var int_val_buffer: Value.Payload.U64 = undefined;
745748 const int_val = val.enumToInt(ty, &int_val_buffer);
746749
747 var int_ty_buffer: Type.Payload.Bits = undefined;
748 const int_ty = ty.intTagType(&int_ty_buffer);
750 const int_ty = ty.intTagType();
749751
750752 try self.lower(int_ty, int_val);
751753 },
752754 .Union => {
753755 const tag_and_val = val.castTag(.@"union").?.data;
754 const layout = ty.unionGetLayout(target);
756 const layout = ty.unionGetLayout(mod);
755757
756758 if (layout.payload_size == 0) {
757759 return try self.lower(ty.unionTagTypeSafety().?, tag_and_val.tag);
......@@ -772,9 +774,9 @@ pub const DeclGen = struct {
772774 try self.lower(ty.unionTagTypeSafety().?, tag_and_val.tag);
773775 }
774776
775 const active_field_size = if (active_field_ty.hasRuntimeBitsIgnoreComptime()) blk: {
777 const active_field_size = if (active_field_ty.hasRuntimeBitsIgnoreComptime(mod)) blk: {
776778 try self.lower(active_field_ty, tag_and_val.val);
777 break :blk active_field_ty.abiSize(target);
779 break :blk active_field_ty.abiSize(mod);
778780 } else 0;
779781
780782 const payload_padding_len = layout.payload_size - active_field_size;
......@@ -808,9 +810,9 @@ pub const DeclGen = struct {
808810 return try self.lower(Type.anyerror, error_val);
809811 }
810812
811 const payload_size = payload_ty.abiSize(target);
812 const error_size = Type.anyerror.abiAlignment(target);
813 const ty_size = ty.abiSize(target);
813 const payload_size = payload_ty.abiSize(mod);
814 const error_size = Type.anyerror.abiAlignment(mod);
815 const ty_size = ty.abiSize(mod);
814816 const padding = ty_size - payload_size - error_size;
815817 const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.initTag(.undef);
816818
......@@ -886,7 +888,7 @@ pub const DeclGen = struct {
886888 // .id_result = result_id,
887889 // .storage_class = storage_class,
888890 // });
889 // } else if (ty.abiSize(target) == 0) {
891 // } else if (ty.abiSize(mod) == 0) {
890892 // // Special case: if the type has no size, then return an undefined pointer.
891893 // return try section.emit(self.spv.gpa, .OpUndef, .{
892894 // .id_result_type = self.typeId(ptr_ty_ref),
......@@ -968,6 +970,7 @@ pub const DeclGen = struct {
968970 /// is then loaded using OpLoad. Such values are loaded into the UniformConstant storage class by default.
969971 /// This function should only be called during function code generation.
970972 fn constant(self: *DeclGen, ty: Type, val: Value, repr: Repr) !IdRef {
973 const mod = self.module;
971974 const target = self.getTarget();
972975 const result_ty_ref = try self.resolveType(ty, repr);
973976
......@@ -977,12 +980,12 @@ pub const DeclGen = struct {
977980 return self.spv.constUndef(result_ty_ref);
978981 }
979982
980 switch (ty.zigTypeTag()) {
983 switch (ty.zigTypeTag(mod)) {
981984 .Int => {
982 if (ty.isSignedInt()) {
983 return try self.spv.constInt(result_ty_ref, val.toSignedInt(target));
985 if (ty.isSignedInt(mod)) {
986 return try self.spv.constInt(result_ty_ref, val.toSignedInt(mod));
984987 } else {
985 return try self.spv.constInt(result_ty_ref, val.toUnsignedInt(target));
988 return try self.spv.constInt(result_ty_ref, val.toUnsignedInt(mod));
986989 }
987990 },
988991 .Bool => switch (repr) {
......@@ -1037,7 +1040,7 @@ pub const DeclGen = struct {
10371040 // The value cannot be generated directly, so generate it as an indirect constant,
10381041 // and then perform an OpLoad.
10391042 const result_id = self.spv.allocId();
1040 const alignment = ty.abiAlignment(target);
1043 const alignment = ty.abiAlignment(mod);
10411044 const spv_decl_index = try self.spv.allocDecl(.global);
10421045
10431046 try self.lowerIndirectConstant(
......@@ -1114,8 +1117,8 @@ pub const DeclGen = struct {
11141117 /// NOTE: When the active field is set to something other than the most aligned field, the
11151118 /// resulting struct will be *underaligned*.
11161119 fn resolveUnionType(self: *DeclGen, ty: Type, maybe_active_field: ?usize) !CacheRef {
1117 const target = self.getTarget();
1118 const layout = ty.unionGetLayout(target);
1120 const mod = self.module;
1121 const layout = ty.unionGetLayout(mod);
11191122 const union_ty = ty.cast(Type.Payload.Union).?.data;
11201123
11211124 if (union_ty.layout == .Packed) {
......@@ -1143,11 +1146,11 @@ pub const DeclGen = struct {
11431146 const active_field = maybe_active_field orelse layout.most_aligned_field;
11441147 const active_field_ty = union_ty.fields.values()[active_field].ty;
11451148
1146 const active_field_size = if (active_field_ty.hasRuntimeBitsIgnoreComptime()) blk: {
1149 const active_field_size = if (active_field_ty.hasRuntimeBitsIgnoreComptime(mod)) blk: {
11471150 const active_payload_ty_ref = try self.resolveType(active_field_ty, .indirect);
11481151 member_types.appendAssumeCapacity(active_payload_ty_ref);
11491152 member_names.appendAssumeCapacity(try self.spv.resolveString("payload"));
1150 break :blk active_field_ty.abiSize(target);
1153 break :blk active_field_ty.abiSize(mod);
11511154 } else 0;
11521155
11531156 const payload_padding_len = layout.payload_size - active_field_size;
......@@ -1177,21 +1180,21 @@ pub const DeclGen = struct {
11771180
11781181 /// Turn a Zig type into a SPIR-V Type, and return a reference to it.
11791182 fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!CacheRef {
1183 const mod = self.module;
11801184 log.debug("resolveType: ty = {}", .{ty.fmt(self.module)});
11811185 const target = self.getTarget();
1182 switch (ty.zigTypeTag()) {
1186 switch (ty.zigTypeTag(mod)) {
11831187 .Void, .NoReturn => return try self.spv.resolve(.void_type),
11841188 .Bool => switch (repr) {
11851189 .direct => return try self.spv.resolve(.bool_type),
11861190 .indirect => return try self.intType(.unsigned, 1),
11871191 },
11881192 .Int => {
1189 const int_info = ty.intInfo(target);
1193 const int_info = ty.intInfo(mod);
11901194 return try self.intType(int_info.signedness, int_info.bits);
11911195 },
11921196 .Enum => {
1193 var buffer: Type.Payload.Bits = undefined;
1194 const tag_ty = ty.intTagType(&buffer);
1197 const tag_ty = ty.intTagType();
11951198 return self.resolveType(tag_ty, repr);
11961199 },
11971200 .Float => {
......@@ -1290,7 +1293,7 @@ pub const DeclGen = struct {
12901293 var member_index: usize = 0;
12911294 for (tuple.types, 0..) |field_ty, i| {
12921295 const field_val = tuple.values[i];
1293 if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue;
1296 if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits(mod)) continue;
12941297
12951298 member_types[member_index] = try self.resolveType(field_ty, .indirect);
12961299 member_index += 1;
......@@ -1315,7 +1318,7 @@ pub const DeclGen = struct {
13151318
13161319 var member_index: usize = 0;
13171320 for (struct_ty.fields.values(), 0..) |field, i| {
1318 if (field.is_comptime or !field.ty.hasRuntimeBits()) continue;
1321 if (field.is_comptime or !field.ty.hasRuntimeBits(mod)) continue;
13191322
13201323 member_types[member_index] = try self.resolveType(field.ty, .indirect);
13211324 member_names[member_index] = try self.spv.resolveString(struct_ty.fields.keys()[i]);
......@@ -1334,7 +1337,7 @@ pub const DeclGen = struct {
13341337 .Optional => {
13351338 var buf: Type.Payload.ElemType = undefined;
13361339 const payload_ty = ty.optionalChild(&buf);
1337 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1340 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
13381341 // Just use a bool.
13391342 // Note: Always generate the bool with indirect format, to save on some sanity
13401343 // Perform the conversion to a direct bool when the field is extracted.
......@@ -1342,7 +1345,7 @@ pub const DeclGen = struct {
13421345 }
13431346
13441347 const payload_ty_ref = try self.resolveType(payload_ty, .indirect);
1345 if (ty.optionalReprIsPayload()) {
1348 if (ty.optionalReprIsPayload(mod)) {
13461349 // Optional is actually a pointer or a slice.
13471350 return payload_ty_ref;
13481351 }
......@@ -1445,14 +1448,14 @@ pub const DeclGen = struct {
14451448 };
14461449
14471450 fn errorUnionLayout(self: *DeclGen, payload_ty: Type) ErrorUnionLayout {
1448 const target = self.getTarget();
1451 const mod = self.module;
14491452
1450 const error_align = Type.anyerror.abiAlignment(target);
1451 const payload_align = payload_ty.abiAlignment(target);
1453 const error_align = Type.anyerror.abiAlignment(mod);
1454 const payload_align = payload_ty.abiAlignment(mod);
14521455
14531456 const error_first = error_align > payload_align;
14541457 return .{
1455 .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(),
1458 .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod),
14561459 .error_first = error_first,
14571460 };
14581461 }
......@@ -1529,14 +1532,15 @@ pub const DeclGen = struct {
15291532 }
15301533
15311534 fn genDecl(self: *DeclGen) !void {
1532 const decl = self.module.declPtr(self.decl_index);
1535 const mod = self.module;
1536 const decl = mod.declPtr(self.decl_index);
15331537 const spv_decl_index = try self.resolveDecl(self.decl_index);
15341538
15351539 const decl_id = self.spv.declPtr(spv_decl_index).result_id;
15361540 log.debug("genDecl: id = {}, index = {}, name = {s}", .{ decl_id.id, @enumToInt(spv_decl_index), decl.name });
15371541
15381542 if (decl.val.castTag(.function)) |_| {
1539 assert(decl.ty.zigTypeTag() == .Fn);
1543 assert(decl.ty.zigTypeTag(mod) == .Fn);
15401544 const prototype_id = try self.resolveTypeId(decl.ty);
15411545 try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{
15421546 .id_result_type = try self.resolveTypeId(decl.ty.fnReturnType()),
......@@ -1634,7 +1638,8 @@ pub const DeclGen = struct {
16341638 /// Convert representation from indirect (in memory) to direct (in 'register')
16351639 /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct).
16361640 fn convertToDirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {
1637 return switch (ty.zigTypeTag()) {
1641 const mod = self.module;
1642 return switch (ty.zigTypeTag(mod)) {
16381643 .Bool => blk: {
16391644 const direct_bool_ty_ref = try self.resolveType(ty, .direct);
16401645 const indirect_bool_ty_ref = try self.resolveType(ty, .indirect);
......@@ -1655,7 +1660,8 @@ pub const DeclGen = struct {
16551660 /// Convert representation from direct (in 'register) to direct (in memory)
16561661 /// This converts the argument type from resolveType(ty, .direct) to resolveType(ty, .indirect).
16571662 fn convertToIndirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {
1658 return switch (ty.zigTypeTag()) {
1663 const mod = self.module;
1664 return switch (ty.zigTypeTag(mod)) {
16591665 .Bool => blk: {
16601666 const indirect_bool_ty_ref = try self.resolveType(ty, .indirect);
16611667 break :blk self.boolToInt(indirect_bool_ty_ref, operand_id);
......@@ -2056,6 +2062,7 @@ pub const DeclGen = struct {
20562062 }
20572063
20582064 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2065 const mod = self.module;
20592066 if (self.liveness.isUnused(inst)) return null;
20602067 const ty = self.air.typeOfIndex(inst);
20612068 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
......@@ -2083,7 +2090,7 @@ pub const DeclGen = struct {
20832090 if (elem.isUndef()) {
20842091 self.func.body.writeOperand(spec.LiteralInteger, 0xFFFF_FFFF);
20852092 } else {
2086 const int = elem.toSignedInt(self.getTarget());
2093 const int = elem.toSignedInt(mod);
20872094 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int + a_len);
20882095 self.func.body.writeOperand(spec.LiteralInteger, unsigned);
20892096 }
......@@ -2189,13 +2196,13 @@ pub const DeclGen = struct {
21892196 lhs_id: IdRef,
21902197 rhs_id: IdRef,
21912198 ) !IdRef {
2199 const mod = self.module;
21922200 var cmp_lhs_id = lhs_id;
21932201 var cmp_rhs_id = rhs_id;
21942202 const opcode: Opcode = opcode: {
2195 var int_buffer: Type.Payload.Bits = undefined;
2196 const op_ty = switch (ty.zigTypeTag()) {
2203 const op_ty = switch (ty.zigTypeTag(mod)) {
21972204 .Int, .Bool, .Float => ty,
2198 .Enum => ty.intTagType(&int_buffer),
2205 .Enum => ty.intTagType(),
21992206 .ErrorSet => Type.u16,
22002207 .Pointer => blk: {
22012208 // Note that while SPIR-V offers OpPtrEqual and OpPtrNotEqual, they are
......@@ -2303,13 +2310,14 @@ pub const DeclGen = struct {
23032310 src_ty: Type,
23042311 src_id: IdRef,
23052312 ) !IdRef {
2313 const mod = self.module;
23062314 const dst_ty_ref = try self.resolveType(dst_ty, .direct);
23072315 const result_id = self.spv.allocId();
23082316
23092317 // TODO: Some more cases are missing here
23102318 // See fn bitCast in llvm.zig
23112319
2312 if (src_ty.zigTypeTag() == .Int and dst_ty.isPtrAtRuntime()) {
2320 if (src_ty.zigTypeTag(mod) == .Int and dst_ty.isPtrAtRuntime(mod)) {
23132321 try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
23142322 .id_result_type = self.typeId(dst_ty_ref),
23152323 .id_result = result_id,
......@@ -2342,8 +2350,8 @@ pub const DeclGen = struct {
23422350 const dest_ty = self.air.typeOfIndex(inst);
23432351 const dest_ty_id = try self.resolveTypeId(dest_ty);
23442352
2345 const target = self.getTarget();
2346 const dest_info = dest_ty.intInfo(target);
2353 const mod = self.module;
2354 const dest_info = dest_ty.intInfo(mod);
23472355
23482356 // TODO: Masking?
23492357
......@@ -2485,8 +2493,9 @@ pub const DeclGen = struct {
24852493 }
24862494
24872495 fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {
2496 const mod = self.module;
24882497 // Construct new pointer type for the resulting pointer
2489 const elem_ty = ptr_ty.elemType2(); // use elemType() so that we get T for *[N]T.
2498 const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T.
24902499 const elem_ty_ref = try self.resolveType(elem_ty, .direct);
24912500 const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, spvStorageClass(ptr_ty.ptrAddressSpace()));
24922501 if (ptr_ty.isSinglePointer()) {
......@@ -2502,12 +2511,13 @@ pub const DeclGen = struct {
25022511 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
25032512 if (self.liveness.isUnused(inst)) return null;
25042513
2514 const mod = self.module;
25052515 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
25062516 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
25072517 const ptr_ty = self.air.typeOf(bin_op.lhs);
25082518 const elem_ty = ptr_ty.childType();
25092519 // TODO: Make this return a null ptr or something
2510 if (!elem_ty.hasRuntimeBitsIgnoreComptime()) return null;
2520 if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
25112521
25122522 const ptr_id = try self.resolve(bin_op.lhs);
25132523 const index_id = try self.resolve(bin_op.rhs);
......@@ -2536,8 +2546,8 @@ pub const DeclGen = struct {
25362546 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
25372547 const un_ty = self.air.typeOf(ty_op.operand);
25382548
2539 const target = self.module.getTarget();
2540 const layout = un_ty.unionGetLayout(target);
2549 const mod = self.module;
2550 const layout = un_ty.unionGetLayout(mod);
25412551 if (layout.tag_size == 0) return null;
25422552
25432553 const union_handle = try self.resolve(ty_op.operand);
......@@ -2551,6 +2561,7 @@ pub const DeclGen = struct {
25512561 fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
25522562 if (self.liveness.isUnused(inst)) return null;
25532563
2564 const mod = self.module;
25542565 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
25552566 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
25562567
......@@ -2559,9 +2570,9 @@ pub const DeclGen = struct {
25592570 const field_index = struct_field.field_index;
25602571 const field_ty = struct_ty.structFieldType(field_index);
25612572
2562 if (!field_ty.hasRuntimeBitsIgnoreComptime()) return null;
2573 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
25632574
2564 assert(struct_ty.zigTypeTag() == .Struct); // Cannot do unions yet.
2575 assert(struct_ty.zigTypeTag(mod) == .Struct); // Cannot do unions yet.
25652576
25662577 return try self.extractField(field_ty, object_id, field_index);
25672578 }
......@@ -2573,8 +2584,9 @@ pub const DeclGen = struct {
25732584 object_ptr: IdRef,
25742585 field_index: u32,
25752586 ) !?IdRef {
2587 const mod = self.module;
25762588 const object_ty = object_ptr_ty.childType();
2577 switch (object_ty.zigTypeTag()) {
2589 switch (object_ty.zigTypeTag(mod)) {
25782590 .Struct => switch (object_ty.containerLayout()) {
25792591 .Packed => unreachable, // TODO
25802592 else => {
......@@ -2667,6 +2679,7 @@ pub const DeclGen = struct {
26672679 // the current block by first generating the code of the block, then a label, and then generate the rest of the current
26682680 // ir.Block in a different SPIR-V block.
26692681
2682 const mod = self.module;
26702683 const label_id = self.spv.allocId();
26712684
26722685 // 4 chosen as arbitrary initial capacity.
......@@ -2690,7 +2703,7 @@ pub const DeclGen = struct {
26902703 try self.beginSpvBlock(label_id);
26912704
26922705 // If this block didn't produce a value, simply return here.
2693 if (!ty.hasRuntimeBitsIgnoreComptime())
2706 if (!ty.hasRuntimeBitsIgnoreComptime(mod))
26942707 return null;
26952708
26962709 // Combine the result from the blocks using the Phi instruction.
......@@ -2716,7 +2729,8 @@ pub const DeclGen = struct {
27162729 const block = self.blocks.get(br.block_inst).?;
27172730 const operand_ty = self.air.typeOf(br.operand);
27182731
2719 if (operand_ty.hasRuntimeBits()) {
2732 const mod = self.module;
2733 if (operand_ty.hasRuntimeBits(mod)) {
27202734 const operand_id = try self.resolve(br.operand);
27212735 // current_block_label_id should not be undefined here, lest there is a br or br_void in the function's body.
27222736 try block.incoming_blocks.append(self.gpa, .{ .src_label_id = self.current_block_label_id, .break_value_id = operand_id });
......@@ -2771,13 +2785,14 @@ pub const DeclGen = struct {
27712785 }
27722786
27732787 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
2788 const mod = self.module;
27742789 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
27752790 const ptr_ty = self.air.typeOf(bin_op.lhs);
27762791 const ptr = try self.resolve(bin_op.lhs);
27772792 const value = try self.resolve(bin_op.rhs);
27782793 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
27792794
2780 const val_is_undef = if (self.air.value(bin_op.rhs)) |val| val.isUndefDeep() else false;
2795 const val_is_undef = if (self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false;
27812796 if (val_is_undef) {
27822797 const undef = try self.spv.constUndef(ptr_ty_ref);
27832798 try self.store(ptr_ty, ptr, undef);
......@@ -2805,7 +2820,8 @@ pub const DeclGen = struct {
28052820 fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {
28062821 const operand = self.air.instructions.items(.data)[inst].un_op;
28072822 const operand_ty = self.air.typeOf(operand);
2808 if (operand_ty.hasRuntimeBits()) {
2823 const mod = self.module;
2824 if (operand_ty.hasRuntimeBits(mod)) {
28092825 const operand_id = try self.resolve(operand);
28102826 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = operand_id });
28112827 } else {
......@@ -2814,11 +2830,12 @@ pub const DeclGen = struct {
28142830 }
28152831
28162832 fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {
2833 const mod = self.module;
28172834 const un_op = self.air.instructions.items(.data)[inst].un_op;
28182835 const ptr_ty = self.air.typeOf(un_op);
28192836 const ret_ty = ptr_ty.childType();
28202837
2821 if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {
2838 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
28222839 try self.func.body.emit(self.spv.gpa, .OpReturn, {});
28232840 return;
28242841 }
......@@ -2946,6 +2963,7 @@ pub const DeclGen = struct {
29462963 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_null, is_non_null }) !?IdRef {
29472964 if (self.liveness.isUnused(inst)) return null;
29482965
2966 const mod = self.module;
29492967 const un_op = self.air.instructions.items(.data)[inst].un_op;
29502968 const operand_id = try self.resolve(un_op);
29512969 const optional_ty = self.air.typeOf(un_op);
......@@ -2955,7 +2973,7 @@ pub const DeclGen = struct {
29552973
29562974 const bool_ty_ref = try self.resolveType(Type.bool, .direct);
29572975
2958 if (optional_ty.optionalReprIsPayload()) {
2976 if (optional_ty.optionalReprIsPayload(mod)) {
29592977 // Pointer payload represents nullability: pointer or slice.
29602978
29612979 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
......@@ -2985,7 +3003,7 @@ pub const DeclGen = struct {
29853003 return result_id;
29863004 }
29873005
2988 const is_non_null_id = if (optional_ty.hasRuntimeBitsIgnoreComptime())
3006 const is_non_null_id = if (optional_ty.hasRuntimeBitsIgnoreComptime(mod))
29893007 try self.extractField(Type.bool, operand_id, 1)
29903008 else
29913009 // Optional representation is bool indicating whether the optional is set
......@@ -3009,14 +3027,15 @@ pub const DeclGen = struct {
30093027 fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
30103028 if (self.liveness.isUnused(inst)) return null;
30113029
3030 const mod = self.module;
30123031 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
30133032 const operand_id = try self.resolve(ty_op.operand);
30143033 const optional_ty = self.air.typeOf(ty_op.operand);
30153034 const payload_ty = self.air.typeOfIndex(inst);
30163035
3017 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return null;
3036 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
30183037
3019 if (optional_ty.optionalReprIsPayload()) {
3038 if (optional_ty.optionalReprIsPayload(mod)) {
30203039 return operand_id;
30213040 }
30223041
......@@ -3026,16 +3045,17 @@ pub const DeclGen = struct {
30263045 fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
30273046 if (self.liveness.isUnused(inst)) return null;
30283047
3048 const mod = self.module;
30293049 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
30303050 const payload_ty = self.air.typeOf(ty_op.operand);
30313051
3032 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3052 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
30333053 return try self.constBool(true, .direct);
30343054 }
30353055
30363056 const operand_id = try self.resolve(ty_op.operand);
30373057 const optional_ty = self.air.typeOfIndex(inst);
3038 if (optional_ty.optionalReprIsPayload()) {
3058 if (optional_ty.optionalReprIsPayload(mod)) {
30393059 return operand_id;
30403060 }
30413061
......@@ -3045,30 +3065,29 @@ pub const DeclGen = struct {
30453065 }
30463066
30473067 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {
3048 const target = self.getTarget();
3068 const mod = self.module;
30493069 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
30503070 const cond = try self.resolve(pl_op.operand);
30513071 const cond_ty = self.air.typeOf(pl_op.operand);
30523072 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
30533073
3054 const cond_words: u32 = switch (cond_ty.zigTypeTag()) {
3074 const cond_words: u32 = switch (cond_ty.zigTypeTag(mod)) {
30553075 .Int => blk: {
3056 const bits = cond_ty.intInfo(target).bits;
3076 const bits = cond_ty.intInfo(mod).bits;
30573077 const backing_bits = self.backingIntBits(bits) orelse {
30583078 return self.todo("implement composite int switch", .{});
30593079 };
30603080 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
30613081 },
30623082 .Enum => blk: {
3063 var buffer: Type.Payload.Bits = undefined;
3064 const int_ty = cond_ty.intTagType(&buffer);
3065 const int_info = int_ty.intInfo(target);
3083 const int_ty = cond_ty.intTagType();
3084 const int_info = int_ty.intInfo(mod);
30663085 const backing_bits = self.backingIntBits(int_info.bits) orelse {
30673086 return self.todo("implement composite int switch", .{});
30683087 };
30693088 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
30703089 },
3071 else => return self.todo("implement switch for type {s}", .{@tagName(cond_ty.zigTypeTag())}), // TODO: Figure out which types apply here, and work around them as we can only do integers.
3090 else => return self.todo("implement switch for type {s}", .{@tagName(cond_ty.zigTypeTag(mod))}), // TODO: Figure out which types apply here, and work around them as we can only do integers.
30723091 };
30733092
30743093 const num_cases = switch_br.data.cases_len;
......@@ -3112,15 +3131,15 @@ pub const DeclGen = struct {
31123131 const label = IdRef{ .id = first_case_label.id + case_i };
31133132
31143133 for (items) |item| {
3115 const value = self.air.value(item) orelse {
3134 const value = self.air.value(item, mod) orelse {
31163135 return self.todo("switch on runtime value???", .{});
31173136 };
3118 const int_val = switch (cond_ty.zigTypeTag()) {
3119 .Int => if (cond_ty.isSignedInt()) @bitCast(u64, value.toSignedInt(target)) else value.toUnsignedInt(target),
3137 const int_val = switch (cond_ty.zigTypeTag(mod)) {
3138 .Int => if (cond_ty.isSignedInt(mod)) @bitCast(u64, value.toSignedInt(mod)) else value.toUnsignedInt(mod),
31203139 .Enum => blk: {
31213140 var int_buffer: Value.Payload.U64 = undefined;
31223141 // TODO: figure out of cond_ty is correct (something with enum literals)
3123 break :blk value.enumToInt(cond_ty, &int_buffer).toUnsignedInt(target); // TODO: composite integer constants
3142 break :blk value.enumToInt(cond_ty, &int_buffer).toUnsignedInt(mod); // TODO: composite integer constants
31243143 },
31253144 else => unreachable,
31263145 };
......@@ -3294,11 +3313,12 @@ pub const DeclGen = struct {
32943313 fn airCall(self: *DeclGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !?IdRef {
32953314 _ = modifier;
32963315
3316 const mod = self.module;
32973317 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
32983318 const extra = self.air.extraData(Air.Call, pl_op.payload);
32993319 const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
33003320 const callee_ty = self.air.typeOf(pl_op.operand);
3301 const zig_fn_ty = switch (callee_ty.zigTypeTag()) {
3321 const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
33023322 .Fn => callee_ty,
33033323 .Pointer => return self.fail("cannot call function pointers", .{}),
33043324 else => unreachable,
......@@ -3320,7 +3340,7 @@ pub const DeclGen = struct {
33203340 // temporary params buffer.
33213341 const arg_id = try self.resolve(arg);
33223342 const arg_ty = self.air.typeOf(arg);
3323 if (!arg_ty.hasRuntimeBitsIgnoreComptime()) continue;
3343 if (!arg_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
33243344
33253345 params[n_params] = arg_id;
33263346 n_params += 1;
......@@ -3337,7 +3357,7 @@ pub const DeclGen = struct {
33373357 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});
33383358 }
33393359
3340 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime()) {
3360 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(mod)) {
33413361 return null;
33423362 }
33433363
src/link/Coff.zig+4-3
......@@ -1123,7 +1123,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
11231123 },
11241124 };
11251125
1126 const required_alignment = tv.ty.abiAlignment(self.base.options.target);
1126 const required_alignment = tv.ty.abiAlignment(mod);
11271127 const atom = self.getAtomPtr(atom_index);
11281128 atom.size = @intCast(u32, code.len);
11291129 atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, required_alignment);
......@@ -1299,7 +1299,8 @@ pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.
12991299fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 {
13001300 const decl = self.base.options.module.?.declPtr(decl_index);
13011301 const ty = decl.ty;
1302 const zig_ty = ty.zigTypeTag();
1302 const mod = self.base.options.module.?;
1303 const zig_ty = ty.zigTypeTag(mod);
13031304 const val = decl.val;
13041305 const index: u16 = blk: {
13051306 if (val.isUndefDeep()) {
......@@ -1330,7 +1331,7 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []u8, comple
13301331 defer gpa.free(decl_name);
13311332
13321333 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
1333 const required_alignment = decl.getAlignment(self.base.options.target);
1334 const required_alignment = decl.getAlignment(mod);
13341335
13351336 const decl_metadata = self.decls.get(decl_index).?;
13361337 const atom_index = decl_metadata.atom;
src/link/Dwarf.zig+52-51
......@@ -169,16 +169,16 @@ pub const DeclState = struct {
169169
170170 fn addDbgInfoType(
171171 self: *DeclState,
172 module: *Module,
172 mod: *Module,
173173 atom_index: Atom.Index,
174174 ty: Type,
175175 ) error{OutOfMemory}!void {
176176 const arena = self.abbrev_type_arena.allocator();
177177 const dbg_info_buffer = &self.dbg_info;
178 const target = module.getTarget();
178 const target = mod.getTarget();
179179 const target_endian = target.cpu.arch.endian();
180180
181 switch (ty.zigTypeTag()) {
181 switch (ty.zigTypeTag(mod)) {
182182 .NoReturn => unreachable,
183183 .Void => {
184184 try dbg_info_buffer.append(@enumToInt(AbbrevKind.pad1));
......@@ -189,12 +189,12 @@ pub const DeclState = struct {
189189 // DW.AT.encoding, DW.FORM.data1
190190 dbg_info_buffer.appendAssumeCapacity(DW.ATE.boolean);
191191 // DW.AT.byte_size, DW.FORM.udata
192 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target));
192 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));
193193 // DW.AT.name, DW.FORM.string
194 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
194 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
195195 },
196196 .Int => {
197 const info = ty.intInfo(target);
197 const info = ty.intInfo(mod);
198198 try dbg_info_buffer.ensureUnusedCapacity(12);
199199 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type));
200200 // DW.AT.encoding, DW.FORM.data1
......@@ -203,20 +203,20 @@ pub const DeclState = struct {
203203 .unsigned => DW.ATE.unsigned,
204204 });
205205 // DW.AT.byte_size, DW.FORM.udata
206 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target));
206 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));
207207 // DW.AT.name, DW.FORM.string
208 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
208 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
209209 },
210210 .Optional => {
211 if (ty.isPtrLikeOptional()) {
211 if (ty.isPtrLikeOptional(mod)) {
212212 try dbg_info_buffer.ensureUnusedCapacity(12);
213213 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type));
214214 // DW.AT.encoding, DW.FORM.data1
215215 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);
216216 // DW.AT.byte_size, DW.FORM.udata
217 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target));
217 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));
218218 // DW.AT.name, DW.FORM.string
219 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
219 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
220220 } else {
221221 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }
222222 var buf = try arena.create(Type.Payload.ElemType);
......@@ -224,10 +224,10 @@ pub const DeclState = struct {
224224 // DW.AT.structure_type
225225 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
226226 // DW.AT.byte_size, DW.FORM.udata
227 const abi_size = ty.abiSize(target);
227 const abi_size = ty.abiSize(mod);
228228 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
229229 // DW.AT.name, DW.FORM.string
230 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
230 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
231231 // DW.AT.member
232232 try dbg_info_buffer.ensureUnusedCapacity(7);
233233 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
......@@ -251,7 +251,7 @@ pub const DeclState = struct {
251251 try dbg_info_buffer.resize(index + 4);
252252 try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(u32, index));
253253 // DW.AT.data_member_location, DW.FORM.udata
254 const offset = abi_size - payload_ty.abiSize(target);
254 const offset = abi_size - payload_ty.abiSize(mod);
255255 try leb128.writeULEB128(dbg_info_buffer.writer(), offset);
256256 // DW.AT.structure_type delimit children
257257 try dbg_info_buffer.append(0);
......@@ -266,9 +266,9 @@ pub const DeclState = struct {
266266 try dbg_info_buffer.ensureUnusedCapacity(2);
267267 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_type));
268268 // DW.AT.byte_size, DW.FORM.udata
269 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target));
269 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));
270270 // DW.AT.name, DW.FORM.string
271 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
271 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
272272 // DW.AT.member
273273 try dbg_info_buffer.ensureUnusedCapacity(5);
274274 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
......@@ -311,7 +311,7 @@ pub const DeclState = struct {
311311 // DW.AT.array_type
312312 try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_type));
313313 // DW.AT.name, DW.FORM.string
314 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
314 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
315315 // DW.AT.type, DW.FORM.ref4
316316 var index = dbg_info_buffer.items.len;
317317 try dbg_info_buffer.resize(index + 4);
......@@ -332,12 +332,12 @@ pub const DeclState = struct {
332332 // DW.AT.structure_type
333333 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
334334 // DW.AT.byte_size, DW.FORM.udata
335 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target));
335 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));
336336
337337 switch (ty.tag()) {
338338 .tuple, .anon_struct => {
339339 // DW.AT.name, DW.FORM.string
340 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)});
340 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
341341
342342 const fields = ty.tupleFields();
343343 for (fields.types, 0..) |field, field_index| {
......@@ -350,13 +350,13 @@ pub const DeclState = struct {
350350 try dbg_info_buffer.resize(index + 4);
351351 try self.addTypeRelocGlobal(atom_index, field, @intCast(u32, index));
352352 // DW.AT.data_member_location, DW.FORM.udata
353 const field_off = ty.structFieldOffset(field_index, target);
353 const field_off = ty.structFieldOffset(field_index, mod);
354354 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
355355 }
356356 },
357357 else => {
358358 // DW.AT.name, DW.FORM.string
359 const struct_name = try ty.nameAllocArena(arena, module);
359 const struct_name = try ty.nameAllocArena(arena, mod);
360360 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);
361361 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);
362362 dbg_info_buffer.appendAssumeCapacity(0);
......@@ -370,7 +370,7 @@ pub const DeclState = struct {
370370 const fields = ty.structFields();
371371 for (fields.keys(), 0..) |field_name, field_index| {
372372 const field = fields.get(field_name).?;
373 if (!field.ty.hasRuntimeBits()) continue;
373 if (!field.ty.hasRuntimeBits(mod)) continue;
374374 // DW.AT.member
375375 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
376376 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
......@@ -382,7 +382,7 @@ pub const DeclState = struct {
382382 try dbg_info_buffer.resize(index + 4);
383383 try self.addTypeRelocGlobal(atom_index, field.ty, @intCast(u32, index));
384384 // DW.AT.data_member_location, DW.FORM.udata
385 const field_off = ty.structFieldOffset(field_index, target);
385 const field_off = ty.structFieldOffset(field_index, mod);
386386 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
387387 }
388388 },
......@@ -395,9 +395,9 @@ pub const DeclState = struct {
395395 // DW.AT.enumeration_type
396396 try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type));
397397 // DW.AT.byte_size, DW.FORM.udata
398 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target));
398 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));
399399 // DW.AT.name, DW.FORM.string
400 const enum_name = try ty.nameAllocArena(arena, module);
400 const enum_name = try ty.nameAllocArena(arena, mod);
401401 try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1);
402402 dbg_info_buffer.appendSliceAssumeCapacity(enum_name);
403403 dbg_info_buffer.appendAssumeCapacity(0);
......@@ -424,7 +424,7 @@ pub const DeclState = struct {
424424 // See https://github.com/ziglang/zig/issues/645
425425 var int_buffer: Value.Payload.U64 = undefined;
426426 const field_int_val = value.enumToInt(ty, &int_buffer);
427 break :value @bitCast(u64, field_int_val.toSignedInt(target));
427 break :value @bitCast(u64, field_int_val.toSignedInt(mod));
428428 } else @intCast(u64, field_i);
429429 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian);
430430 }
......@@ -433,12 +433,12 @@ pub const DeclState = struct {
433433 try dbg_info_buffer.append(0);
434434 },
435435 .Union => {
436 const layout = ty.unionGetLayout(target);
436 const layout = ty.unionGetLayout(mod);
437437 const union_obj = ty.cast(Type.Payload.Union).?.data;
438438 const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0;
439439 const tag_offset = if (layout.tag_align >= layout.payload_align) 0 else layout.payload_size;
440440 const is_tagged = layout.tag_size > 0;
441 const union_name = try ty.nameAllocArena(arena, module);
441 const union_name = try ty.nameAllocArena(arena, mod);
442442
443443 // TODO this is temporary to match current state of unions in Zig - we don't yet have
444444 // safety checks implemented meaning the implicit tag is not yet stored and generated
......@@ -481,7 +481,7 @@ pub const DeclState = struct {
481481 const fields = ty.unionFields();
482482 for (fields.keys()) |field_name| {
483483 const field = fields.get(field_name).?;
484 if (!field.ty.hasRuntimeBits()) continue;
484 if (!field.ty.hasRuntimeBits(mod)) continue;
485485 // DW.AT.member
486486 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_member));
487487 // DW.AT.name, DW.FORM.string
......@@ -517,7 +517,7 @@ pub const DeclState = struct {
517517 .ErrorSet => {
518518 try addDbgInfoErrorSet(
519519 self.abbrev_type_arena.allocator(),
520 module,
520 mod,
521521 ty,
522522 target,
523523 &self.dbg_info,
......@@ -526,18 +526,18 @@ pub const DeclState = struct {
526526 .ErrorUnion => {
527527 const error_ty = ty.errorUnionSet();
528528 const payload_ty = ty.errorUnionPayload();
529 const payload_align = if (payload_ty.isNoReturn()) 0 else payload_ty.abiAlignment(target);
530 const error_align = Type.anyerror.abiAlignment(target);
531 const abi_size = ty.abiSize(target);
532 const payload_off = if (error_align >= payload_align) Type.anyerror.abiSize(target) else 0;
533 const error_off = if (error_align >= payload_align) 0 else payload_ty.abiSize(target);
529 const payload_align = if (payload_ty.isNoReturn()) 0 else payload_ty.abiAlignment(mod);
530 const error_align = Type.anyerror.abiAlignment(mod);
531 const abi_size = ty.abiSize(mod);
532 const payload_off = if (error_align >= payload_align) Type.anyerror.abiSize(mod) else 0;
533 const error_off = if (error_align >= payload_align) 0 else payload_ty.abiSize(mod);
534534
535535 // DW.AT.structure_type
536536 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
537537 // DW.AT.byte_size, DW.FORM.udata
538538 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
539539 // DW.AT.name, DW.FORM.string
540 const name = try ty.nameAllocArena(arena, module);
540 const name = try ty.nameAllocArena(arena, mod);
541541 try dbg_info_buffer.writer().print("{s}\x00", .{name});
542542
543543 if (!payload_ty.isNoReturn()) {
......@@ -685,7 +685,8 @@ pub const DeclState = struct {
685685 const atom_index = self.di_atom_decls.get(owner_decl).?;
686686 const name_with_null = name.ptr[0 .. name.len + 1];
687687 try dbg_info.append(@enumToInt(AbbrevKind.variable));
688 const target = self.mod.getTarget();
688 const mod = self.mod;
689 const target = mod.getTarget();
689690 const endian = target.cpu.arch.endian();
690691 const child_ty = if (is_ptr) ty.childType() else ty;
691692
......@@ -790,9 +791,9 @@ pub const DeclState = struct {
790791 const fixup = dbg_info.items.len;
791792 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
792793 1,
793 if (child_ty.isSignedInt()) DW.OP.consts else DW.OP.constu,
794 if (child_ty.isSignedInt(mod)) DW.OP.consts else DW.OP.constu,
794795 });
795 if (child_ty.isSignedInt()) {
796 if (child_ty.isSignedInt(mod)) {
796797 try leb128.writeILEB128(dbg_info.writer(), @bitCast(i64, x));
797798 } else {
798799 try leb128.writeULEB128(dbg_info.writer(), x);
......@@ -805,7 +806,7 @@ pub const DeclState = struct {
805806 // DW.AT.location, DW.FORM.exprloc
806807 // uleb128(exprloc_len)
807808 // DW.OP.implicit_value uleb128(len_of_bytes) bytes
808 const abi_size = @intCast(u32, child_ty.abiSize(target));
809 const abi_size = @intCast(u32, child_ty.abiSize(mod));
809810 var implicit_value_len = std.ArrayList(u8).init(self.gpa);
810811 defer implicit_value_len.deinit();
811812 try leb128.writeULEB128(implicit_value_len.writer(), abi_size);
......@@ -979,7 +980,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
979980
980981 assert(decl.has_tv);
981982
982 switch (decl.ty.zigTypeTag()) {
983 switch (decl.ty.zigTypeTag(mod)) {
983984 .Fn => {
984985 _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index);
985986
......@@ -1027,7 +1028,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
10271028 try dbg_info_buffer.ensureUnusedCapacity(25 + decl_name_with_null.len);
10281029
10291030 const fn_ret_type = decl.ty.fnReturnType();
1030 const fn_ret_has_bits = fn_ret_type.hasRuntimeBits();
1031 const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(mod);
10311032 if (fn_ret_has_bits) {
10321033 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.subprogram));
10331034 } else {
......@@ -1059,7 +1060,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
10591060
10601061pub fn commitDeclState(
10611062 self: *Dwarf,
1062 module: *Module,
1063 mod: *Module,
10631064 decl_index: Module.Decl.Index,
10641065 sym_addr: u64,
10651066 sym_size: u64,
......@@ -1071,12 +1072,12 @@ pub fn commitDeclState(
10711072 const gpa = self.allocator;
10721073 var dbg_line_buffer = &decl_state.dbg_line;
10731074 var dbg_info_buffer = &decl_state.dbg_info;
1074 const decl = module.declPtr(decl_index);
1075 const decl = mod.declPtr(decl_index);
10751076
10761077 const target_endian = self.target.cpu.arch.endian();
10771078
10781079 assert(decl.has_tv);
1079 switch (decl.ty.zigTypeTag()) {
1080 switch (decl.ty.zigTypeTag(mod)) {
10801081 .Fn => {
10811082 // Since the Decl is a function, we need to update the .debug_line program.
10821083 // Perform the relocations based on vaddr.
......@@ -1283,7 +1284,7 @@ pub fn commitDeclState(
12831284 if (deferred) continue;
12841285
12851286 symbol.offset = @intCast(u32, dbg_info_buffer.items.len);
1286 try decl_state.addDbgInfoType(module, di_atom_index, ty);
1287 try decl_state.addDbgInfoType(mod, di_atom_index, ty);
12871288 }
12881289 }
12891290
......@@ -1319,7 +1320,7 @@ pub fn commitDeclState(
13191320 reloc.offset,
13201321 value,
13211322 target,
1322 ty.fmt(module),
1323 ty.fmt(mod),
13231324 });
13241325 mem.writeInt(
13251326 u32,
......@@ -2663,7 +2664,7 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {
26632664
26642665fn addDbgInfoErrorSet(
26652666 arena: Allocator,
2666 module: *Module,
2667 mod: *Module,
26672668 ty: Type,
26682669 target: std.Target,
26692670 dbg_info_buffer: *std.ArrayList(u8),
......@@ -2673,10 +2674,10 @@ fn addDbgInfoErrorSet(
26732674 // DW.AT.enumeration_type
26742675 try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type));
26752676 // DW.AT.byte_size, DW.FORM.udata
2676 const abi_size = Type.anyerror.abiSize(target);
2677 const abi_size = Type.anyerror.abiSize(mod);
26772678 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
26782679 // DW.AT.name, DW.FORM.string
2679 const name = try ty.nameAllocArena(arena, module);
2680 const name = try ty.nameAllocArena(arena, mod);
26802681 try dbg_info_buffer.writer().print("{s}\x00", .{name});
26812682
26822683 // DW.AT.enumerator
......@@ -2691,7 +2692,7 @@ fn addDbgInfoErrorSet(
26912692
26922693 const error_names = ty.errorSetNames();
26932694 for (error_names) |error_name| {
2694 const kv = module.getErrorValue(error_name) catch unreachable;
2695 const kv = mod.getErrorValue(error_name) catch unreachable;
26952696 // DW.AT.enumerator
26962697 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));
26972698 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
src/link/Elf.zig+5-4
......@@ -2449,9 +2449,10 @@ pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.I
24492449}
24502450
24512451fn getDeclShdrIndex(self: *Elf, decl_index: Module.Decl.Index) u16 {
2452 const decl = self.base.options.module.?.declPtr(decl_index);
2452 const mod = self.base.options.module.?;
2453 const decl = mod.declPtr(decl_index);
24532454 const ty = decl.ty;
2454 const zig_ty = ty.zigTypeTag();
2455 const zig_ty = ty.zigTypeTag(mod);
24552456 const val = decl.val;
24562457 const shdr_index: u16 = blk: {
24572458 if (val.isUndefDeep()) {
......@@ -2482,7 +2483,7 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
24822483 defer self.base.allocator.free(decl_name);
24832484
24842485 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
2485 const required_alignment = decl.getAlignment(self.base.options.target);
2486 const required_alignment = decl.getAlignment(mod);
24862487
24872488 const decl_metadata = self.decls.get(decl_index).?;
24882489 const atom_index = decl_metadata.atom;
......@@ -2826,7 +2827,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
28262827 },
28272828 };
28282829
2829 const required_alignment = typed_value.ty.abiAlignment(self.base.options.target);
2830 const required_alignment = typed_value.ty.abiAlignment(mod);
28302831 const shdr_index = self.rodata_section_index.?;
28312832 const phdr_index = self.sections.items(.phdr_index)[shdr_index];
28322833 const local_sym = self.getAtom(atom_index).getSymbolPtr(self);
src/link/MachO.zig+7-4
......@@ -1948,7 +1948,8 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
19481948 },
19491949 };
19501950
1951 const required_alignment = typed_value.ty.abiAlignment(self.base.options.target);
1951 const mod = self.base.options.module.?;
1952 const required_alignment = typed_value.ty.abiAlignment(mod);
19521953 const atom = self.getAtomPtr(atom_index);
19531954 atom.size = code.len;
19541955 // TODO: work out logic for disambiguating functions from function pointers
......@@ -2152,6 +2153,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.In
21522153}
21532154
21542155fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.Decl.Index) !void {
2156 const mod = self.base.options.module.?;
21552157 // Lowering a TLV on macOS involves two stages:
21562158 // 1. first we lower the initializer into appopriate section (__thread_data or __thread_bss)
21572159 // 2. next, we create a corresponding threadlocal variable descriptor in __thread_vars
......@@ -2202,7 +2204,7 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D
22022204 },
22032205 };
22042206
2205 const required_alignment = decl.getAlignment(self.base.options.target);
2207 const required_alignment = decl.getAlignment(mod);
22062208
22072209 const decl_name = try decl.getFullyQualifiedName(module);
22082210 defer gpa.free(decl_name);
......@@ -2262,7 +2264,8 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 {
22622264 const decl = self.base.options.module.?.declPtr(decl_index);
22632265 const ty = decl.ty;
22642266 const val = decl.val;
2265 const zig_ty = ty.zigTypeTag();
2267 const mod = self.base.options.module.?;
2268 const zig_ty = ty.zigTypeTag(mod);
22662269 const mode = self.base.options.optimize_mode;
22672270 const single_threaded = self.base.options.single_threaded;
22682271 const sect_id: u8 = blk: {
......@@ -2301,7 +2304,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64
23012304 const mod = self.base.options.module.?;
23022305 const decl = mod.declPtr(decl_index);
23032306
2304 const required_alignment = decl.getAlignment(self.base.options.target);
2307 const required_alignment = decl.getAlignment(mod);
23052308
23062309 const decl_name = try decl.getFullyQualifiedName(mod);
23072310 defer gpa.free(decl_name);
src/link/Plan9.zig+5-4
......@@ -432,8 +432,9 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl_index: Module.Decl.Index)
432432}
433433/// called at the end of update{Decl,Func}
434434fn updateFinish(self: *Plan9, decl_index: Module.Decl.Index) !void {
435 const decl = self.base.options.module.?.declPtr(decl_index);
436 const is_fn = (decl.ty.zigTypeTag() == .Fn);
435 const mod = self.base.options.module.?;
436 const decl = mod.declPtr(decl_index);
437 const is_fn = (decl.ty.zigTypeTag(mod) == .Fn);
437438 log.debug("update the symbol table and got for decl {*} ({s})", .{ decl, decl.name });
438439 const sym_t: aout.Sym.Type = if (is_fn) .t else .d;
439440
......@@ -704,7 +705,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
704705 log.debug("relocating the address of '{s}' + {d} into '{s}' + {d}", .{ target_decl.name, addend, source_decl.name, offset });
705706
706707 const code = blk: {
707 const is_fn = source_decl.ty.zigTypeTag() == .Fn;
708 const is_fn = source_decl.ty.zigTypeTag(mod) == .Fn;
708709 if (is_fn) {
709710 const table = self.fn_decl_table.get(source_decl.getFileScope()).?.functions;
710711 const output = table.get(source_decl_index).?;
......@@ -1031,7 +1032,7 @@ pub fn getDeclVAddr(
10311032) !u64 {
10321033 const mod = self.base.options.module.?;
10331034 const decl = mod.declPtr(decl_index);
1034 if (decl.ty.zigTypeTag() == .Fn) {
1035 if (decl.ty.zigTypeTag(mod) == .Fn) {
10351036 var start = self.bases.text;
10361037 var it_file = self.fn_decl_table.iterator();
10371038 while (it_file.next()) |fentry| {
src/link/Wasm.zig+8-8
......@@ -1473,7 +1473,7 @@ fn finishUpdateDecl(wasm: *Wasm, decl_index: Module.Decl.Index, code: []const u8
14731473
14741474 atom.size = @intCast(u32, code.len);
14751475 if (code.len == 0) return;
1476 atom.alignment = decl.ty.abiAlignment(wasm.base.options.target);
1476 atom.alignment = decl.ty.abiAlignment(mod);
14771477}
14781478
14791479/// From a given symbol location, returns its `wasm.GlobalType`.
......@@ -1523,9 +1523,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
15231523/// Returns the symbol index of the local
15241524/// The given `decl` is the parent decl whom owns the constant.
15251525pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.Index) !u32 {
1526 assert(tv.ty.zigTypeTag() != .Fn); // cannot create local symbols for functions
1527
15281526 const mod = wasm.base.options.module.?;
1527 assert(tv.ty.zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
15291528 const decl = mod.declPtr(decl_index);
15301529
15311530 // Create and initialize a new local symbol and atom
......@@ -1543,7 +1542,7 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In
15431542
15441543 const code = code: {
15451544 const atom = wasm.getAtomPtr(atom_index);
1546 atom.alignment = tv.ty.abiAlignment(wasm.base.options.target);
1545 atom.alignment = tv.ty.abiAlignment(mod);
15471546 wasm.symbols.items[atom.sym_index] = .{
15481547 .name = try wasm.string_table.put(wasm.base.allocator, name),
15491548 .flags = @enumToInt(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
......@@ -1632,7 +1631,7 @@ pub fn getDeclVAddr(
16321631 const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;
16331632 const atom = wasm.getAtomPtr(atom_index);
16341633 const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;
1635 if (decl.ty.zigTypeTag() == .Fn) {
1634 if (decl.ty.zigTypeTag(mod) == .Fn) {
16361635 assert(reloc_info.addend == 0); // addend not allowed for function relocations
16371636 // We found a function pointer, so add it to our table,
16381637 // as function pointers are not allowed to be stored inside the data section.
......@@ -2933,7 +2932,8 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 {
29332932 const atom_index = try wasm.createAtom();
29342933 const atom = wasm.getAtomPtr(atom_index);
29352934 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
2936 atom.alignment = slice_ty.abiAlignment(wasm.base.options.target);
2935 const mod = wasm.base.options.module.?;
2936 atom.alignment = slice_ty.abiAlignment(mod);
29372937 const sym_index = atom.sym_index;
29382938
29392939 const sym_name = try wasm.string_table.put(wasm.base.allocator, "__zig_err_name_table");
......@@ -3000,7 +3000,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
30003000 .offset = offset,
30013001 .addend = @intCast(i32, addend),
30023002 });
3003 atom.size += @intCast(u32, slice_ty.abiSize(wasm.base.options.target));
3003 atom.size += @intCast(u32, slice_ty.abiSize(mod));
30043004 addend += len;
30053005
30063006 // as we updated the error name table, we now store the actual name within the names atom
......@@ -3369,7 +3369,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
33693369 if (decl.isExtern()) continue;
33703370 const atom_index = entry.value_ptr.*;
33713371 const atom = wasm.getAtomPtr(atom_index);
3372 if (decl.ty.zigTypeTag() == .Fn) {
3372 if (decl.ty.zigTypeTag(mod) == .Fn) {
33733373 try wasm.parseAtom(atom_index, .function);
33743374 } else if (decl.getVariable()) |variable| {
33753375 if (!variable.is_mutable) {
src/print_air.zig+4-4
......@@ -7,6 +7,7 @@ const Value = @import("value.zig").Value;
77const Type = @import("type.zig").Type;
88const Air = @import("Air.zig");
99const Liveness = @import("Liveness.zig");
10const InternPool = @import("InternPool.zig");
1011
1112pub fn write(stream: anytype, module: *Module, air: Air, liveness: ?Liveness) void {
1213 const instruction_bytes = air.instructions.len *
......@@ -965,14 +966,13 @@ const Writer = struct {
965966 operand: Air.Inst.Ref,
966967 dies: bool,
967968 ) @TypeOf(s).Error!void {
968 var i: usize = @enumToInt(operand);
969 const i = @enumToInt(operand);
969970
970 if (i < Air.Inst.Ref.typed_value_map.len) {
971 if (i < InternPool.static_len) {
971972 return s.print("@{}", .{operand});
972973 }
973 i -= Air.Inst.Ref.typed_value_map.len;
974974
975 return w.writeInstIndex(s, @intCast(Air.Inst.Index, i), dies);
975 return w.writeInstIndex(s, i - InternPool.static_len, dies);
976976 }
977977
978978 fn writeInstIndex(
src/print_zir.zig+4-8
......@@ -3,6 +3,7 @@ const mem = std.mem;
33const Allocator = std.mem.Allocator;
44const assert = std.debug.assert;
55const Ast = std.zig.Ast;
6const InternPool = @import("InternPool.zig");
67
78const Zir = @import("Zir.zig");
89const Module = @import("Module.zig");
......@@ -2468,14 +2469,9 @@ const Writer = struct {
24682469 }
24692470
24702471 fn writeInstRef(self: *Writer, stream: anytype, ref: Zir.Inst.Ref) !void {
2471 var i: usize = @enumToInt(ref);
2472
2473 if (i < Zir.Inst.Ref.typed_value_map.len) {
2474 return stream.print("@{}", .{ref});
2475 }
2476 i -= Zir.Inst.Ref.typed_value_map.len;
2477
2478 return self.writeInstIndex(stream, @intCast(Zir.Inst.Index, i));
2472 const i = @enumToInt(ref);
2473 if (i < InternPool.static_len) return stream.print("@{}", .{@intToEnum(InternPool.Index, i)});
2474 return self.writeInstIndex(stream, i - InternPool.static_len);
24792475 }
24802476
24812477 fn writeInstIndex(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
src/target.zig-128
......@@ -512,134 +512,6 @@ pub fn needUnwindTables(target: std.Target) bool {
512512 return target.os.tag == .windows;
513513}
514514
515pub const AtomicPtrAlignmentError = error{
516 FloatTooBig,
517 IntTooBig,
518 BadType,
519};
520
521pub const AtomicPtrAlignmentDiagnostics = struct {
522 bits: u16 = undefined,
523 max_bits: u16 = undefined,
524};
525
526/// If ABI alignment of `ty` is OK for atomic operations, returns 0.
527/// Otherwise returns the alignment required on a pointer for the target
528/// to perform atomic operations.
529// TODO this function does not take into account CPU features, which can affect
530// this value. Audit this!
531pub fn atomicPtrAlignment(
532 target: std.Target,
533 ty: Type,
534 diags: *AtomicPtrAlignmentDiagnostics,
535) AtomicPtrAlignmentError!u32 {
536 const max_atomic_bits: u16 = switch (target.cpu.arch) {
537 .avr,
538 .msp430,
539 .spu_2,
540 => 16,
541
542 .arc,
543 .arm,
544 .armeb,
545 .hexagon,
546 .m68k,
547 .le32,
548 .mips,
549 .mipsel,
550 .nvptx,
551 .powerpc,
552 .powerpcle,
553 .r600,
554 .riscv32,
555 .sparc,
556 .sparcel,
557 .tce,
558 .tcele,
559 .thumb,
560 .thumbeb,
561 .x86,
562 .xcore,
563 .amdil,
564 .hsail,
565 .spir,
566 .kalimba,
567 .lanai,
568 .shave,
569 .wasm32,
570 .renderscript32,
571 .csky,
572 .spirv32,
573 .dxil,
574 .loongarch32,
575 .xtensa,
576 => 32,
577
578 .amdgcn,
579 .bpfel,
580 .bpfeb,
581 .le64,
582 .mips64,
583 .mips64el,
584 .nvptx64,
585 .powerpc64,
586 .powerpc64le,
587 .riscv64,
588 .sparc64,
589 .s390x,
590 .amdil64,
591 .hsail64,
592 .spir64,
593 .wasm64,
594 .renderscript64,
595 .ve,
596 .spirv64,
597 .loongarch64,
598 => 64,
599
600 .aarch64,
601 .aarch64_be,
602 .aarch64_32,
603 => 128,
604
605 .x86_64 => if (std.Target.x86.featureSetHas(target.cpu.features, .cx16)) 128 else 64,
606 };
607
608 var buffer: Type.Payload.Bits = undefined;
609
610 const int_ty = switch (ty.zigTypeTag()) {
611 .Int => ty,
612 .Enum => ty.intTagType(&buffer),
613 .Float => {
614 const bit_count = ty.floatBits(target);
615 if (bit_count > max_atomic_bits) {
616 diags.* = .{
617 .bits = bit_count,
618 .max_bits = max_atomic_bits,
619 };
620 return error.FloatTooBig;
621 }
622 return 0;
623 },
624 .Bool => return 0,
625 else => {
626 if (ty.isPtrAtRuntime()) return 0;
627 return error.BadType;
628 },
629 };
630
631 const bit_count = int_ty.intInfo(target).bits;
632 if (bit_count > max_atomic_bits) {
633 diags.* = .{
634 .bits = bit_count,
635 .max_bits = max_atomic_bits,
636 };
637 return error.IntTooBig;
638 }
639
640 return 0;
641}
642
643515pub fn defaultAddressSpace(
644516 target: std.Target,
645517 context: enum {
src/type.zig+650-663
......@@ -9,27 +9,102 @@ const log = std.log.scoped(.Type);
99const target_util = @import("target.zig");
1010const TypedValue = @import("TypedValue.zig");
1111const Sema = @import("Sema.zig");
12const InternPool = @import("InternPool.zig");
1213
1314const file_struct = @This();
1415
15/// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.
16/// It's important for this type to be small.
17/// Types are not de-duplicated, which helps with multi-threading since it obviates the requirement
18/// of obtaining a lock on a global type table, as well as making the
19/// garbage collection bookkeeping simpler.
20/// This union takes advantage of the fact that the first page of memory
21/// is unmapped, giving us 4096 possible enum tags that have no payload.
22pub const Type = extern union {
23 /// If the tag value is less than Tag.no_payload_count, then no pointer
24 /// dereference is needed.
25 tag_if_small_enough: Tag,
26 ptr_otherwise: *Payload,
27
28 pub fn zigTypeTag(ty: Type) std.builtin.TypeId {
29 return ty.zigTypeTagOrPoison() catch unreachable;
30 }
16pub const Type = struct {
17 /// We are migrating towards using this for every Type object. However, many
18 /// types are still represented the legacy way. This is indicated by using
19 /// InternPool.Index.none.
20 ip_index: InternPool.Index,
21
22 /// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.
23 /// This union takes advantage of the fact that the first page of memory
24 /// is unmapped, giving us 4096 possible enum tags that have no payload.
25 legacy: extern union {
26 /// If the tag value is less than Tag.no_payload_count, then no pointer
27 /// dereference is needed.
28 tag_if_small_enough: Tag,
29 ptr_otherwise: *Payload,
30 },
31
32 pub fn zigTypeTag(ty: Type, mod: *const Module) std.builtin.TypeId {
33 return ty.zigTypeTagOrPoison(mod) catch unreachable;
34 }
35
36 pub fn zigTypeTagOrPoison(ty: Type, mod: *const Module) error{GenericPoison}!std.builtin.TypeId {
37 if (ty.ip_index != .none) {
38 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
39 .int_type => return .Int,
40 .ptr_type => return .Pointer,
41 .array_type => return .Array,
42 .vector_type => return .Vector,
43 .optional_type => return .Optional,
44 .error_union_type => return .ErrorUnion,
45 .struct_type => return .Struct,
46 .simple_type => |s| switch (s) {
47 .f16,
48 .f32,
49 .f64,
50 .f80,
51 .f128,
52 => return .Float,
53
54 .usize,
55 .isize,
56 .c_char,
57 .c_short,
58 .c_ushort,
59 .c_int,
60 .c_uint,
61 .c_long,
62 .c_ulong,
63 .c_longlong,
64 .c_ulonglong,
65 .c_longdouble,
66 => return .Int,
67
68 .anyopaque => return .Opaque,
69 .bool => return .Bool,
70 .void => return .Void,
71 .type => return .Type,
72 .anyerror => return .ErrorSet,
73 .comptime_int => return .ComptimeInt,
74 .comptime_float => return .ComptimeFloat,
75 .noreturn => return .NoReturn,
76 .@"anyframe" => return .AnyFrame,
77 .null => return .Null,
78 .undefined => return .Undefined,
79 .enum_literal => return .EnumLiteral,
80
81 .atomic_order,
82 .atomic_rmw_op,
83 .calling_convention,
84 .address_space,
85 .float_mode,
86 .reduce_op,
87 => return .Enum,
88
89 .call_modifier,
90 .prefetch_options,
91 .export_options,
92 .extern_options,
93 => return .Struct,
94
95 .type_info => return .Union,
96
97 .generic_poison => unreachable,
98 .var_args_param => unreachable,
99 },
31100
32 pub fn zigTypeTagOrPoison(ty: Type) error{GenericPoison}!std.builtin.TypeId {
101 .extern_func,
102 .int,
103 .enum_tag,
104 .simple_value,
105 => unreachable, // it's a value, not a type
106 }
107 }
33108 switch (ty.tag()) {
34109 .generic_poison => return error.GenericPoison,
35110
......@@ -56,8 +131,6 @@ pub const Type = extern union {
56131 .c_ulong,
57132 .c_longlong,
58133 .c_ulonglong,
59 .int_signed,
60 .int_unsigned,
61134 => return .Int,
62135
63136 .f16,
......@@ -85,10 +158,6 @@ pub const Type = extern union {
85158 .null => return .Null,
86159 .undefined => return .Undefined,
87160
88 .fn_noreturn_no_args => return .Fn,
89 .fn_void_no_args => return .Fn,
90 .fn_naked_noreturn_no_args => return .Fn,
91 .fn_ccc_void_no_args => return .Fn,
92161 .function => return .Fn,
93162
94163 .array,
......@@ -159,26 +228,26 @@ pub const Type = extern union {
159228 }
160229 }
161230
162 pub fn baseZigTypeTag(self: Type) std.builtin.TypeId {
163 return switch (self.zigTypeTag()) {
164 .ErrorUnion => self.errorUnionPayload().baseZigTypeTag(),
231 pub fn baseZigTypeTag(self: Type, mod: *const Module) std.builtin.TypeId {
232 return switch (self.zigTypeTag(mod)) {
233 .ErrorUnion => self.errorUnionPayload().baseZigTypeTag(mod),
165234 .Optional => {
166235 var buf: Payload.ElemType = undefined;
167 return self.optionalChild(&buf).baseZigTypeTag();
236 return self.optionalChild(&buf).baseZigTypeTag(mod);
168237 },
169238 else => |t| t,
170239 };
171240 }
172241
173 pub fn isSelfComparable(ty: Type, is_equality_cmp: bool) bool {
174 return switch (ty.zigTypeTag()) {
242 pub fn isSelfComparable(ty: Type, mod: *const Module, is_equality_cmp: bool) bool {
243 return switch (ty.zigTypeTag(mod)) {
175244 .Int,
176245 .Float,
177246 .ComptimeFloat,
178247 .ComptimeInt,
179248 => true,
180249
181 .Vector => ty.elemType2().isSelfComparable(is_equality_cmp),
250 .Vector => ty.elemType2(mod).isSelfComparable(mod, is_equality_cmp),
182251
183252 .Bool,
184253 .Type,
......@@ -205,44 +274,54 @@ pub const Type = extern union {
205274 .Optional => {
206275 if (!is_equality_cmp) return false;
207276 var buf: Payload.ElemType = undefined;
208 return ty.optionalChild(&buf).isSelfComparable(is_equality_cmp);
277 return ty.optionalChild(&buf).isSelfComparable(mod, is_equality_cmp);
209278 },
210279 };
211280 }
212281
213282 pub fn initTag(comptime small_tag: Tag) Type {
214283 comptime assert(@enumToInt(small_tag) < Tag.no_payload_count);
215 return .{ .tag_if_small_enough = small_tag };
284 return Type{
285 .ip_index = .none,
286 .legacy = .{ .tag_if_small_enough = small_tag },
287 };
216288 }
217289
218290 pub fn initPayload(payload: *Payload) Type {
219291 assert(@enumToInt(payload.tag) >= Tag.no_payload_count);
220 return .{ .ptr_otherwise = payload };
292 return Type{
293 .ip_index = .none,
294 .legacy = .{ .ptr_otherwise = payload },
295 };
221296 }
222297
223 pub fn tag(self: Type) Tag {
224 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
225 return self.tag_if_small_enough;
298 pub fn tag(ty: Type) Tag {
299 assert(ty.ip_index == .none);
300 if (@enumToInt(ty.legacy.tag_if_small_enough) < Tag.no_payload_count) {
301 return ty.legacy.tag_if_small_enough;
226302 } else {
227 return self.ptr_otherwise.tag;
303 return ty.legacy.ptr_otherwise.tag;
228304 }
229305 }
230306
231307 /// Prefer `castTag` to this.
232308 pub fn cast(self: Type, comptime T: type) ?*T {
309 if (self.ip_index != .none) {
310 return null;
311 }
233312 if (@hasField(T, "base_tag")) {
234313 return self.castTag(T.base_tag);
235314 }
236 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
315 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
237316 return null;
238317 }
239318 inline for (@typeInfo(Tag).Enum.fields) |field| {
240319 if (field.value < Tag.no_payload_count)
241320 continue;
242321 const t = @intToEnum(Tag, field.value);
243 if (self.ptr_otherwise.tag == t) {
322 if (self.legacy.ptr_otherwise.tag == t) {
244323 if (T == t.Type()) {
245 return @fieldParentPtr(T, "base", self.ptr_otherwise);
324 return @fieldParentPtr(T, "base", self.legacy.ptr_otherwise);
246325 }
247326 return null;
248327 }
......@@ -251,11 +330,14 @@ pub const Type = extern union {
251330 }
252331
253332 pub fn castTag(self: Type, comptime t: Tag) ?*t.Type() {
254 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count)
333 if (self.ip_index != .none) {
334 return null;
335 }
336 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count)
255337 return null;
256338
257 if (self.ptr_otherwise.tag == t)
258 return @fieldParentPtr(t.Type(), "base", self.ptr_otherwise);
339 if (self.legacy.ptr_otherwise.tag == t)
340 return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise);
259341
260342 return null;
261343 }
......@@ -285,10 +367,10 @@ pub const Type = extern union {
285367 }
286368
287369 /// If it is a function pointer, returns the function type. Otherwise returns null.
288 pub fn castPtrToFn(ty: Type) ?Type {
289 if (ty.zigTypeTag() != .Pointer) return null;
370 pub fn castPtrToFn(ty: Type, mod: *const Module) ?Type {
371 if (ty.zigTypeTag(mod) != .Pointer) return null;
290372 const elem_ty = ty.childType();
291 if (elem_ty.zigTypeTag() != .Fn) return null;
373 if (elem_ty.zigTypeTag(mod) != .Fn) return null;
292374 return elem_ty;
293375 }
294376
......@@ -536,7 +618,10 @@ pub const Type = extern union {
536618
537619 pub fn eql(a: Type, b: Type, mod: *Module) bool {
538620 // As a shortcut, if the small tags / addresses match, we're done.
539 if (a.tag_if_small_enough == b.tag_if_small_enough) return true;
621 if (a.ip_index != .none or b.ip_index != .none) {
622 return a.ip_index == b.ip_index;
623 }
624 if (a.legacy.tag_if_small_enough == b.legacy.tag_if_small_enough) return true;
540625
541626 switch (a.tag()) {
542627 .generic_poison => unreachable,
......@@ -589,16 +674,11 @@ pub const Type = extern union {
589674 .i64,
590675 .u128,
591676 .i128,
592 .int_signed,
593 .int_unsigned,
594677 => {
595 if (b.zigTypeTag() != .Int) return false;
678 if (b.zigTypeTag(mod) != .Int) return false;
596679 if (b.isNamedInt()) return false;
597
598 // Arbitrary sized integers. The target will not be branched upon,
599 // because we handled target-dependent cases above.
600 const info_a = a.intInfo(@as(Target, undefined));
601 const info_b = b.intInfo(@as(Target, undefined));
680 const info_a = a.intInfo(mod);
681 const info_b = b.intInfo(mod);
602682 return info_a.signedness == info_b.signedness and info_a.bits == info_b.bits;
603683 },
604684
......@@ -641,13 +721,8 @@ pub const Type = extern union {
641721 return opaque_obj_a == opaque_obj_b;
642722 },
643723
644 .fn_noreturn_no_args,
645 .fn_void_no_args,
646 .fn_naked_noreturn_no_args,
647 .fn_ccc_void_no_args,
648 .function,
649 => {
650 if (b.zigTypeTag() != .Fn) return false;
724 .function => {
725 if (b.zigTypeTag(mod) != .Fn) return false;
651726
652727 const a_info = a.fnInfo();
653728 const b_info = b.fnInfo();
......@@ -699,7 +774,7 @@ pub const Type = extern union {
699774 .array_sentinel,
700775 .vector,
701776 => {
702 if (a.zigTypeTag() != b.zigTypeTag()) return false;
777 if (a.zigTypeTag(mod) != b.zigTypeTag(mod)) return false;
703778
704779 if (a.arrayLen() != b.arrayLen())
705780 return false;
......@@ -737,7 +812,7 @@ pub const Type = extern union {
737812 .manyptr_const_u8,
738813 .manyptr_const_u8_sentinel_0,
739814 => {
740 if (b.zigTypeTag() != .Pointer) return false;
815 if (b.zigTypeTag(mod) != .Pointer) return false;
741816
742817 const info_a = a.ptrInfo().data;
743818 const info_b = b.ptrInfo().data;
......@@ -783,7 +858,7 @@ pub const Type = extern union {
783858 .optional_single_const_pointer,
784859 .optional_single_mut_pointer,
785860 => {
786 if (b.zigTypeTag() != .Optional) return false;
861 if (b.zigTypeTag(mod) != .Optional) return false;
787862
788863 var buf_a: Payload.ElemType = undefined;
789864 var buf_b: Payload.ElemType = undefined;
......@@ -791,7 +866,7 @@ pub const Type = extern union {
791866 },
792867
793868 .anyerror_void_error_union, .error_union => {
794 if (b.zigTypeTag() != .ErrorUnion) return false;
869 if (b.zigTypeTag(mod) != .ErrorUnion) return false;
795870
796871 const a_set = a.errorUnionSet();
797872 const b_set = b.errorUnionSet();
......@@ -805,8 +880,8 @@ pub const Type = extern union {
805880 },
806881
807882 .anyframe_T => {
808 if (b.zigTypeTag() != .AnyFrame) return false;
809 return a.elemType2().eql(b.elemType2(), mod);
883 if (b.zigTypeTag(mod) != .AnyFrame) return false;
884 return a.elemType2(mod).eql(b.elemType2(mod), mod);
810885 },
811886
812887 .empty_struct => {
......@@ -941,6 +1016,9 @@ pub const Type = extern union {
9411016 }
9421017
9431018 pub fn hashWithHasher(ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
1019 if (ty.ip_index != .none) {
1020 return mod.intern_pool.indexToKey(ty.ip_index).hashWithHasher(hasher);
1021 }
9441022 switch (ty.tag()) {
9451023 .generic_poison => unreachable,
9461024
......@@ -1007,13 +1085,10 @@ pub const Type = extern union {
10071085 .i64,
10081086 .u128,
10091087 .i128,
1010 .int_signed,
1011 .int_unsigned,
10121088 => {
1013 // Arbitrary sized integers. The target will not be branched upon,
1014 // because we handled target-dependent cases above.
1089 // Arbitrary sized integers.
10151090 std.hash.autoHash(hasher, std.builtin.TypeId.Int);
1016 const info = ty.intInfo(@as(Target, undefined));
1091 const info = ty.intInfo(mod);
10171092 std.hash.autoHash(hasher, info.signedness);
10181093 std.hash.autoHash(hasher, info.bits);
10191094 },
......@@ -1052,12 +1127,7 @@ pub const Type = extern union {
10521127 std.hash.autoHash(hasher, opaque_obj);
10531128 },
10541129
1055 .fn_noreturn_no_args,
1056 .fn_void_no_args,
1057 .fn_naked_noreturn_no_args,
1058 .fn_ccc_void_no_args,
1059 .function,
1060 => {
1130 .function => {
10611131 std.hash.autoHash(hasher, std.builtin.TypeId.Fn);
10621132
10631133 const fn_info = ty.fnInfo();
......@@ -1275,9 +1345,15 @@ pub const Type = extern union {
12751345 };
12761346
12771347 pub fn copy(self: Type, allocator: Allocator) error{OutOfMemory}!Type {
1278 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
1279 return Type{ .tag_if_small_enough = self.tag_if_small_enough };
1280 } else switch (self.ptr_otherwise.tag) {
1348 if (self.ip_index != .none) {
1349 return Type{ .ip_index = self.ip_index, .legacy = undefined };
1350 }
1351 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
1352 return Type{
1353 .ip_index = .none,
1354 .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough },
1355 };
1356 } else switch (self.legacy.ptr_otherwise.tag) {
12811357 .u1,
12821358 .u8,
12831359 .i8,
......@@ -1317,10 +1393,6 @@ pub const Type = extern union {
13171393 .noreturn,
13181394 .null,
13191395 .undefined,
1320 .fn_noreturn_no_args,
1321 .fn_void_no_args,
1322 .fn_naked_noreturn_no_args,
1323 .fn_ccc_void_no_args,
13241396 .single_const_pointer_to_comptime_int,
13251397 .const_slice_u8,
13261398 .const_slice_u8_sentinel_0,
......@@ -1370,13 +1442,12 @@ pub const Type = extern union {
13701442 .base = .{ .tag = payload.base.tag },
13711443 .data = try payload.data.copy(allocator),
13721444 };
1373 return Type{ .ptr_otherwise = &new_payload.base };
1445 return Type{
1446 .ip_index = .none,
1447 .legacy = .{ .ptr_otherwise = &new_payload.base },
1448 };
13741449 },
13751450
1376 .int_signed,
1377 .int_unsigned,
1378 => return self.copyPayloadShallow(allocator, Payload.Bits),
1379
13801451 .vector => {
13811452 const payload = self.castTag(.vector).?.data;
13821453 return Tag.vector.create(allocator, .{
......@@ -1511,7 +1582,10 @@ pub const Type = extern union {
15111582 const payload = self.cast(T).?;
15121583 const new_payload = try allocator.create(T);
15131584 new_payload.* = payload.*;
1514 return Type{ .ptr_otherwise = &new_payload.base };
1585 return Type{
1586 .ip_index = .none,
1587 .legacy = .{ .ptr_otherwise = &new_payload.base },
1588 };
15151589 }
15161590
15171591 pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
......@@ -1550,7 +1624,7 @@ pub const Type = extern union {
15501624 }
15511625
15521626 /// This is a debug function. In order to print types in a meaningful way
1553 /// we also need access to the target.
1627 /// we also need access to the module.
15541628 pub fn dump(
15551629 start_type: Type,
15561630 comptime unused_format_string: []const u8,
......@@ -1559,10 +1633,13 @@ pub const Type = extern union {
15591633 ) @TypeOf(writer).Error!void {
15601634 _ = options;
15611635 comptime assert(unused_format_string.len == 0);
1636 if (start_type.ip_index != .none) {
1637 return writer.print("(intern index: {d})", .{@enumToInt(start_type.ip_index)});
1638 }
15621639 if (true) {
1563 // This is disabled to work around a bug where this function
1564 // recursively causes more generic function instantiations
1565 // resulting in an infinite loop in the compiler.
1640 // This is disabled to work around a stage2 bug where this function recursively
1641 // causes more generic function instantiations resulting in an infinite loop
1642 // in the compiler.
15661643 try writer.writeAll("[TODO fix internal compiler bug regarding dump]");
15671644 return;
15681645 }
......@@ -1656,10 +1733,6 @@ pub const Type = extern union {
16561733 .anyerror_void_error_union => return writer.writeAll("anyerror!void"),
16571734 .const_slice_u8 => return writer.writeAll("[]const u8"),
16581735 .const_slice_u8_sentinel_0 => return writer.writeAll("[:0]const u8"),
1659 .fn_noreturn_no_args => return writer.writeAll("fn() noreturn"),
1660 .fn_void_no_args => return writer.writeAll("fn() void"),
1661 .fn_naked_noreturn_no_args => return writer.writeAll("fn() callconv(.Naked) noreturn"),
1662 .fn_ccc_void_no_args => return writer.writeAll("fn() callconv(.C) void"),
16631736 .single_const_pointer_to_comptime_int => return writer.writeAll("*const comptime_int"),
16641737 .manyptr_u8 => return writer.writeAll("[*]u8"),
16651738 .manyptr_const_u8 => return writer.writeAll("[*]const u8"),
......@@ -1820,14 +1893,6 @@ pub const Type = extern union {
18201893 ty = pointee_type;
18211894 continue;
18221895 },
1823 .int_signed => {
1824 const bits = ty.castTag(.int_signed).?.data;
1825 return writer.print("i{d}", .{bits});
1826 },
1827 .int_unsigned => {
1828 const bits = ty.castTag(.int_unsigned).?.data;
1829 return writer.print("u{d}", .{bits});
1830 },
18311896 .optional => {
18321897 const child_type = ty.castTag(.optional).?.data;
18331898 try writer.writeByte('?');
......@@ -1938,6 +2003,26 @@ pub const Type = extern union {
19382003
19392004 /// Prints a name suitable for `@typeName`.
19402005 pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {
2006 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2007 .int_type => |int_type| {
2008 const sign_char: u8 = switch (int_type.signedness) {
2009 .signed => 'i',
2010 .unsigned => 'u',
2011 };
2012 return writer.print("{c}{d}", .{ sign_char, int_type.bits });
2013 },
2014 .ptr_type => @panic("TODO"),
2015 .array_type => @panic("TODO"),
2016 .vector_type => @panic("TODO"),
2017 .optional_type => @panic("TODO"),
2018 .error_union_type => @panic("TODO"),
2019 .simple_type => |s| return writer.writeAll(@tagName(s)),
2020 .struct_type => @panic("TODO"),
2021 .simple_value => unreachable,
2022 .extern_func => unreachable,
2023 .int => unreachable,
2024 .enum_tag => unreachable,
2025 };
19412026 const t = ty.tag();
19422027 switch (t) {
19432028 .inferred_alloc_const => unreachable,
......@@ -2041,10 +2126,6 @@ pub const Type = extern union {
20412126 .anyerror_void_error_union => try writer.writeAll("anyerror!void"),
20422127 .const_slice_u8 => try writer.writeAll("[]const u8"),
20432128 .const_slice_u8_sentinel_0 => try writer.writeAll("[:0]const u8"),
2044 .fn_noreturn_no_args => try writer.writeAll("fn() noreturn"),
2045 .fn_void_no_args => try writer.writeAll("fn() void"),
2046 .fn_naked_noreturn_no_args => try writer.writeAll("fn() callconv(.Naked) noreturn"),
2047 .fn_ccc_void_no_args => try writer.writeAll("fn() callconv(.C) void"),
20482129 .single_const_pointer_to_comptime_int => try writer.writeAll("*const comptime_int"),
20492130 .manyptr_u8 => try writer.writeAll("[*]u8"),
20502131 .manyptr_const_u8 => try writer.writeAll("[*]const u8"),
......@@ -2200,7 +2281,7 @@ pub const Type = extern union {
22002281 if (info.@"align" != 0) {
22012282 try writer.print("align({d}", .{info.@"align"});
22022283 } else {
2203 const alignment = info.pointee_type.abiAlignment(mod.getTarget());
2284 const alignment = info.pointee_type.abiAlignment(mod);
22042285 try writer.print("align({d}", .{alignment});
22052286 }
22062287
......@@ -2224,14 +2305,6 @@ pub const Type = extern union {
22242305 try print(info.pointee_type, writer, mod);
22252306 },
22262307
2227 .int_signed => {
2228 const bits = ty.castTag(.int_signed).?.data;
2229 return writer.print("i{d}", .{bits});
2230 },
2231 .int_unsigned => {
2232 const bits = ty.castTag(.int_unsigned).?.data;
2233 return writer.print("u{d}", .{bits});
2234 },
22352308 .optional => {
22362309 const child_type = ty.castTag(.optional).?.data;
22372310 try writer.writeByte('?');
......@@ -2317,10 +2390,6 @@ pub const Type = extern union {
23172390 .noreturn => return Value.initTag(.noreturn_type),
23182391 .null => return Value.initTag(.null_type),
23192392 .undefined => return Value.initTag(.undefined_type),
2320 .fn_noreturn_no_args => return Value.initTag(.fn_noreturn_no_args_type),
2321 .fn_void_no_args => return Value.initTag(.fn_void_no_args_type),
2322 .fn_naked_noreturn_no_args => return Value.initTag(.fn_naked_noreturn_no_args_type),
2323 .fn_ccc_void_no_args => return Value.initTag(.fn_ccc_void_no_args_type),
23242393 .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
23252394 .const_slice_u8 => return Value.initTag(.const_slice_u8_type),
23262395 .const_slice_u8_sentinel_0 => return Value.initTag(.const_slice_u8_sentinel_0_type),
......@@ -2360,9 +2429,24 @@ pub const Type = extern union {
23602429 /// may return false positives.
23612430 pub fn hasRuntimeBitsAdvanced(
23622431 ty: Type,
2432 mod: *const Module,
23632433 ignore_comptime_only: bool,
23642434 strat: AbiAlignmentAdvancedStrat,
23652435 ) RuntimeBitsError!bool {
2436 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2437 .int_type => |int_type| return int_type.bits != 0,
2438 .ptr_type => @panic("TODO"),
2439 .array_type => @panic("TODO"),
2440 .vector_type => @panic("TODO"),
2441 .optional_type => @panic("TODO"),
2442 .error_union_type => @panic("TODO"),
2443 .simple_type => @panic("TODO"),
2444 .struct_type => @panic("TODO"),
2445 .simple_value => unreachable,
2446 .extern_func => unreachable,
2447 .int => unreachable,
2448 .enum_tag => unreachable, // it's a value, not a type
2449 };
23662450 switch (ty.tag()) {
23672451 .u1,
23682452 .u8,
......@@ -2440,12 +2524,12 @@ pub const Type = extern union {
24402524 => {
24412525 if (ignore_comptime_only) {
24422526 return true;
2443 } else if (ty.childType().zigTypeTag() == .Fn) {
2527 } else if (ty.childType().zigTypeTag(mod) == .Fn) {
24442528 return !ty.childType().fnInfo().is_generic;
24452529 } else if (strat == .sema) {
24462530 return !(try strat.sema.typeRequiresComptime(ty));
24472531 } else {
2448 return !comptimeOnly(ty);
2532 return !comptimeOnly(ty, mod);
24492533 }
24502534 },
24512535
......@@ -2465,10 +2549,6 @@ pub const Type = extern union {
24652549 // Special exceptions have to be made when emitting functions due to
24662550 // this returning false.
24672551 .function,
2468 .fn_noreturn_no_args,
2469 .fn_void_no_args,
2470 .fn_naked_noreturn_no_args,
2471 .fn_ccc_void_no_args,
24722552 => return false,
24732553
24742554 .optional => {
......@@ -2483,7 +2563,7 @@ pub const Type = extern union {
24832563 } else if (strat == .sema) {
24842564 return !(try strat.sema.typeRequiresComptime(child_ty));
24852565 } else {
2486 return !comptimeOnly(child_ty);
2566 return !comptimeOnly(child_ty, mod);
24872567 }
24882568 },
24892569
......@@ -2502,7 +2582,7 @@ pub const Type = extern union {
25022582 }
25032583 for (struct_obj.fields.values()) |field| {
25042584 if (field.is_comptime) continue;
2505 if (try field.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, strat))
2585 if (try field.ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat))
25062586 return true;
25072587 } else {
25082588 return false;
......@@ -2511,16 +2591,15 @@ pub const Type = extern union {
25112591
25122592 .enum_full => {
25132593 const enum_full = ty.castTag(.enum_full).?.data;
2514 return enum_full.tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, strat);
2594 return enum_full.tag_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat);
25152595 },
25162596 .enum_simple => {
25172597 const enum_simple = ty.castTag(.enum_simple).?.data;
25182598 return enum_simple.fields.count() >= 2;
25192599 },
25202600 .enum_numbered, .enum_nonexhaustive => {
2521 var buffer: Payload.Bits = undefined;
2522 const int_tag_ty = ty.intTagType(&buffer);
2523 return int_tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, strat);
2601 const int_tag_ty = ty.intTagType();
2602 return int_tag_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat);
25242603 },
25252604
25262605 .@"union" => {
......@@ -2537,7 +2616,7 @@ pub const Type = extern union {
25372616 .lazy => if (!union_obj.haveFieldTypes()) return error.NeedLazy,
25382617 }
25392618 for (union_obj.fields.values()) |value| {
2540 if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, strat))
2619 if (try value.ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat))
25412620 return true;
25422621 } else {
25432622 return false;
......@@ -2545,7 +2624,7 @@ pub const Type = extern union {
25452624 },
25462625 .union_safety_tagged, .union_tagged => {
25472626 const union_obj = ty.cast(Payload.Union).?.data;
2548 if (try union_obj.tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, strat)) {
2627 if (try union_obj.tag_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) {
25492628 return true;
25502629 }
25512630
......@@ -2555,7 +2634,7 @@ pub const Type = extern union {
25552634 .lazy => if (!union_obj.haveFieldTypes()) return error.NeedLazy,
25562635 }
25572636 for (union_obj.fields.values()) |value| {
2558 if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, strat))
2637 if (try value.ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat))
25592638 return true;
25602639 } else {
25612640 return false;
......@@ -2563,18 +2642,16 @@ pub const Type = extern union {
25632642 },
25642643
25652644 .array, .vector => return ty.arrayLen() != 0 and
2566 try ty.elemType().hasRuntimeBitsAdvanced(ignore_comptime_only, strat),
2645 try ty.elemType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat),
25672646 .array_u8 => return ty.arrayLen() != 0,
2568 .array_sentinel => return ty.childType().hasRuntimeBitsAdvanced(ignore_comptime_only, strat),
2569
2570 .int_signed, .int_unsigned => return ty.cast(Payload.Bits).?.data != 0,
2647 .array_sentinel => return ty.childType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat),
25712648
25722649 .tuple, .anon_struct => {
25732650 const tuple = ty.tupleFields();
25742651 for (tuple.types, 0..) |field_ty, i| {
25752652 const val = tuple.values[i];
25762653 if (val.tag() != .unreachable_value) continue; // comptime field
2577 if (try field_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, strat)) return true;
2654 if (try field_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) return true;
25782655 }
25792656 return false;
25802657 },
......@@ -2588,7 +2665,21 @@ pub const Type = extern union {
25882665 /// true if and only if the type has a well-defined memory layout
25892666 /// readFrom/writeToMemory are supported only for types with a well-
25902667 /// defined memory layout
2591 pub fn hasWellDefinedLayout(ty: Type) bool {
2668 pub fn hasWellDefinedLayout(ty: Type, mod: *const Module) bool {
2669 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2670 .int_type => return true,
2671 .ptr_type => @panic("TODO"),
2672 .array_type => @panic("TODO"),
2673 .vector_type => @panic("TODO"),
2674 .optional_type => @panic("TODO"),
2675 .error_union_type => @panic("TODO"),
2676 .simple_type => @panic("TODO"),
2677 .struct_type => @panic("TODO"),
2678 .simple_value => unreachable,
2679 .extern_func => unreachable,
2680 .int => unreachable,
2681 .enum_tag => unreachable, // it's a value, not a type
2682 };
25922683 return switch (ty.tag()) {
25932684 .u1,
25942685 .u8,
......@@ -2626,8 +2717,6 @@ pub const Type = extern union {
26262717 .manyptr_const_u8_sentinel_0,
26272718 .array_u8,
26282719 .array_u8_sentinel_0,
2629 .int_signed,
2630 .int_unsigned,
26312720 .pointer,
26322721 .single_const_pointer,
26332722 .single_mut_pointer,
......@@ -2670,10 +2759,6 @@ pub const Type = extern union {
26702759 .enum_literal,
26712760 .type_info,
26722761 // These are function bodies, not function pointers.
2673 .fn_noreturn_no_args,
2674 .fn_void_no_args,
2675 .fn_naked_noreturn_no_args,
2676 .fn_ccc_void_no_args,
26772762 .function,
26782763 .const_slice_u8,
26792764 .const_slice_u8_sentinel_0,
......@@ -2698,25 +2783,25 @@ pub const Type = extern union {
26982783
26992784 .array,
27002785 .array_sentinel,
2701 => ty.childType().hasWellDefinedLayout(),
2786 => ty.childType().hasWellDefinedLayout(mod),
27022787
2703 .optional => ty.isPtrLikeOptional(),
2788 .optional => ty.isPtrLikeOptional(mod),
27042789 .@"struct" => ty.castTag(.@"struct").?.data.layout != .Auto,
27052790 .@"union", .union_safety_tagged => ty.cast(Payload.Union).?.data.layout != .Auto,
27062791 .union_tagged => false,
27072792 };
27082793 }
27092794
2710 pub fn hasRuntimeBits(ty: Type) bool {
2711 return hasRuntimeBitsAdvanced(ty, false, .eager) catch unreachable;
2795 pub fn hasRuntimeBits(ty: Type, mod: *const Module) bool {
2796 return hasRuntimeBitsAdvanced(ty, mod, false, .eager) catch unreachable;
27122797 }
27132798
2714 pub fn hasRuntimeBitsIgnoreComptime(ty: Type) bool {
2715 return hasRuntimeBitsAdvanced(ty, true, .eager) catch unreachable;
2799 pub fn hasRuntimeBitsIgnoreComptime(ty: Type, mod: *const Module) bool {
2800 return hasRuntimeBitsAdvanced(ty, mod, true, .eager) catch unreachable;
27162801 }
27172802
2718 pub fn isFnOrHasRuntimeBits(ty: Type) bool {
2719 switch (ty.zigTypeTag()) {
2803 pub fn isFnOrHasRuntimeBits(ty: Type, mod: *const Module) bool {
2804 switch (ty.zigTypeTag(mod)) {
27202805 .Fn => {
27212806 const fn_info = ty.fnInfo();
27222807 if (fn_info.is_generic) return false;
......@@ -2727,18 +2812,18 @@ pub const Type = extern union {
27272812 .Inline => return false,
27282813 else => {},
27292814 }
2730 if (fn_info.return_type.comptimeOnly()) return false;
2815 if (fn_info.return_type.comptimeOnly(mod)) return false;
27312816 return true;
27322817 },
2733 else => return ty.hasRuntimeBits(),
2818 else => return ty.hasRuntimeBits(mod),
27342819 }
27352820 }
27362821
27372822 /// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive.
2738 pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type) bool {
2739 return switch (ty.zigTypeTag()) {
2823 pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, mod: *const Module) bool {
2824 return switch (ty.zigTypeTag(mod)) {
27402825 .Fn => true,
2741 else => return ty.hasRuntimeBitsIgnoreComptime(),
2826 else => return ty.hasRuntimeBitsIgnoreComptime(mod),
27422827 };
27432828 }
27442829
......@@ -2761,11 +2846,11 @@ pub const Type = extern union {
27612846 }
27622847
27632848 /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit.
2764 pub fn ptrAlignment(ty: Type, target: Target) u32 {
2765 return ptrAlignmentAdvanced(ty, target, null) catch unreachable;
2849 pub fn ptrAlignment(ty: Type, mod: *const Module) u32 {
2850 return ptrAlignmentAdvanced(ty, mod, null) catch unreachable;
27662851 }
27672852
2768 pub fn ptrAlignmentAdvanced(ty: Type, target: Target, opt_sema: ?*Sema) !u32 {
2853 pub fn ptrAlignmentAdvanced(ty: Type, mod: *const Module, opt_sema: ?*Sema) !u32 {
27692854 switch (ty.tag()) {
27702855 .single_const_pointer,
27712856 .single_mut_pointer,
......@@ -2780,10 +2865,10 @@ pub const Type = extern union {
27802865 => {
27812866 const child_type = ty.cast(Payload.ElemType).?.data;
27822867 if (opt_sema) |sema| {
2783 const res = try child_type.abiAlignmentAdvanced(target, .{ .sema = sema });
2868 const res = try child_type.abiAlignmentAdvanced(mod, .{ .sema = sema });
27842869 return res.scalar;
27852870 }
2786 return (child_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;
2871 return (child_type.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
27872872 },
27882873
27892874 .manyptr_u8,
......@@ -2798,13 +2883,13 @@ pub const Type = extern union {
27982883 if (ptr_info.@"align" != 0) {
27992884 return ptr_info.@"align";
28002885 } else if (opt_sema) |sema| {
2801 const res = try ptr_info.pointee_type.abiAlignmentAdvanced(target, .{ .sema = sema });
2886 const res = try ptr_info.pointee_type.abiAlignmentAdvanced(mod, .{ .sema = sema });
28022887 return res.scalar;
28032888 } else {
2804 return (ptr_info.pointee_type.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;
2889 return (ptr_info.pointee_type.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
28052890 }
28062891 },
2807 .optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(target, opt_sema),
2892 .optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(mod, opt_sema),
28082893
28092894 else => unreachable,
28102895 }
......@@ -2843,13 +2928,13 @@ pub const Type = extern union {
28432928 }
28442929
28452930 /// Returns 0 for 0-bit types.
2846 pub fn abiAlignment(ty: Type, target: Target) u32 {
2847 return (ty.abiAlignmentAdvanced(target, .eager) catch unreachable).scalar;
2931 pub fn abiAlignment(ty: Type, mod: *const Module) u32 {
2932 return (ty.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
28482933 }
28492934
28502935 /// May capture a reference to `ty`.
2851 pub fn lazyAbiAlignment(ty: Type, target: Target, arena: Allocator) !Value {
2852 switch (try ty.abiAlignmentAdvanced(target, .{ .lazy = arena })) {
2936 pub fn lazyAbiAlignment(ty: Type, mod: *const Module, arena: Allocator) !Value {
2937 switch (try ty.abiAlignmentAdvanced(mod, .{ .lazy = arena })) {
28532938 .val => |val| return val,
28542939 .scalar => |x| return Value.Tag.int_u64.create(arena, x),
28552940 }
......@@ -2874,9 +2959,29 @@ pub const Type = extern union {
28742959 /// necessary, possibly returning a CompileError.
28752960 pub fn abiAlignmentAdvanced(
28762961 ty: Type,
2877 target: Target,
2962 mod: *const Module,
28782963 strat: AbiAlignmentAdvancedStrat,
28792964 ) Module.CompileError!AbiAlignmentAdvanced {
2965 const target = mod.getTarget();
2966
2967 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2968 .int_type => |int_type| {
2969 if (int_type.bits == 0) return AbiAlignmentAdvanced{ .scalar = 0 };
2970 return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(int_type.bits, target) };
2971 },
2972 .ptr_type => @panic("TODO"),
2973 .array_type => @panic("TODO"),
2974 .vector_type => @panic("TODO"),
2975 .optional_type => @panic("TODO"),
2976 .error_union_type => @panic("TODO"),
2977 .simple_type => @panic("TODO"),
2978 .struct_type => @panic("TODO"),
2979 .simple_value => unreachable,
2980 .extern_func => unreachable,
2981 .int => unreachable,
2982 .enum_tag => unreachable, // it's a value, not a type
2983 };
2984
28802985 const opt_sema = switch (strat) {
28812986 .sema => |sema| sema,
28822987 else => null,
......@@ -2902,12 +3007,6 @@ pub const Type = extern union {
29023007 .anyopaque,
29033008 => return AbiAlignmentAdvanced{ .scalar = 1 },
29043009
2905 .fn_noreturn_no_args, // represents machine code; not a pointer
2906 .fn_void_no_args, // represents machine code; not a pointer
2907 .fn_naked_noreturn_no_args, // represents machine code; not a pointer
2908 .fn_ccc_void_no_args, // represents machine code; not a pointer
2909 => return AbiAlignmentAdvanced{ .scalar = target_util.defaultFunctionAlignment(target) },
2910
29113010 // represents machine code; not a pointer
29123011 .function => {
29133012 const alignment = ty.castTag(.function).?.data.alignment;
......@@ -2958,12 +3057,11 @@ pub const Type = extern union {
29583057 .f80 => switch (target.c_type_bit_size(.longdouble)) {
29593058 80 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longdouble) },
29603059 else => {
2961 var payload: Payload.Bits = .{
2962 .base = .{ .tag = .int_unsigned },
2963 .data = 80,
3060 const u80_ty: Type = .{
3061 .ip_index = .u80_type,
3062 .legacy = undefined,
29643063 };
2965 const u80_ty = initPayload(&payload.base);
2966 return AbiAlignmentAdvanced{ .scalar = abiAlignment(u80_ty, target) };
3064 return AbiAlignmentAdvanced{ .scalar = abiAlignment(u80_ty, mod) };
29673065 },
29683066 },
29693067 .f128 => switch (target.c_type_bit_size(.longdouble)) {
......@@ -2980,11 +3078,11 @@ pub const Type = extern union {
29803078 .error_set_merged,
29813079 => return AbiAlignmentAdvanced{ .scalar = 2 },
29823080
2983 .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat),
3081 .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(mod, strat),
29843082
29853083 .vector => {
29863084 const len = ty.arrayLen();
2987 const bits = try bitSizeAdvanced(ty.elemType(), target, opt_sema);
3085 const bits = try bitSizeAdvanced(ty.elemType(), mod, opt_sema);
29883086 const bytes = ((bits * len) + 7) / 8;
29893087 const alignment = std.math.ceilPowerOfTwoAssert(u64, bytes);
29903088 return AbiAlignmentAdvanced{ .scalar = @intCast(u32, alignment) };
......@@ -2996,34 +3094,28 @@ pub const Type = extern union {
29963094 .i64, .u64 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(64, target) },
29973095 .u128, .i128 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(128, target) },
29983096
2999 .int_signed, .int_unsigned => {
3000 const bits: u16 = ty.cast(Payload.Bits).?.data;
3001 if (bits == 0) return AbiAlignmentAdvanced{ .scalar = 0 };
3002 return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(bits, target) };
3003 },
3004
30053097 .optional => {
30063098 var buf: Payload.ElemType = undefined;
30073099 const child_type = ty.optionalChild(&buf);
30083100
3009 switch (child_type.zigTypeTag()) {
3101 switch (child_type.zigTypeTag(mod)) {
30103102 .Pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },
3011 .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, target, strat),
3103 .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, mod, strat),
30123104 .NoReturn => return AbiAlignmentAdvanced{ .scalar = 0 },
30133105 else => {},
30143106 }
30153107
30163108 switch (strat) {
30173109 .eager, .sema => {
3018 if (!(child_type.hasRuntimeBitsAdvanced(false, strat) catch |err| switch (err) {
3110 if (!(child_type.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
30193111 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
30203112 else => |e| return e,
30213113 })) {
30223114 return AbiAlignmentAdvanced{ .scalar = 1 };
30233115 }
3024 return child_type.abiAlignmentAdvanced(target, strat);
3116 return child_type.abiAlignmentAdvanced(mod, strat);
30253117 },
3026 .lazy => |arena| switch (try child_type.abiAlignmentAdvanced(target, strat)) {
3118 .lazy => |arena| switch (try child_type.abiAlignmentAdvanced(mod, strat)) {
30273119 .scalar => |x| return AbiAlignmentAdvanced{ .scalar = @max(x, 1) },
30283120 .val => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) },
30293121 },
......@@ -3034,10 +3126,10 @@ pub const Type = extern union {
30343126 // This code needs to be kept in sync with the equivalent switch prong
30353127 // in abiSizeAdvanced.
30363128 const data = ty.castTag(.error_union).?.data;
3037 const code_align = abiAlignment(Type.anyerror, target);
3129 const code_align = abiAlignment(Type.anyerror, mod);
30383130 switch (strat) {
30393131 .eager, .sema => {
3040 if (!(data.payload.hasRuntimeBitsAdvanced(false, strat) catch |err| switch (err) {
3132 if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
30413133 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
30423134 else => |e| return e,
30433135 })) {
......@@ -3045,11 +3137,11 @@ pub const Type = extern union {
30453137 }
30463138 return AbiAlignmentAdvanced{ .scalar = @max(
30473139 code_align,
3048 (try data.payload.abiAlignmentAdvanced(target, strat)).scalar,
3140 (try data.payload.abiAlignmentAdvanced(mod, strat)).scalar,
30493141 ) };
30503142 },
30513143 .lazy => |arena| {
3052 switch (try data.payload.abiAlignmentAdvanced(target, strat)) {
3144 switch (try data.payload.abiAlignmentAdvanced(mod, strat)) {
30533145 .scalar => |payload_align| {
30543146 return AbiAlignmentAdvanced{
30553147 .scalar = @max(code_align, payload_align),
......@@ -3089,20 +3181,20 @@ pub const Type = extern union {
30893181 .eager => {},
30903182 }
30913183 assert(struct_obj.haveLayout());
3092 return AbiAlignmentAdvanced{ .scalar = struct_obj.backing_int_ty.abiAlignment(target) };
3184 return AbiAlignmentAdvanced{ .scalar = struct_obj.backing_int_ty.abiAlignment(mod) };
30933185 }
30943186
30953187 const fields = ty.structFields();
30963188 var big_align: u32 = 0;
30973189 for (fields.values()) |field| {
3098 if (!(field.ty.hasRuntimeBitsAdvanced(false, strat) catch |err| switch (err) {
3190 if (!(field.ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
30993191 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
31003192 else => |e| return e,
31013193 })) continue;
31023194
31033195 const field_align = if (field.abi_align != 0)
31043196 field.abi_align
3105 else switch (try field.ty.abiAlignmentAdvanced(target, strat)) {
3197 else switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
31063198 .scalar => |a| a,
31073199 .val => switch (strat) {
31083200 .eager => unreachable, // struct layout not resolved
......@@ -3114,7 +3206,7 @@ pub const Type = extern union {
31143206
31153207 // This logic is duplicated in Module.Struct.Field.alignment.
31163208 if (struct_obj.layout == .Extern or target.ofmt == .c) {
3117 if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) {
3209 if (field.ty.isAbiInt(mod) and field.ty.intInfo(mod).bits >= 128) {
31183210 // The C ABI requires 128 bit integer fields of structs
31193211 // to be 16-bytes aligned.
31203212 big_align = @max(big_align, 16);
......@@ -3130,9 +3222,9 @@ pub const Type = extern union {
31303222 for (tuple.types, 0..) |field_ty, i| {
31313223 const val = tuple.values[i];
31323224 if (val.tag() != .unreachable_value) continue; // comptime field
3133 if (!(field_ty.hasRuntimeBits())) continue;
3225 if (!(field_ty.hasRuntimeBits(mod))) continue;
31343226
3135 switch (try field_ty.abiAlignmentAdvanced(target, strat)) {
3227 switch (try field_ty.abiAlignmentAdvanced(mod, strat)) {
31363228 .scalar => |field_align| big_align = @max(big_align, field_align),
31373229 .val => switch (strat) {
31383230 .eager => unreachable, // field type alignment not resolved
......@@ -3145,17 +3237,16 @@ pub const Type = extern union {
31453237 },
31463238
31473239 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {
3148 var buffer: Payload.Bits = undefined;
3149 const int_tag_ty = ty.intTagType(&buffer);
3150 return AbiAlignmentAdvanced{ .scalar = int_tag_ty.abiAlignment(target) };
3240 const int_tag_ty = ty.intTagType();
3241 return AbiAlignmentAdvanced{ .scalar = int_tag_ty.abiAlignment(mod) };
31513242 },
31523243 .@"union" => {
31533244 const union_obj = ty.castTag(.@"union").?.data;
3154 return abiAlignmentAdvancedUnion(ty, target, strat, union_obj, false);
3245 return abiAlignmentAdvancedUnion(ty, mod, strat, union_obj, false);
31553246 },
31563247 .union_safety_tagged, .union_tagged => {
31573248 const union_obj = ty.cast(Payload.Union).?.data;
3158 return abiAlignmentAdvancedUnion(ty, target, strat, union_obj, true);
3249 return abiAlignmentAdvancedUnion(ty, mod, strat, union_obj, true);
31593250 },
31603251
31613252 .empty_struct,
......@@ -3181,7 +3272,7 @@ pub const Type = extern union {
31813272
31823273 pub fn abiAlignmentAdvancedUnion(
31833274 ty: Type,
3184 target: Target,
3275 mod: *const Module,
31853276 strat: AbiAlignmentAdvancedStrat,
31863277 union_obj: *Module.Union,
31873278 have_tag: bool,
......@@ -3195,6 +3286,7 @@ pub const Type = extern union {
31953286 // We'll guess "pointer-aligned", if the union has an
31963287 // underaligned pointer field then some allocations
31973288 // might require explicit alignment.
3289 const target = mod.getTarget();
31983290 return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) };
31993291 }
32003292 _ = try sema.resolveTypeFields(ty);
......@@ -3206,23 +3298,23 @@ pub const Type = extern union {
32063298 };
32073299 if (union_obj.fields.count() == 0) {
32083300 if (have_tag) {
3209 return abiAlignmentAdvanced(union_obj.tag_ty, target, strat);
3301 return abiAlignmentAdvanced(union_obj.tag_ty, mod, strat);
32103302 } else {
32113303 return AbiAlignmentAdvanced{ .scalar = @boolToInt(union_obj.layout == .Extern) };
32123304 }
32133305 }
32143306
32153307 var max_align: u32 = 0;
3216 if (have_tag) max_align = union_obj.tag_ty.abiAlignment(target);
3308 if (have_tag) max_align = union_obj.tag_ty.abiAlignment(mod);
32173309 for (union_obj.fields.values()) |field| {
3218 if (!(field.ty.hasRuntimeBitsAdvanced(false, strat) catch |err| switch (err) {
3310 if (!(field.ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
32193311 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
32203312 else => |e| return e,
32213313 })) continue;
32223314
32233315 const field_align = if (field.abi_align != 0)
32243316 field.abi_align
3225 else switch (try field.ty.abiAlignmentAdvanced(target, strat)) {
3317 else switch (try field.ty.abiAlignmentAdvanced(mod, strat)) {
32263318 .scalar => |a| a,
32273319 .val => switch (strat) {
32283320 .eager => unreachable, // struct layout not resolved
......@@ -3236,8 +3328,8 @@ pub const Type = extern union {
32363328 }
32373329
32383330 /// May capture a reference to `ty`.
3239 pub fn lazyAbiSize(ty: Type, target: Target, arena: Allocator) !Value {
3240 switch (try ty.abiSizeAdvanced(target, .{ .lazy = arena })) {
3331 pub fn lazyAbiSize(ty: Type, mod: *const Module, arena: Allocator) !Value {
3332 switch (try ty.abiSizeAdvanced(mod, .{ .lazy = arena })) {
32413333 .val => |val| return val,
32423334 .scalar => |x| return Value.Tag.int_u64.create(arena, x),
32433335 }
......@@ -3245,8 +3337,8 @@ pub const Type = extern union {
32453337
32463338 /// Asserts the type has the ABI size already resolved.
32473339 /// Types that return false for hasRuntimeBits() return 0.
3248 pub fn abiSize(ty: Type, target: Target) u64 {
3249 return (abiSizeAdvanced(ty, target, .eager) catch unreachable).scalar;
3340 pub fn abiSize(ty: Type, mod: *const Module) u64 {
3341 return (abiSizeAdvanced(ty, mod, .eager) catch unreachable).scalar;
32503342 }
32513343
32523344 const AbiSizeAdvanced = union(enum) {
......@@ -3262,14 +3354,30 @@ pub const Type = extern union {
32623354 /// necessary, possibly returning a CompileError.
32633355 pub fn abiSizeAdvanced(
32643356 ty: Type,
3265 target: Target,
3357 mod: *const Module,
32663358 strat: AbiAlignmentAdvancedStrat,
32673359 ) Module.CompileError!AbiSizeAdvanced {
3360 const target = mod.getTarget();
3361
3362 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3363 .int_type => |int_type| {
3364 if (int_type.bits == 0) return AbiSizeAdvanced{ .scalar = 0 };
3365 return AbiSizeAdvanced{ .scalar = intAbiSize(int_type.bits, target) };
3366 },
3367 .ptr_type => @panic("TODO"),
3368 .array_type => @panic("TODO"),
3369 .vector_type => @panic("TODO"),
3370 .optional_type => @panic("TODO"),
3371 .error_union_type => @panic("TODO"),
3372 .simple_type => @panic("TODO"),
3373 .struct_type => @panic("TODO"),
3374 .simple_value => unreachable,
3375 .extern_func => unreachable,
3376 .int => unreachable,
3377 .enum_tag => unreachable, // it's a value, not a type
3378 };
3379
32683380 switch (ty.tag()) {
3269 .fn_noreturn_no_args => unreachable, // represents machine code; not a pointer
3270 .fn_void_no_args => unreachable, // represents machine code; not a pointer
3271 .fn_naked_noreturn_no_args => unreachable, // represents machine code; not a pointer
3272 .fn_ccc_void_no_args => unreachable, // represents machine code; not a pointer
32733381 .function => unreachable, // represents machine code; not a pointer
32743382 .@"opaque" => unreachable, // no size available
32753383 .noreturn => unreachable,
......@@ -3308,7 +3416,7 @@ pub const Type = extern union {
33083416 .eager => {},
33093417 }
33103418 assert(struct_obj.haveLayout());
3311 return AbiSizeAdvanced{ .scalar = struct_obj.backing_int_ty.abiSize(target) };
3419 return AbiSizeAdvanced{ .scalar = struct_obj.backing_int_ty.abiSize(mod) };
33123420 },
33133421 else => {
33143422 switch (strat) {
......@@ -3327,22 +3435,21 @@ pub const Type = extern union {
33273435 if (field_count == 0) {
33283436 return AbiSizeAdvanced{ .scalar = 0 };
33293437 }
3330 return AbiSizeAdvanced{ .scalar = ty.structFieldOffset(field_count, target) };
3438 return AbiSizeAdvanced{ .scalar = ty.structFieldOffset(field_count, mod) };
33313439 },
33323440 },
33333441
33343442 .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {
3335 var buffer: Payload.Bits = undefined;
3336 const int_tag_ty = ty.intTagType(&buffer);
3337 return AbiSizeAdvanced{ .scalar = int_tag_ty.abiSize(target) };
3443 const int_tag_ty = ty.intTagType();
3444 return AbiSizeAdvanced{ .scalar = int_tag_ty.abiSize(mod) };
33383445 },
33393446 .@"union" => {
33403447 const union_obj = ty.castTag(.@"union").?.data;
3341 return abiSizeAdvancedUnion(ty, target, strat, union_obj, false);
3448 return abiSizeAdvancedUnion(ty, mod, strat, union_obj, false);
33423449 },
33433450 .union_safety_tagged, .union_tagged => {
33443451 const union_obj = ty.cast(Payload.Union).?.data;
3345 return abiSizeAdvancedUnion(ty, target, strat, union_obj, true);
3452 return abiSizeAdvancedUnion(ty, mod, strat, union_obj, true);
33463453 },
33473454
33483455 .u1,
......@@ -3361,7 +3468,7 @@ pub const Type = extern union {
33613468 .array_u8_sentinel_0 => return AbiSizeAdvanced{ .scalar = ty.castTag(.array_u8_sentinel_0).?.data + 1 },
33623469 .array => {
33633470 const payload = ty.castTag(.array).?.data;
3364 switch (try payload.elem_type.abiSizeAdvanced(target, strat)) {
3471 switch (try payload.elem_type.abiSizeAdvanced(mod, strat)) {
33653472 .scalar => |elem_size| return AbiSizeAdvanced{ .scalar = payload.len * elem_size },
33663473 .val => switch (strat) {
33673474 .sema => unreachable,
......@@ -3372,7 +3479,7 @@ pub const Type = extern union {
33723479 },
33733480 .array_sentinel => {
33743481 const payload = ty.castTag(.array_sentinel).?.data;
3375 switch (try payload.elem_type.abiSizeAdvanced(target, strat)) {
3482 switch (try payload.elem_type.abiSizeAdvanced(mod, strat)) {
33763483 .scalar => |elem_size| return AbiSizeAdvanced{ .scalar = (payload.len + 1) * elem_size },
33773484 .val => switch (strat) {
33783485 .sema => unreachable,
......@@ -3391,10 +3498,10 @@ pub const Type = extern union {
33913498 .val = try Value.Tag.lazy_size.create(arena, ty),
33923499 },
33933500 };
3394 const elem_bits = try payload.elem_type.bitSizeAdvanced(target, opt_sema);
3501 const elem_bits = try payload.elem_type.bitSizeAdvanced(mod, opt_sema);
33953502 const total_bits = elem_bits * payload.len;
33963503 const total_bytes = (total_bits + 7) / 8;
3397 const alignment = switch (try ty.abiAlignmentAdvanced(target, strat)) {
3504 const alignment = switch (try ty.abiAlignmentAdvanced(mod, strat)) {
33983505 .scalar => |x| x,
33993506 .val => return AbiSizeAdvanced{
34003507 .val = try Value.Tag.lazy_size.create(strat.lazy, ty),
......@@ -3450,12 +3557,11 @@ pub const Type = extern union {
34503557 .f80 => switch (target.c_type_bit_size(.longdouble)) {
34513558 80 => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) },
34523559 else => {
3453 var payload: Payload.Bits = .{
3454 .base = .{ .tag = .int_unsigned },
3455 .data = 80,
3560 const u80_ty: Type = .{
3561 .ip_index = .u80_type,
3562 .legacy = undefined,
34563563 };
3457 const u80_ty = initPayload(&payload.base);
3458 return AbiSizeAdvanced{ .scalar = abiSize(u80_ty, target) };
3564 return AbiSizeAdvanced{ .scalar = abiSize(u80_ty, mod) };
34593565 },
34603566 },
34613567
......@@ -3473,11 +3579,6 @@ pub const Type = extern union {
34733579 .i32, .u32 => return AbiSizeAdvanced{ .scalar = intAbiSize(32, target) },
34743580 .i64, .u64 => return AbiSizeAdvanced{ .scalar = intAbiSize(64, target) },
34753581 .u128, .i128 => return AbiSizeAdvanced{ .scalar = intAbiSize(128, target) },
3476 .int_signed, .int_unsigned => {
3477 const bits: u16 = ty.cast(Payload.Bits).?.data;
3478 if (bits == 0) return AbiSizeAdvanced{ .scalar = 0 };
3479 return AbiSizeAdvanced{ .scalar = intAbiSize(bits, target) };
3480 },
34813582
34823583 .optional => {
34833584 var buf: Payload.ElemType = undefined;
......@@ -3487,16 +3588,16 @@ pub const Type = extern union {
34873588 return AbiSizeAdvanced{ .scalar = 0 };
34883589 }
34893590
3490 if (!(child_type.hasRuntimeBitsAdvanced(false, strat) catch |err| switch (err) {
3591 if (!(child_type.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
34913592 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },
34923593 else => |e| return e,
34933594 })) return AbiSizeAdvanced{ .scalar = 1 };
34943595
3495 if (ty.optionalReprIsPayload()) {
3496 return abiSizeAdvanced(child_type, target, strat);
3596 if (ty.optionalReprIsPayload(mod)) {
3597 return abiSizeAdvanced(child_type, mod, strat);
34973598 }
34983599
3499 const payload_size = switch (try child_type.abiSizeAdvanced(target, strat)) {
3600 const payload_size = switch (try child_type.abiSizeAdvanced(mod, strat)) {
35003601 .scalar => |elem_size| elem_size,
35013602 .val => switch (strat) {
35023603 .sema => unreachable,
......@@ -3510,7 +3611,7 @@ pub const Type = extern union {
35103611 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal
35113612 // to the child type's ABI alignment.
35123613 return AbiSizeAdvanced{
3513 .scalar = child_type.abiAlignment(target) + payload_size,
3614 .scalar = child_type.abiAlignment(mod) + payload_size,
35143615 };
35153616 },
35163617
......@@ -3518,17 +3619,17 @@ pub const Type = extern union {
35183619 // This code needs to be kept in sync with the equivalent switch prong
35193620 // in abiAlignmentAdvanced.
35203621 const data = ty.castTag(.error_union).?.data;
3521 const code_size = abiSize(Type.anyerror, target);
3522 if (!(data.payload.hasRuntimeBitsAdvanced(false, strat) catch |err| switch (err) {
3622 const code_size = abiSize(Type.anyerror, mod);
3623 if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
35233624 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },
35243625 else => |e| return e,
35253626 })) {
35263627 // Same as anyerror.
35273628 return AbiSizeAdvanced{ .scalar = code_size };
35283629 }
3529 const code_align = abiAlignment(Type.anyerror, target);
3530 const payload_align = abiAlignment(data.payload, target);
3531 const payload_size = switch (try data.payload.abiSizeAdvanced(target, strat)) {
3630 const code_align = abiAlignment(Type.anyerror, mod);
3631 const payload_align = abiAlignment(data.payload, mod);
3632 const payload_size = switch (try data.payload.abiSizeAdvanced(mod, strat)) {
35323633 .scalar => |elem_size| elem_size,
35333634 .val => switch (strat) {
35343635 .sema => unreachable,
......@@ -3556,7 +3657,7 @@ pub const Type = extern union {
35563657
35573658 pub fn abiSizeAdvancedUnion(
35583659 ty: Type,
3559 target: Target,
3660 mod: *const Module,
35603661 strat: AbiAlignmentAdvancedStrat,
35613662 union_obj: *Module.Union,
35623663 have_tag: bool,
......@@ -3570,7 +3671,7 @@ pub const Type = extern union {
35703671 },
35713672 .eager => {},
35723673 }
3573 return AbiSizeAdvanced{ .scalar = union_obj.abiSize(target, have_tag) };
3674 return AbiSizeAdvanced{ .scalar = union_obj.abiSize(mod, have_tag) };
35743675 }
35753676
35763677 fn intAbiSize(bits: u16, target: Target) u64 {
......@@ -3585,8 +3686,8 @@ pub const Type = extern union {
35853686 );
35863687 }
35873688
3588 pub fn bitSize(ty: Type, target: Target) u64 {
3589 return bitSizeAdvanced(ty, target, null) catch unreachable;
3689 pub fn bitSize(ty: Type, mod: *const Module) u64 {
3690 return bitSizeAdvanced(ty, mod, null) catch unreachable;
35903691 }
35913692
35923693 /// If you pass `opt_sema`, any recursive type resolutions will happen if
......@@ -3594,15 +3695,29 @@ pub const Type = extern union {
35943695 /// the type is fully resolved, and there will be no error, guaranteed.
35953696 pub fn bitSizeAdvanced(
35963697 ty: Type,
3597 target: Target,
3698 mod: *const Module,
35983699 opt_sema: ?*Sema,
35993700 ) Module.CompileError!u64 {
3701 const target = mod.getTarget();
3702
3703 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3704 .int_type => |int_type| return int_type.bits,
3705 .ptr_type => @panic("TODO"),
3706 .array_type => @panic("TODO"),
3707 .vector_type => @panic("TODO"),
3708 .optional_type => @panic("TODO"),
3709 .error_union_type => @panic("TODO"),
3710 .simple_type => @panic("TODO"),
3711 .struct_type => @panic("TODO"),
3712 .simple_value => unreachable,
3713 .extern_func => unreachable,
3714 .int => unreachable,
3715 .enum_tag => unreachable, // it's a value, not a type
3716 };
3717
36003718 const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
3719
36013720 switch (ty.tag()) {
3602 .fn_noreturn_no_args => unreachable, // represents machine code; not a pointer
3603 .fn_void_no_args => unreachable, // represents machine code; not a pointer
3604 .fn_naked_noreturn_no_args => unreachable, // represents machine code; not a pointer
3605 .fn_ccc_void_no_args => unreachable, // represents machine code; not a pointer
36063721 .function => unreachable, // represents machine code; not a pointer
36073722 .anyopaque => unreachable,
36083723 .type => unreachable,
......@@ -3633,68 +3748,67 @@ pub const Type = extern union {
36333748 .@"struct" => {
36343749 const struct_obj = ty.castTag(.@"struct").?.data;
36353750 if (struct_obj.layout != .Packed) {
3636 return (try ty.abiSizeAdvanced(target, strat)).scalar * 8;
3751 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
36373752 }
36383753 if (opt_sema) |sema| _ = try sema.resolveTypeLayout(ty);
36393754 assert(struct_obj.haveLayout());
3640 return try struct_obj.backing_int_ty.bitSizeAdvanced(target, opt_sema);
3755 return try struct_obj.backing_int_ty.bitSizeAdvanced(mod, opt_sema);
36413756 },
36423757
36433758 .tuple, .anon_struct => {
36443759 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
36453760 if (ty.containerLayout() != .Packed) {
3646 return (try ty.abiSizeAdvanced(target, strat)).scalar * 8;
3761 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
36473762 }
36483763 var total: u64 = 0;
36493764 for (ty.tupleFields().types) |field_ty| {
3650 total += try bitSizeAdvanced(field_ty, target, opt_sema);
3765 total += try bitSizeAdvanced(field_ty, mod, opt_sema);
36513766 }
36523767 return total;
36533768 },
36543769
36553770 .enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {
3656 var buffer: Payload.Bits = undefined;
3657 const int_tag_ty = ty.intTagType(&buffer);
3658 return try bitSizeAdvanced(int_tag_ty, target, opt_sema);
3771 const int_tag_ty = ty.intTagType();
3772 return try bitSizeAdvanced(int_tag_ty, mod, opt_sema);
36593773 },
36603774
36613775 .@"union", .union_safety_tagged, .union_tagged => {
36623776 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
36633777 if (ty.containerLayout() != .Packed) {
3664 return (try ty.abiSizeAdvanced(target, strat)).scalar * 8;
3778 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
36653779 }
36663780 const union_obj = ty.cast(Payload.Union).?.data;
36673781 assert(union_obj.haveFieldTypes());
36683782
36693783 var size: u64 = 0;
36703784 for (union_obj.fields.values()) |field| {
3671 size = @max(size, try bitSizeAdvanced(field.ty, target, opt_sema));
3785 size = @max(size, try bitSizeAdvanced(field.ty, mod, opt_sema));
36723786 }
36733787 return size;
36743788 },
36753789
36763790 .vector => {
36773791 const payload = ty.castTag(.vector).?.data;
3678 const elem_bit_size = try bitSizeAdvanced(payload.elem_type, target, opt_sema);
3792 const elem_bit_size = try bitSizeAdvanced(payload.elem_type, mod, opt_sema);
36793793 return elem_bit_size * payload.len;
36803794 },
36813795 .array_u8 => return 8 * ty.castTag(.array_u8).?.data,
36823796 .array_u8_sentinel_0 => return 8 * (ty.castTag(.array_u8_sentinel_0).?.data + 1),
36833797 .array => {
36843798 const payload = ty.castTag(.array).?.data;
3685 const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
3799 const elem_size = std.math.max(payload.elem_type.abiAlignment(mod), payload.elem_type.abiSize(mod));
36863800 if (elem_size == 0 or payload.len == 0)
36873801 return @as(u64, 0);
3688 const elem_bit_size = try bitSizeAdvanced(payload.elem_type, target, opt_sema);
3802 const elem_bit_size = try bitSizeAdvanced(payload.elem_type, mod, opt_sema);
36893803 return (payload.len - 1) * 8 * elem_size + elem_bit_size;
36903804 },
36913805 .array_sentinel => {
36923806 const payload = ty.castTag(.array_sentinel).?.data;
36933807 const elem_size = std.math.max(
3694 payload.elem_type.abiAlignment(target),
3695 payload.elem_type.abiSize(target),
3808 payload.elem_type.abiAlignment(mod),
3809 payload.elem_type.abiSize(mod),
36963810 );
3697 const elem_bit_size = try bitSizeAdvanced(payload.elem_type, target, opt_sema);
3811 const elem_bit_size = try bitSizeAdvanced(payload.elem_type, mod, opt_sema);
36983812 return payload.len * 8 * elem_size + elem_bit_size;
36993813 },
37003814
......@@ -3757,12 +3871,10 @@ pub const Type = extern union {
37573871 .error_set_merged,
37583872 => return 16, // TODO revisit this when we have the concept of the error tag type
37593873
3760 .int_signed, .int_unsigned => return ty.cast(Payload.Bits).?.data,
3761
37623874 .optional, .error_union => {
37633875 // Optionals and error unions are not packed so their bitsize
37643876 // includes padding bits.
3765 return (try abiSizeAdvanced(ty, target, strat)).scalar * 8;
3877 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
37663878 },
37673879
37683880 .atomic_order,
......@@ -3782,8 +3894,8 @@ pub const Type = extern union {
37823894
37833895 /// Returns true if the type's layout is already resolved and it is safe
37843896 /// to use `abiSize`, `abiAlignment` and `bitSize` on it.
3785 pub fn layoutIsResolved(ty: Type) bool {
3786 switch (ty.zigTypeTag()) {
3897 pub fn layoutIsResolved(ty: Type, mod: *const Module) bool {
3898 switch (ty.zigTypeTag(mod)) {
37873899 .Struct => {
37883900 if (ty.castTag(.@"struct")) |struct_ty| {
37893901 return struct_ty.data.haveLayout();
......@@ -3798,16 +3910,16 @@ pub const Type = extern union {
37983910 },
37993911 .Array => {
38003912 if (ty.arrayLenIncludingSentinel() == 0) return true;
3801 return ty.childType().layoutIsResolved();
3913 return ty.childType().layoutIsResolved(mod);
38023914 },
38033915 .Optional => {
38043916 var buf: Type.Payload.ElemType = undefined;
38053917 const payload_ty = ty.optionalChild(&buf);
3806 return payload_ty.layoutIsResolved();
3918 return payload_ty.layoutIsResolved(mod);
38073919 },
38083920 .ErrorUnion => {
38093921 const payload_ty = ty.errorUnionPayload();
3810 return payload_ty.layoutIsResolved();
3922 return payload_ty.layoutIsResolved(mod);
38113923 },
38123924 else => return true,
38133925 }
......@@ -3994,13 +4106,13 @@ pub const Type = extern union {
39944106 };
39954107 }
39964108
3997 pub fn isAllowzeroPtr(self: Type) bool {
4109 pub fn isAllowzeroPtr(self: Type, mod: *const Module) bool {
39984110 return switch (self.tag()) {
39994111 .pointer => {
40004112 const payload = self.castTag(.pointer).?.data;
40014113 return payload.@"allowzero";
40024114 },
4003 else => return self.zigTypeTag() == .Optional,
4115 else => return self.zigTypeTag(mod) == .Optional,
40044116 };
40054117 }
40064118
......@@ -4016,7 +4128,7 @@ pub const Type = extern union {
40164128 };
40174129 }
40184130
4019 pub fn isPtrAtRuntime(self: Type) bool {
4131 pub fn isPtrAtRuntime(self: Type, mod: *const Module) bool {
40204132 switch (self.tag()) {
40214133 .c_const_pointer,
40224134 .c_mut_pointer,
......@@ -4040,7 +4152,7 @@ pub const Type = extern union {
40404152 .optional => {
40414153 var buf: Payload.ElemType = undefined;
40424154 const child_type = self.optionalChild(&buf);
4043 if (child_type.zigTypeTag() != .Pointer) return false;
4155 if (child_type.zigTypeTag(mod) != .Pointer) return false;
40444156 const info = child_type.ptrInfo().data;
40454157 switch (info.size) {
40464158 .Slice, .C => return false,
......@@ -4054,15 +4166,15 @@ pub const Type = extern union {
40544166
40554167 /// For pointer-like optionals, returns true, otherwise returns the allowzero property
40564168 /// of pointers.
4057 pub fn ptrAllowsZero(ty: Type) bool {
4058 if (ty.isPtrLikeOptional()) {
4169 pub fn ptrAllowsZero(ty: Type, mod: *const Module) bool {
4170 if (ty.isPtrLikeOptional(mod)) {
40594171 return true;
40604172 }
40614173 return ty.ptrInfo().data.@"allowzero";
40624174 }
40634175
40644176 /// See also `isPtrLikeOptional`.
4065 pub fn optionalReprIsPayload(ty: Type) bool {
4177 pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool {
40664178 switch (ty.tag()) {
40674179 .optional_single_const_pointer,
40684180 .optional_single_mut_pointer,
......@@ -4072,7 +4184,7 @@ pub const Type = extern union {
40724184
40734185 .optional => {
40744186 const child_ty = ty.castTag(.optional).?.data;
4075 switch (child_ty.zigTypeTag()) {
4187 switch (child_ty.zigTypeTag(mod)) {
40764188 .Pointer => {
40774189 const info = child_ty.ptrInfo().data;
40784190 switch (info.size) {
......@@ -4093,7 +4205,7 @@ pub const Type = extern union {
40934205
40944206 /// Returns true if the type is optional and would be lowered to a single pointer
40954207 /// address value, using 0 for null. Note that this returns true for C pointers.
4096 pub fn isPtrLikeOptional(self: Type) bool {
4208 pub fn isPtrLikeOptional(self: Type, mod: *const Module) bool {
40974209 switch (self.tag()) {
40984210 .optional_single_const_pointer,
40994211 .optional_single_mut_pointer,
......@@ -4103,7 +4215,7 @@ pub const Type = extern union {
41034215
41044216 .optional => {
41054217 const child_ty = self.castTag(.optional).?.data;
4106 if (child_ty.zigTypeTag() != .Pointer) return false;
4218 if (child_ty.zigTypeTag(mod) != .Pointer) return false;
41074219 const info = child_ty.ptrInfo().data;
41084220 switch (info.size) {
41094221 .Slice, .C => return false,
......@@ -4166,7 +4278,7 @@ pub const Type = extern union {
41664278 /// For [N]T, returns T.
41674279 /// For []T, returns T.
41684280 /// For anyframe->T, returns T.
4169 pub fn elemType2(ty: Type) Type {
4281 pub fn elemType2(ty: Type, mod: *const Module) Type {
41704282 return switch (ty.tag()) {
41714283 .vector => ty.castTag(.vector).?.data.elem_type,
41724284 .array => ty.castTag(.array).?.data.elem_type,
......@@ -4181,7 +4293,7 @@ pub const Type = extern union {
41814293
41824294 .single_const_pointer,
41834295 .single_mut_pointer,
4184 => ty.castPointer().?.data.shallowElemType(),
4296 => ty.castPointer().?.data.shallowElemType(mod),
41854297
41864298 .array_u8,
41874299 .array_u8_sentinel_0,
......@@ -4197,7 +4309,7 @@ pub const Type = extern union {
41974309 const info = ty.castTag(.pointer).?.data;
41984310 const child_ty = info.pointee_type;
41994311 if (info.size == .One) {
4200 return child_ty.shallowElemType();
4312 return child_ty.shallowElemType(mod);
42014313 } else {
42024314 return child_ty;
42034315 }
......@@ -4213,16 +4325,16 @@ pub const Type = extern union {
42134325 };
42144326 }
42154327
4216 fn shallowElemType(child_ty: Type) Type {
4217 return switch (child_ty.zigTypeTag()) {
4328 fn shallowElemType(child_ty: Type, mod: *const Module) Type {
4329 return switch (child_ty.zigTypeTag(mod)) {
42184330 .Array, .Vector => child_ty.childType(),
42194331 else => child_ty,
42204332 };
42214333 }
42224334
42234335 /// For vectors, returns the element type. Otherwise returns self.
4224 pub fn scalarType(ty: Type) Type {
4225 return switch (ty.zigTypeTag()) {
4336 pub fn scalarType(ty: Type, mod: *const Module) Type {
4337 return switch (ty.zigTypeTag(mod)) {
42264338 .Vector => ty.childType(),
42274339 else => ty,
42284340 };
......@@ -4360,19 +4472,19 @@ pub const Type = extern union {
43604472 return union_obj.fields.getIndex(name);
43614473 }
43624474
4363 pub fn unionHasAllZeroBitFieldTypes(ty: Type) bool {
4364 return ty.cast(Payload.Union).?.data.hasAllZeroBitFieldTypes();
4475 pub fn unionHasAllZeroBitFieldTypes(ty: Type, mod: *const Module) bool {
4476 return ty.cast(Payload.Union).?.data.hasAllZeroBitFieldTypes(mod);
43654477 }
43664478
4367 pub fn unionGetLayout(ty: Type, target: Target) Module.Union.Layout {
4479 pub fn unionGetLayout(ty: Type, mod: *const Module) Module.Union.Layout {
43684480 switch (ty.tag()) {
43694481 .@"union" => {
43704482 const union_obj = ty.castTag(.@"union").?.data;
4371 return union_obj.getLayout(target, false);
4483 return union_obj.getLayout(mod, false);
43724484 },
43734485 .union_safety_tagged, .union_tagged => {
43744486 const union_obj = ty.cast(Payload.Union).?.data;
4375 return union_obj.getLayout(target, true);
4487 return union_obj.getLayout(mod, true);
43764488 },
43774489 else => unreachable,
43784490 }
......@@ -4441,8 +4553,8 @@ pub const Type = extern union {
44414553 };
44424554 }
44434555
4444 pub fn isError(ty: Type) bool {
4445 return switch (ty.zigTypeTag()) {
4556 pub fn isError(ty: Type, mod: *const Module) bool {
4557 return switch (ty.zigTypeTag(mod)) {
44464558 .ErrorUnion, .ErrorSet => true,
44474559 else => false,
44484560 };
......@@ -4543,14 +4655,21 @@ pub const Type = extern union {
45434655 }
45444656
45454657 /// Returns true if and only if the type is a fixed-width integer.
4546 pub fn isInt(self: Type) bool {
4547 return self.isSignedInt() or self.isUnsignedInt();
4658 pub fn isInt(self: Type, mod: *const Module) bool {
4659 return self.isSignedInt(mod) or self.isUnsignedInt(mod);
45484660 }
45494661
45504662 /// Returns true if and only if the type is a fixed-width, signed integer.
4551 pub fn isSignedInt(self: Type) bool {
4552 return switch (self.tag()) {
4553 .int_signed,
4663 pub fn isSignedInt(ty: Type, mod: *const Module) bool {
4664 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
4665 .int_type => |int_type| return int_type.signedness == .signed,
4666 .simple_type => |s| return switch (s) {
4667 .c_char, .isize, .c_short, .c_int, .c_long, .c_longlong => true,
4668 else => false,
4669 },
4670 else => return false,
4671 };
4672 return switch (ty.tag()) {
45544673 .i8,
45554674 .isize,
45564675 .c_char,
......@@ -4569,9 +4688,16 @@ pub const Type = extern union {
45694688 }
45704689
45714690 /// Returns true if and only if the type is a fixed-width, unsigned integer.
4572 pub fn isUnsignedInt(self: Type) bool {
4573 return switch (self.tag()) {
4574 .int_unsigned,
4691 pub fn isUnsignedInt(ty: Type, mod: *const Module) bool {
4692 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
4693 .int_type => |int_type| return int_type.signedness == .unsigned,
4694 .simple_type => |s| return switch (s) {
4695 .usize, .c_ushort, .c_uint, .c_ulong, .c_ulonglong => true,
4696 else => false,
4697 },
4698 else => return false,
4699 };
4700 return switch (ty.tag()) {
45754701 .usize,
45764702 .c_ushort,
45774703 .c_uint,
......@@ -4592,8 +4718,8 @@ pub const Type = extern union {
45924718
45934719 /// Returns true for integers, enums, error sets, and packed structs.
45944720 /// If this function returns true, then intInfo() can be called on the type.
4595 pub fn isAbiInt(ty: Type) bool {
4596 return switch (ty.zigTypeTag()) {
4721 pub fn isAbiInt(ty: Type, mod: *const Module) bool {
4722 return switch (ty.zigTypeTag(mod)) {
45974723 .Int, .Enum, .ErrorSet => true,
45984724 .Struct => ty.containerLayout() == .Packed,
45994725 else => false,
......@@ -4601,17 +4727,26 @@ pub const Type = extern union {
46014727 }
46024728
46034729 /// Asserts the type is an integer, enum, error set, or vector of one of them.
4604 pub fn intInfo(self: Type, target: Target) std.builtin.Type.Int {
4605 var ty = self;
4730 pub fn intInfo(starting_ty: Type, mod: *const Module) InternPool.Key.IntType {
4731 const target = mod.getTarget();
4732 var ty = starting_ty;
4733
4734 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
4735 .int_type => |int_type| return int_type,
4736 .ptr_type => @panic("TODO"),
4737 .array_type => @panic("TODO"),
4738 .vector_type => @panic("TODO"),
4739 .optional_type => @panic("TODO"),
4740 .error_union_type => @panic("TODO"),
4741 .simple_type => @panic("TODO"),
4742 .struct_type => unreachable,
4743 .simple_value => unreachable,
4744 .extern_func => unreachable,
4745 .int => unreachable,
4746 .enum_tag => unreachable, // it's a value, not a type
4747 };
4748
46064749 while (true) switch (ty.tag()) {
4607 .int_unsigned => return .{
4608 .signedness = .unsigned,
4609 .bits = ty.castTag(.int_unsigned).?.data,
4610 },
4611 .int_signed => return .{
4612 .signedness = .signed,
4613 .bits = ty.castTag(.int_signed).?.data,
4614 },
46154750 .u1 => return .{ .signedness = .unsigned, .bits = 1 },
46164751 .u8 => return .{ .signedness = .unsigned, .bits = 8 },
46174752 .i8 => return .{ .signedness = .signed, .bits = 8 },
......@@ -4729,32 +4864,14 @@ pub const Type = extern union {
47294864
47304865 /// Asserts the type is a function.
47314866 pub fn fnParamLen(self: Type) usize {
4732 return switch (self.tag()) {
4733 .fn_noreturn_no_args => 0,
4734 .fn_void_no_args => 0,
4735 .fn_naked_noreturn_no_args => 0,
4736 .fn_ccc_void_no_args => 0,
4737 .function => self.castTag(.function).?.data.param_types.len,
4738
4739 else => unreachable,
4740 };
4867 return self.castTag(.function).?.data.param_types.len;
47414868 }
47424869
47434870 /// Asserts the type is a function. The length of the slice must be at least the length
47444871 /// given by `fnParamLen`.
47454872 pub fn fnParamTypes(self: Type, types: []Type) void {
4746 switch (self.tag()) {
4747 .fn_noreturn_no_args => return,
4748 .fn_void_no_args => return,
4749 .fn_naked_noreturn_no_args => return,
4750 .fn_ccc_void_no_args => return,
4751 .function => {
4752 const payload = self.castTag(.function).?.data;
4753 @memcpy(types[0..payload.param_types.len], payload.param_types);
4754 },
4755
4756 else => unreachable,
4757 }
4873 const payload = self.castTag(.function).?.data;
4874 @memcpy(types[0..payload.param_types.len], payload.param_types);
47584875 }
47594876
47604877 /// Asserts the type is a function.
......@@ -4769,33 +4886,15 @@ pub const Type = extern union {
47694886 }
47704887 }
47714888
4772 /// Asserts the type is a function.
4773 pub fn fnReturnType(self: Type) Type {
4774 return switch (self.tag()) {
4775 .fn_noreturn_no_args => Type.initTag(.noreturn),
4776 .fn_naked_noreturn_no_args => Type.initTag(.noreturn),
4777
4778 .fn_void_no_args,
4779 .fn_ccc_void_no_args,
4780 => Type.initTag(.void),
4781
4782 .function => self.castTag(.function).?.data.return_type,
4783
4784 else => unreachable,
4785 };
4889 /// Asserts the type is a function or a function pointer.
4890 pub fn fnReturnType(ty: Type) Type {
4891 const fn_ty = if (ty.castPointer()) |p| p.data else ty;
4892 return fn_ty.castTag(.function).?.data.return_type;
47864893 }
47874894
47884895 /// Asserts the type is a function.
47894896 pub fn fnCallingConvention(self: Type) std.builtin.CallingConvention {
4790 return switch (self.tag()) {
4791 .fn_noreturn_no_args => .Unspecified,
4792 .fn_void_no_args => .Unspecified,
4793 .fn_naked_noreturn_no_args => .Naked,
4794 .fn_ccc_void_no_args => .C,
4795 .function => self.castTag(.function).?.data.cc,
4796
4797 else => unreachable,
4798 };
4897 return self.castTag(.function).?.data.cc;
47994898 }
48004899
48014900 /// Asserts the type is a function.
......@@ -4809,15 +4908,15 @@ pub const Type = extern union {
48094908 };
48104909 }
48114910
4812 pub fn isValidParamType(self: Type) bool {
4813 return switch (self.zigTypeTagOrPoison() catch return true) {
4911 pub fn isValidParamType(self: Type, mod: *const Module) bool {
4912 return switch (self.zigTypeTagOrPoison(mod) catch return true) {
48144913 .Undefined, .Null, .Opaque, .NoReturn => false,
48154914 else => true,
48164915 };
48174916 }
48184917
4819 pub fn isValidReturnType(self: Type) bool {
4820 return switch (self.zigTypeTagOrPoison() catch return true) {
4918 pub fn isValidReturnType(self: Type, mod: *const Module) bool {
4919 return switch (self.zigTypeTagOrPoison(mod) catch return true) {
48214920 .Undefined, .Null, .Opaque => false,
48224921 else => true,
48234922 };
......@@ -4825,87 +4924,43 @@ pub const Type = extern union {
48254924
48264925 /// Asserts the type is a function.
48274926 pub fn fnIsVarArgs(self: Type) bool {
4828 return switch (self.tag()) {
4829 .fn_noreturn_no_args => false,
4830 .fn_void_no_args => false,
4831 .fn_naked_noreturn_no_args => false,
4832 .fn_ccc_void_no_args => false,
4833 .function => self.castTag(.function).?.data.is_var_args,
4834
4835 else => unreachable,
4836 };
4927 return self.castTag(.function).?.data.is_var_args;
48374928 }
48384929
48394930 pub fn fnInfo(ty: Type) Payload.Function.Data {
4840 return switch (ty.tag()) {
4841 .fn_noreturn_no_args => .{
4842 .param_types = &.{},
4843 .comptime_params = undefined,
4844 .return_type = initTag(.noreturn),
4845 .cc = .Unspecified,
4846 .alignment = 0,
4847 .is_var_args = false,
4848 .is_generic = false,
4849 .is_noinline = false,
4850 .align_is_generic = false,
4851 .cc_is_generic = false,
4852 .section_is_generic = false,
4853 .addrspace_is_generic = false,
4854 .noalias_bits = 0,
4855 },
4856 .fn_void_no_args => .{
4857 .param_types = &.{},
4858 .comptime_params = undefined,
4859 .return_type = initTag(.void),
4860 .cc = .Unspecified,
4861 .alignment = 0,
4862 .is_var_args = false,
4863 .is_generic = false,
4864 .is_noinline = false,
4865 .align_is_generic = false,
4866 .cc_is_generic = false,
4867 .section_is_generic = false,
4868 .addrspace_is_generic = false,
4869 .noalias_bits = 0,
4870 },
4871 .fn_naked_noreturn_no_args => .{
4872 .param_types = &.{},
4873 .comptime_params = undefined,
4874 .return_type = initTag(.noreturn),
4875 .cc = .Naked,
4876 .alignment = 0,
4877 .is_var_args = false,
4878 .is_generic = false,
4879 .is_noinline = false,
4880 .align_is_generic = false,
4881 .cc_is_generic = false,
4882 .section_is_generic = false,
4883 .addrspace_is_generic = false,
4884 .noalias_bits = 0,
4885 },
4886 .fn_ccc_void_no_args => .{
4887 .param_types = &.{},
4888 .comptime_params = undefined,
4889 .return_type = initTag(.void),
4890 .cc = .C,
4891 .alignment = 0,
4892 .is_var_args = false,
4893 .is_generic = false,
4894 .is_noinline = false,
4895 .align_is_generic = false,
4896 .cc_is_generic = false,
4897 .section_is_generic = false,
4898 .addrspace_is_generic = false,
4899 .noalias_bits = 0,
4900 },
4901 .function => ty.castTag(.function).?.data,
4902
4903 else => unreachable,
4904 };
4931 return ty.castTag(.function).?.data;
49054932 }
49064933
4907 pub fn isNumeric(self: Type) bool {
4908 return switch (self.tag()) {
4934 pub fn isNumeric(ty: Type, mod: *const Module) bool {
4935 if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
4936 .int_type => true,
4937 .simple_type => |s| return switch (s) {
4938 .f16,
4939 .f32,
4940 .f64,
4941 .f80,
4942 .f128,
4943 .c_longdouble,
4944 .comptime_int,
4945 .comptime_float,
4946 .usize,
4947 .isize,
4948 .c_char,
4949 .c_short,
4950 .c_ushort,
4951 .c_int,
4952 .c_uint,
4953 .c_long,
4954 .c_ulong,
4955 .c_longlong,
4956 .c_ulonglong,
4957 => true,
4958
4959 else => false,
4960 },
4961 else => false,
4962 };
4963 return switch (ty.tag()) {
49094964 .f16,
49104965 .f32,
49114966 .f64,
......@@ -4937,8 +4992,6 @@ pub const Type = extern union {
49374992 .c_ulong,
49384993 .c_longlong,
49394994 .c_ulonglong,
4940 .int_unsigned,
4941 .int_signed,
49424995 => true,
49434996
49444997 else => false,
......@@ -4947,8 +5000,30 @@ pub const Type = extern union {
49475000
49485001 /// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which
49495002 /// resolves field types rather than asserting they are already resolved.
4950 pub fn onePossibleValue(starting_type: Type) ?Value {
5003 pub fn onePossibleValue(starting_type: Type, mod: *const Module) ?Value {
49515004 var ty = starting_type;
5005
5006 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
5007 .int_type => |int_type| {
5008 if (int_type.bits == 0) {
5009 return Value.zero;
5010 } else {
5011 return null;
5012 }
5013 },
5014 .ptr_type => @panic("TODO"),
5015 .array_type => @panic("TODO"),
5016 .vector_type => @panic("TODO"),
5017 .optional_type => @panic("TODO"),
5018 .error_union_type => @panic("TODO"),
5019 .simple_type => @panic("TODO"),
5020 .struct_type => @panic("TODO"),
5021 .simple_value => unreachable,
5022 .extern_func => unreachable,
5023 .int => unreachable,
5024 .enum_tag => unreachable, // it's a value, not a type
5025 };
5026
49525027 while (true) switch (ty.tag()) {
49535028 .f16,
49545029 .f32,
......@@ -4988,10 +5063,6 @@ pub const Type = extern union {
49885063 .error_set_single,
49895064 .error_set,
49905065 .error_set_merged,
4991 .fn_noreturn_no_args,
4992 .fn_void_no_args,
4993 .fn_naked_noreturn_no_args,
4994 .fn_ccc_void_no_args,
49955066 .function,
49965067 .single_const_pointer_to_comptime_int,
49975068 .array_sentinel,
......@@ -5047,7 +5118,7 @@ pub const Type = extern union {
50475118 assert(s.haveFieldTypes());
50485119 for (s.fields.values()) |field| {
50495120 if (field.is_comptime) continue;
5050 if (field.ty.onePossibleValue() != null) continue;
5121 if (field.ty.onePossibleValue(mod) != null) continue;
50515122 return null;
50525123 }
50535124 return Value.initTag(.empty_struct_value);
......@@ -5058,7 +5129,7 @@ pub const Type = extern union {
50585129 for (tuple.values, 0..) |val, i| {
50595130 const is_comptime = val.tag() != .unreachable_value;
50605131 if (is_comptime) continue;
5061 if (tuple.types[i].onePossibleValue() != null) continue;
5132 if (tuple.types[i].onePossibleValue(mod) != null) continue;
50625133 return null;
50635134 }
50645135 return Value.initTag(.empty_struct_value);
......@@ -5067,7 +5138,7 @@ pub const Type = extern union {
50675138 .enum_numbered => {
50685139 const enum_numbered = ty.castTag(.enum_numbered).?.data;
50695140 // An explicit tag type is always provided for enum_numbered.
5070 if (enum_numbered.tag_ty.hasRuntimeBits()) {
5141 if (enum_numbered.tag_ty.hasRuntimeBits(mod)) {
50715142 return null;
50725143 }
50735144 assert(enum_numbered.fields.count() == 1);
......@@ -5075,7 +5146,7 @@ pub const Type = extern union {
50755146 },
50765147 .enum_full => {
50775148 const enum_full = ty.castTag(.enum_full).?.data;
5078 if (enum_full.tag_ty.hasRuntimeBits()) {
5149 if (enum_full.tag_ty.hasRuntimeBits(mod)) {
50795150 return null;
50805151 }
50815152 switch (enum_full.fields.count()) {
......@@ -5098,7 +5169,7 @@ pub const Type = extern union {
50985169 },
50995170 .enum_nonexhaustive => {
51005171 const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty;
5101 if (!tag_ty.hasRuntimeBits()) {
5172 if (!tag_ty.hasRuntimeBits(mod)) {
51025173 return Value.zero;
51035174 } else {
51045175 return null;
......@@ -5106,10 +5177,10 @@ pub const Type = extern union {
51065177 },
51075178 .@"union", .union_safety_tagged, .union_tagged => {
51085179 const union_obj = ty.cast(Payload.Union).?.data;
5109 const tag_val = union_obj.tag_ty.onePossibleValue() orelse return null;
5180 const tag_val = union_obj.tag_ty.onePossibleValue(mod) orelse return null;
51105181 if (union_obj.fields.count() == 0) return Value.initTag(.unreachable_value);
51115182 const only_field = union_obj.fields.values()[0];
5112 const val_val = only_field.ty.onePossibleValue() orelse return null;
5183 const val_val = only_field.ty.onePossibleValue(mod) orelse return null;
51135184 _ = tag_val;
51145185 _ = val_val;
51155186 return Value.initTag(.empty_struct_value);
......@@ -5121,17 +5192,10 @@ pub const Type = extern union {
51215192 .null => return Value.initTag(.null_value),
51225193 .undefined => return Value.initTag(.undef),
51235194
5124 .int_unsigned, .int_signed => {
5125 if (ty.cast(Payload.Bits).?.data == 0) {
5126 return Value.zero;
5127 } else {
5128 return null;
5129 }
5130 },
51315195 .vector, .array, .array_u8 => {
51325196 if (ty.arrayLen() == 0)
51335197 return Value.initTag(.empty_array);
5134 if (ty.elemType().onePossibleValue() != null)
5198 if (ty.elemType().onePossibleValue(mod) != null)
51355199 return Value.initTag(.the_only_possible_value);
51365200 return null;
51375201 },
......@@ -5146,7 +5210,22 @@ pub const Type = extern union {
51465210 /// resolves field types rather than asserting they are already resolved.
51475211 /// TODO merge these implementations together with the "advanced" pattern seen
51485212 /// elsewhere in this file.
5149 pub fn comptimeOnly(ty: Type) bool {
5213 pub fn comptimeOnly(ty: Type, mod: *const Module) bool {
5214 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
5215 .int_type => return false,
5216 .ptr_type => @panic("TODO"),
5217 .array_type => @panic("TODO"),
5218 .vector_type => @panic("TODO"),
5219 .optional_type => @panic("TODO"),
5220 .error_union_type => @panic("TODO"),
5221 .simple_type => @panic("TODO"),
5222 .struct_type => @panic("TODO"),
5223 .simple_value => unreachable,
5224 .extern_func => unreachable,
5225 .int => unreachable,
5226 .enum_tag => unreachable, // it's a value, not a type
5227 };
5228
51505229 return switch (ty.tag()) {
51515230 .u1,
51525231 .u8,
......@@ -5211,8 +5290,6 @@ pub const Type = extern union {
52115290 .generic_poison,
52125291 .array_u8,
52135292 .array_u8_sentinel_0,
5214 .int_signed,
5215 .int_unsigned,
52165293 .enum_simple,
52175294 => false,
52185295
......@@ -5223,10 +5300,6 @@ pub const Type = extern union {
52235300 .enum_literal,
52245301 .type_info,
52255302 // These are function bodies, not function pointers.
5226 .fn_noreturn_no_args,
5227 .fn_void_no_args,
5228 .fn_naked_noreturn_no_args,
5229 .fn_ccc_void_no_args,
52305303 .function,
52315304 => true,
52325305
......@@ -5236,7 +5309,7 @@ pub const Type = extern union {
52365309 .array,
52375310 .array_sentinel,
52385311 .vector,
5239 => return ty.childType().comptimeOnly(),
5312 => return ty.childType().comptimeOnly(mod),
52405313
52415314 .pointer,
52425315 .single_const_pointer,
......@@ -5249,10 +5322,10 @@ pub const Type = extern union {
52495322 .mut_slice,
52505323 => {
52515324 const child_ty = ty.childType();
5252 if (child_ty.zigTypeTag() == .Fn) {
5325 if (child_ty.zigTypeTag(mod) == .Fn) {
52535326 return false;
52545327 } else {
5255 return child_ty.comptimeOnly();
5328 return child_ty.comptimeOnly(mod);
52565329 }
52575330 },
52585331
......@@ -5261,14 +5334,14 @@ pub const Type = extern union {
52615334 .optional_single_const_pointer,
52625335 => {
52635336 var buf: Type.Payload.ElemType = undefined;
5264 return ty.optionalChild(&buf).comptimeOnly();
5337 return ty.optionalChild(&buf).comptimeOnly(mod);
52655338 },
52665339
52675340 .tuple, .anon_struct => {
52685341 const tuple = ty.tupleFields();
52695342 for (tuple.types, 0..) |field_ty, i| {
52705343 const have_comptime_val = tuple.values[i].tag() != .unreachable_value;
5271 if (!have_comptime_val and field_ty.comptimeOnly()) return true;
5344 if (!have_comptime_val and field_ty.comptimeOnly(mod)) return true;
52725345 }
52735346 return false;
52745347 },
......@@ -5301,48 +5374,48 @@ pub const Type = extern union {
53015374 }
53025375 },
53035376
5304 .error_union => return ty.errorUnionPayload().comptimeOnly(),
5377 .error_union => return ty.errorUnionPayload().comptimeOnly(mod),
53055378 .anyframe_T => {
53065379 const child_ty = ty.castTag(.anyframe_T).?.data;
5307 return child_ty.comptimeOnly();
5380 return child_ty.comptimeOnly(mod);
53085381 },
53095382 .enum_numbered => {
53105383 const tag_ty = ty.castTag(.enum_numbered).?.data.tag_ty;
5311 return tag_ty.comptimeOnly();
5384 return tag_ty.comptimeOnly(mod);
53125385 },
53135386 .enum_full, .enum_nonexhaustive => {
53145387 const tag_ty = ty.cast(Type.Payload.EnumFull).?.data.tag_ty;
5315 return tag_ty.comptimeOnly();
5388 return tag_ty.comptimeOnly(mod);
53165389 },
53175390 };
53185391 }
53195392
5320 pub fn isArrayOrVector(ty: Type) bool {
5321 return switch (ty.zigTypeTag()) {
5393 pub fn isArrayOrVector(ty: Type, mod: *const Module) bool {
5394 return switch (ty.zigTypeTag(mod)) {
53225395 .Array, .Vector => true,
53235396 else => false,
53245397 };
53255398 }
53265399
5327 pub fn isIndexable(ty: Type) bool {
5328 return switch (ty.zigTypeTag()) {
5400 pub fn isIndexable(ty: Type, mod: *const Module) bool {
5401 return switch (ty.zigTypeTag(mod)) {
53295402 .Array, .Vector => true,
53305403 .Pointer => switch (ty.ptrSize()) {
53315404 .Slice, .Many, .C => true,
5332 .One => ty.elemType().zigTypeTag() == .Array,
5405 .One => ty.elemType().zigTypeTag(mod) == .Array,
53335406 },
53345407 .Struct => ty.isTuple(),
53355408 else => false,
53365409 };
53375410 }
53385411
5339 pub fn indexableHasLen(ty: Type) bool {
5340 return switch (ty.zigTypeTag()) {
5412 pub fn indexableHasLen(ty: Type, mod: *const Module) bool {
5413 return switch (ty.zigTypeTag(mod)) {
53415414 .Array, .Vector => true,
53425415 .Pointer => switch (ty.ptrSize()) {
53435416 .Many, .C => false,
53445417 .Slice => true,
5345 .One => ty.elemType().zigTypeTag() == .Array,
5418 .One => ty.elemType().zigTypeTag(mod) == .Array,
53465419 },
53475420 .Struct => ty.isTuple(),
53485421 else => false,
......@@ -5366,19 +5439,19 @@ pub const Type = extern union {
53665439 }
53675440
53685441 // Works for vectors and vectors of integers.
5369 pub fn minInt(ty: Type, arena: Allocator, target: Target) !Value {
5370 const scalar = try minIntScalar(ty.scalarType(), arena, target);
5371 if (ty.zigTypeTag() == .Vector and scalar.tag() != .the_only_possible_value) {
5442 pub fn minInt(ty: Type, arena: Allocator, mod: *const Module) !Value {
5443 const scalar = try minIntScalar(ty.scalarType(mod), arena, mod);
5444 if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) {
53725445 return Value.Tag.repeated.create(arena, scalar);
53735446 } else {
53745447 return scalar;
53755448 }
53765449 }
53775450
5378 /// Asserts that self.zigTypeTag() == .Int.
5379 pub fn minIntScalar(ty: Type, arena: Allocator, target: Target) !Value {
5380 assert(ty.zigTypeTag() == .Int);
5381 const info = ty.intInfo(target);
5451 /// Asserts that self.zigTypeTag(mod) == .Int.
5452 pub fn minIntScalar(ty: Type, arena: Allocator, mod: *const Module) !Value {
5453 assert(ty.zigTypeTag(mod) == .Int);
5454 const info = ty.intInfo(mod);
53825455
53835456 if (info.bits == 0) {
53845457 return Value.initTag(.the_only_possible_value);
......@@ -5405,9 +5478,9 @@ pub const Type = extern union {
54055478 }
54065479
54075480 // Works for vectors and vectors of integers.
5408 pub fn maxInt(ty: Type, arena: Allocator, target: Target) !Value {
5409 const scalar = try maxIntScalar(ty.scalarType(), arena, target);
5410 if (ty.zigTypeTag() == .Vector and scalar.tag() != .the_only_possible_value) {
5481 pub fn maxInt(ty: Type, arena: Allocator, mod: *const Module) !Value {
5482 const scalar = try maxIntScalar(ty.scalarType(mod), arena, mod);
5483 if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) {
54115484 return Value.Tag.repeated.create(arena, scalar);
54125485 } else {
54135486 return scalar;
......@@ -5415,9 +5488,9 @@ pub const Type = extern union {
54155488 }
54165489
54175490 /// Asserts that self.zigTypeTag() == .Int.
5418 pub fn maxIntScalar(self: Type, arena: Allocator, target: Target) !Value {
5419 assert(self.zigTypeTag() == .Int);
5420 const info = self.intInfo(target);
5491 pub fn maxIntScalar(self: Type, arena: Allocator, mod: *const Module) !Value {
5492 assert(self.zigTypeTag(mod) == .Int);
5493 const info = self.intInfo(mod);
54215494
54225495 if (info.bits == 0) {
54235496 return Value.initTag(.the_only_possible_value);
......@@ -5452,21 +5525,25 @@ pub const Type = extern union {
54525525 }
54535526
54545527 /// Asserts the type is an enum or a union.
5455 pub fn intTagType(ty: Type, buffer: *Payload.Bits) Type {
5528 pub fn intTagType(ty: Type) Type {
54565529 switch (ty.tag()) {
54575530 .enum_full, .enum_nonexhaustive => return ty.cast(Payload.EnumFull).?.data.tag_ty,
54585531 .enum_numbered => return ty.castTag(.enum_numbered).?.data.tag_ty,
54595532 .enum_simple => {
5460 const enum_simple = ty.castTag(.enum_simple).?.data;
5461 const field_count = enum_simple.fields.count();
5462 const bits: u16 = if (field_count == 0) 0 else std.math.log2_int_ceil(usize, field_count);
5463 buffer.* = .{
5464 .base = .{ .tag = .int_unsigned },
5465 .data = bits,
5466 };
5467 return Type.initPayload(&buffer.base);
5533 @panic("TODO move enum_simple to use the intern pool");
5534 //const enum_simple = ty.castTag(.enum_simple).?.data;
5535 //const field_count = enum_simple.fields.count();
5536 //const bits: u16 = if (field_count == 0) 0 else std.math.log2_int_ceil(usize, field_count);
5537 //buffer.* = .{
5538 // .base = .{ .tag = .int_unsigned },
5539 // .data = bits,
5540 //};
5541 //return Type.initPayload(&buffer.base);
5542 },
5543 .union_tagged => {
5544 @panic("TODO move union_tagged to use the intern pool");
5545 //return ty.castTag(.union_tagged).?.data.tag_ty.intTagType(buffer),
54685546 },
5469 .union_tagged => return ty.castTag(.union_tagged).?.data.tag_ty.intTagType(buffer),
54705547 else => unreachable,
54715548 }
54725549 }
......@@ -5566,7 +5643,7 @@ pub const Type = extern union {
55665643 };
55675644 const end_val = Value.initPayload(&end_payload.base);
55685645 if (int_val.compareAll(.gte, end_val, int_ty, m)) return null;
5569 return @intCast(usize, int_val.toUnsignedInt(m.getTarget()));
5646 return @intCast(usize, int_val.toUnsignedInt(m));
55705647 }
55715648 };
55725649 switch (ty.tag()) {
......@@ -5598,11 +5675,7 @@ pub const Type = extern union {
55985675 const enum_simple = ty.castTag(.enum_simple).?.data;
55995676 const fields_len = enum_simple.fields.count();
56005677 const bits = std.math.log2_int_ceil(usize, fields_len);
5601 var buffer: Payload.Bits = .{
5602 .base = .{ .tag = .int_unsigned },
5603 .data = bits,
5604 };
5605 const tag_ty = Type.initPayload(&buffer.base);
5678 const tag_ty = mod.intType(.unsigned, bits) catch @panic("TODO: handle OOM here");
56065679 return S.fieldWithRange(tag_ty, enum_tag, fields_len, mod);
56075680 },
56085681 .atomic_order,
......@@ -5675,19 +5748,19 @@ pub const Type = extern union {
56755748 }
56765749 }
56775750
5678 pub fn structFieldAlign(ty: Type, index: usize, target: Target) u32 {
5751 pub fn structFieldAlign(ty: Type, index: usize, mod: *const Module) u32 {
56795752 switch (ty.tag()) {
56805753 .@"struct" => {
56815754 const struct_obj = ty.castTag(.@"struct").?.data;
56825755 assert(struct_obj.layout != .Packed);
5683 return struct_obj.fields.values()[index].alignment(target, struct_obj.layout);
5756 return struct_obj.fields.values()[index].alignment(mod, struct_obj.layout);
56845757 },
56855758 .@"union", .union_safety_tagged, .union_tagged => {
56865759 const union_obj = ty.cast(Payload.Union).?.data;
5687 return union_obj.fields.values()[index].normalAlignment(target);
5760 return union_obj.fields.values()[index].normalAlignment(mod);
56885761 },
5689 .tuple => return ty.castTag(.tuple).?.data.types[index].abiAlignment(target),
5690 .anon_struct => return ty.castTag(.anon_struct).?.data.types[index].abiAlignment(target),
5762 .tuple => return ty.castTag(.tuple).?.data.types[index].abiAlignment(mod),
5763 .anon_struct => return ty.castTag(.anon_struct).?.data.types[index].abiAlignment(mod),
56915764 else => unreachable,
56925765 }
56935766 }
......@@ -5710,7 +5783,7 @@ pub const Type = extern union {
57105783 }
57115784 }
57125785
5713 pub fn structFieldValueComptime(ty: Type, index: usize) ?Value {
5786 pub fn structFieldValueComptime(ty: Type, mod: *const Module, index: usize) ?Value {
57145787 switch (ty.tag()) {
57155788 .@"struct" => {
57165789 const struct_obj = ty.castTag(.@"struct").?.data;
......@@ -5718,14 +5791,14 @@ pub const Type = extern union {
57185791 if (field.is_comptime) {
57195792 return field.default_val;
57205793 } else {
5721 return field.ty.onePossibleValue();
5794 return field.ty.onePossibleValue(mod);
57225795 }
57235796 },
57245797 .tuple => {
57255798 const tuple = ty.castTag(.tuple).?.data;
57265799 const val = tuple.values[index];
57275800 if (val.tag() == .unreachable_value) {
5728 return tuple.types[index].onePossibleValue();
5801 return tuple.types[index].onePossibleValue(mod);
57295802 } else {
57305803 return val;
57315804 }
......@@ -5734,7 +5807,7 @@ pub const Type = extern union {
57345807 const anon_struct = ty.castTag(.anon_struct).?.data;
57355808 const val = anon_struct.values[index];
57365809 if (val.tag() == .unreachable_value) {
5737 return anon_struct.types[index].onePossibleValue();
5810 return anon_struct.types[index].onePossibleValue(mod);
57385811 } else {
57395812 return val;
57405813 }
......@@ -5765,7 +5838,7 @@ pub const Type = extern union {
57655838 }
57665839 }
57675840
5768 pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, target: Target) u32 {
5841 pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, mod: *const Module) u32 {
57695842 const struct_obj = ty.castTag(.@"struct").?.data;
57705843 assert(struct_obj.layout == .Packed);
57715844 comptime assert(Type.packed_struct_layout_version == 2);
......@@ -5774,9 +5847,9 @@ pub const Type = extern union {
57745847 var elem_size_bits: u16 = undefined;
57755848 var running_bits: u16 = 0;
57765849 for (struct_obj.fields.values(), 0..) |f, i| {
5777 if (!f.ty.hasRuntimeBits()) continue;
5850 if (!f.ty.hasRuntimeBits(mod)) continue;
57785851
5779 const field_bits = @intCast(u16, f.ty.bitSize(target));
5852 const field_bits = @intCast(u16, f.ty.bitSize(mod));
57805853 if (i == field_index) {
57815854 bit_offset = running_bits;
57825855 elem_size_bits = field_bits;
......@@ -5797,9 +5870,10 @@ pub const Type = extern union {
57975870 offset: u64 = 0,
57985871 big_align: u32 = 0,
57995872 struct_obj: *Module.Struct,
5800 target: Target,
5873 module: *const Module,
58015874
58025875 pub fn next(it: *StructOffsetIterator) ?FieldOffset {
5876 const mod = it.module;
58035877 var i = it.field;
58045878 if (it.struct_obj.fields.count() <= i)
58055879 return null;
......@@ -5811,35 +5885,35 @@ pub const Type = extern union {
58115885 const field = it.struct_obj.fields.values()[i];
58125886 it.field += 1;
58135887
5814 if (field.is_comptime or !field.ty.hasRuntimeBits()) {
5888 if (field.is_comptime or !field.ty.hasRuntimeBits(mod)) {
58155889 return FieldOffset{ .field = i, .offset = it.offset };
58165890 }
58175891
5818 const field_align = field.alignment(it.target, it.struct_obj.layout);
5892 const field_align = field.alignment(mod, it.struct_obj.layout);
58195893 it.big_align = @max(it.big_align, field_align);
58205894 const field_offset = std.mem.alignForwardGeneric(u64, it.offset, field_align);
5821 it.offset = field_offset + field.ty.abiSize(it.target);
5895 it.offset = field_offset + field.ty.abiSize(mod);
58225896 return FieldOffset{ .field = i, .offset = field_offset };
58235897 }
58245898 };
58255899
58265900 /// Get an iterator that iterates over all the struct field, returning the field and
58275901 /// offset of that field. Asserts that the type is a non-packed struct.
5828 pub fn iterateStructOffsets(ty: Type, target: Target) StructOffsetIterator {
5902 pub fn iterateStructOffsets(ty: Type, mod: *const Module) StructOffsetIterator {
58295903 const struct_obj = ty.castTag(.@"struct").?.data;
58305904 assert(struct_obj.haveLayout());
58315905 assert(struct_obj.layout != .Packed);
5832 return .{ .struct_obj = struct_obj, .target = target };
5906 return .{ .struct_obj = struct_obj, .module = mod };
58335907 }
58345908
58355909 /// Supports structs and unions.
5836 pub fn structFieldOffset(ty: Type, index: usize, target: Target) u64 {
5910 pub fn structFieldOffset(ty: Type, index: usize, mod: *const Module) u64 {
58375911 switch (ty.tag()) {
58385912 .@"struct" => {
58395913 const struct_obj = ty.castTag(.@"struct").?.data;
58405914 assert(struct_obj.haveLayout());
58415915 assert(struct_obj.layout != .Packed);
5842 var it = ty.iterateStructOffsets(target);
5916 var it = ty.iterateStructOffsets(mod);
58435917 while (it.next()) |field_offset| {
58445918 if (index == field_offset.field)
58455919 return field_offset.offset;
......@@ -5856,17 +5930,17 @@ pub const Type = extern union {
58565930
58575931 for (tuple.types, 0..) |field_ty, i| {
58585932 const field_val = tuple.values[i];
5859 if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) {
5933 if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits(mod)) {
58605934 // comptime field
58615935 if (i == index) return offset;
58625936 continue;
58635937 }
58645938
5865 const field_align = field_ty.abiAlignment(target);
5939 const field_align = field_ty.abiAlignment(mod);
58665940 big_align = @max(big_align, field_align);
58675941 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
58685942 if (i == index) return offset;
5869 offset += field_ty.abiSize(target);
5943 offset += field_ty.abiSize(mod);
58705944 }
58715945 offset = std.mem.alignForwardGeneric(u64, offset, @max(big_align, 1));
58725946 return offset;
......@@ -5875,7 +5949,7 @@ pub const Type = extern union {
58755949 .@"union" => return 0,
58765950 .union_safety_tagged, .union_tagged => {
58775951 const union_obj = ty.cast(Payload.Union).?.data;
5878 const layout = union_obj.getLayout(target, true);
5952 const layout = union_obj.getLayout(mod, true);
58795953 if (layout.tag_align >= layout.payload_align) {
58805954 // {Tag, Payload}
58815955 return std.mem.alignForwardGeneric(u64, layout.tag_size, layout.payload_align);
......@@ -6050,10 +6124,6 @@ pub const Type = extern union {
60506124 manyptr_u8,
60516125 manyptr_const_u8,
60526126 manyptr_const_u8_sentinel_0,
6053 fn_noreturn_no_args,
6054 fn_void_no_args,
6055 fn_naked_noreturn_no_args,
6056 fn_ccc_void_no_args,
60576127 single_const_pointer_to_comptime_int,
60586128 const_slice_u8,
60596129 const_slice_u8_sentinel_0,
......@@ -6087,8 +6157,6 @@ pub const Type = extern union {
60876157 c_mut_pointer,
60886158 const_slice,
60896159 mut_slice,
6090 int_signed,
6091 int_unsigned,
60926160 function,
60936161 optional,
60946162 optional_single_mut_pointer,
......@@ -6157,10 +6225,6 @@ pub const Type = extern union {
61576225 .enum_literal,
61586226 .null,
61596227 .undefined,
6160 .fn_noreturn_no_args,
6161 .fn_void_no_args,
6162 .fn_naked_noreturn_no_args,
6163 .fn_ccc_void_no_args,
61646228 .single_const_pointer_to_comptime_int,
61656229 .anyerror_void_error_union,
61666230 .const_slice_u8,
......@@ -6204,10 +6268,6 @@ pub const Type = extern union {
62046268 .anyframe_T,
62056269 => Payload.ElemType,
62066270
6207 .int_signed,
6208 .int_unsigned,
6209 => Payload.Bits,
6210
62116271 .error_set => Payload.ErrorSet,
62126272 .error_set_inferred => Payload.ErrorSetInferred,
62136273 .error_set_merged => Payload.ErrorSetMerged,
......@@ -6232,7 +6292,10 @@ pub const Type = extern union {
62326292
62336293 pub fn init(comptime t: Tag) file_struct.Type {
62346294 comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);
6235 return .{ .tag_if_small_enough = t };
6295 return file_struct.Type{
6296 .ip_index = .none,
6297 .legacy = .{ .tag_if_small_enough = t },
6298 };
62366299 }
62376300
62386301 pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!file_struct.Type {
......@@ -6241,7 +6304,10 @@ pub const Type = extern union {
62416304 .base = .{ .tag = t },
62426305 .data = data,
62436306 };
6244 return file_struct.Type{ .ptr_otherwise = &p.base };
6307 return file_struct.Type{
6308 .ip_index = .none,
6309 .legacy = .{ .ptr_otherwise = &p.base },
6310 };
62456311 }
62466312
62476313 pub fn Data(comptime t: Tag) type {
......@@ -6422,10 +6488,9 @@ pub const Type = extern union {
64226488 runtime = std.math.maxInt(u32) - 1,
64236489 _,
64246490 };
6425
6426 pub fn alignment(data: Data, target: Target) u32 {
6491 pub fn alignment(data: Data, mod: *const Module) u32 {
64276492 if (data.@"align" != 0) return data.@"align";
6428 return abiAlignment(data.pointee_type, target);
6493 return abiAlignment(data.pointee_type, mod);
64296494 }
64306495 };
64316496 };
......@@ -6537,12 +6602,11 @@ pub const Type = extern union {
65376602 pub const @"anyerror" = initTag(.anyerror);
65386603 pub const @"anyopaque" = initTag(.anyopaque);
65396604 pub const @"null" = initTag(.null);
6605 pub const @"noreturn" = initTag(.noreturn);
65406606
65416607 pub const err_int = Type.u16;
65426608
65436609 pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {
6544 const target = mod.getTarget();
6545
65466610 var d = data;
65476611
65486612 if (d.size == .C) {
......@@ -6554,8 +6618,8 @@ pub const Type = extern union {
65546618 // pointee type needs to be resolved more, that needs to be done before calling
65556619 // this ptr() function.
65566620 if (d.@"align" != 0) canonicalize: {
6557 if (!d.pointee_type.layoutIsResolved()) break :canonicalize;
6558 if (d.@"align" == d.pointee_type.abiAlignment(target)) {
6621 if (!d.pointee_type.layoutIsResolved(mod)) break :canonicalize;
6622 if (d.@"align" == d.pointee_type.abiAlignment(mod)) {
65596623 d.@"align" = 0;
65606624 }
65616625 }
......@@ -6565,7 +6629,7 @@ pub const Type = extern union {
65656629 // needs to be resolved before calling this ptr() function.
65666630 if (d.host_size != 0) {
65676631 assert(d.bit_offset < d.host_size * 8);
6568 if (d.host_size * 8 == d.pointee_type.bitSize(target)) {
6632 if (d.host_size * 8 == d.pointee_type.bitSize(mod)) {
65696633 assert(d.bit_offset == 0);
65706634 d.host_size = 0;
65716635 }
......@@ -6676,7 +6740,7 @@ pub const Type = extern union {
66766740 payload: Type,
66776741 mod: *Module,
66786742 ) Allocator.Error!Type {
6679 assert(error_set.zigTypeTag() == .ErrorSet);
6743 assert(error_set.zigTypeTag(mod) == .ErrorSet);
66806744 if (error_set.eql(Type.anyerror, mod) and
66816745 payload.eql(Type.void, mod))
66826746 {
......@@ -6696,83 +6760,6 @@ pub const Type = extern union {
66966760 return @intCast(u16, base + @boolToInt(upper < max));
66976761 }
66986762
6699 pub fn smallestUnsignedInt(arena: Allocator, max: u64) !Type {
6700 const bits = smallestUnsignedBits(max);
6701 return intWithBits(arena, false, bits);
6702 }
6703
6704 pub fn intWithBits(arena: Allocator, sign: bool, bits: u16) !Type {
6705 return if (sign) switch (bits) {
6706 8 => initTag(.i8),
6707 16 => initTag(.i16),
6708 32 => initTag(.i32),
6709 64 => initTag(.i64),
6710 else => return Tag.int_signed.create(arena, bits),
6711 } else switch (bits) {
6712 1 => initTag(.u1),
6713 8 => initTag(.u8),
6714 16 => initTag(.u16),
6715 32 => initTag(.u32),
6716 64 => initTag(.u64),
6717 else => return Tag.int_unsigned.create(arena, bits),
6718 };
6719 }
6720
6721 /// Given a value representing an integer, returns the number of bits necessary to represent
6722 /// this value in an integer. If `sign` is true, returns the number of bits necessary in a
6723 /// twos-complement integer; otherwise in an unsigned integer.
6724 /// Asserts that `val` is not undef. If `val` is negative, asserts that `sign` is true.
6725 pub fn intBitsForValue(target: Target, val: Value, sign: bool) u16 {
6726 assert(!val.isUndef());
6727 switch (val.tag()) {
6728 .int_big_positive => {
6729 const limbs = val.castTag(.int_big_positive).?.data;
6730 const big: std.math.big.int.Const = .{ .limbs = limbs, .positive = true };
6731 return @intCast(u16, big.bitCountAbs() + @boolToInt(sign));
6732 },
6733 .int_big_negative => {
6734 const limbs = val.castTag(.int_big_negative).?.data;
6735 // Zero is still a possibility, in which case unsigned is fine
6736 for (limbs) |limb| {
6737 if (limb != 0) break;
6738 } else return 0; // val == 0
6739 assert(sign);
6740 const big: std.math.big.int.Const = .{ .limbs = limbs, .positive = false };
6741 return @intCast(u16, big.bitCountTwosComp());
6742 },
6743 .int_i64 => {
6744 const x = val.castTag(.int_i64).?.data;
6745 if (x >= 0) return smallestUnsignedBits(@intCast(u64, x));
6746 assert(sign);
6747 return smallestUnsignedBits(@intCast(u64, -x - 1)) + 1;
6748 },
6749 else => {
6750 const x = val.toUnsignedInt(target);
6751 return smallestUnsignedBits(x) + @boolToInt(sign);
6752 },
6753 }
6754 }
6755
6756 /// Returns the smallest possible integer type containing both `min` and `max`. Asserts that neither
6757 /// value is undef.
6758 /// TODO: if #3806 is implemented, this becomes trivial
6759 pub fn intFittingRange(target: Target, arena: Allocator, min: Value, max: Value) !Type {
6760 assert(!min.isUndef());
6761 assert(!max.isUndef());
6762
6763 if (std.debug.runtime_safety) {
6764 assert(Value.order(min, max, target).compare(.lte));
6765 }
6766
6767 const sign = min.orderAgainstZero() == .lt;
6768
6769 const min_val_bits = intBitsForValue(target, min, sign);
6770 const max_val_bits = intBitsForValue(target, max, sign);
6771 const bits = @max(min_val_bits, max_val_bits);
6772
6773 return intWithBits(arena, sign, bits);
6774 }
6775
67766763 /// This is only used for comptime asserts. Bump this number when you make a change
67776764 /// to packed struct layout to find out all the places in the codebase you need to edit!
67786765 pub const packed_struct_layout_version = 2;
src/value.zig+441-439
......@@ -11,17 +11,24 @@ const Module = @import("Module.zig");
1111const Air = @import("Air.zig");
1212const TypedValue = @import("TypedValue.zig");
1313const Sema = @import("Sema.zig");
14
15/// This is the raw data, with no bookkeeping, no memory awareness,
16/// no de-duplication, and no type system awareness.
17/// It's important for this type to be small.
18/// This union takes advantage of the fact that the first page of memory
19/// is unmapped, giving us 4096 possible enum tags that have no payload.
20pub const Value = extern union {
21 /// If the tag value is less than Tag.no_payload_count, then no pointer
22 /// dereference is needed.
23 tag_if_small_enough: Tag,
24 ptr_otherwise: *Payload,
14const InternPool = @import("InternPool.zig");
15
16pub const Value = struct {
17 /// We are migrating towards using this for every Value object. However, many
18 /// values are still represented the legacy way. This is indicated by using
19 /// InternPool.Index.none.
20 ip_index: InternPool.Index,
21
22 /// This is the raw data, with no bookkeeping, no memory awareness,
23 /// no de-duplication, and no type system awareness.
24 /// This union takes advantage of the fact that the first page of memory
25 /// is unmapped, giving us 4096 possible enum tags that have no payload.
26 legacy: extern union {
27 /// If the tag value is less than Tag.no_payload_count, then no pointer
28 /// dereference is needed.
29 tag_if_small_enough: Tag,
30 ptr_otherwise: *Payload,
31 },
2532
2633 // Keep in sync with tools/stage2_pretty_printers_common.py
2734 pub const Tag = enum(usize) {
......@@ -81,10 +88,6 @@ pub const Value = extern union {
8188 manyptr_u8_type,
8289 manyptr_const_u8_type,
8390 manyptr_const_u8_sentinel_0_type,
84 fn_noreturn_no_args_type,
85 fn_void_no_args_type,
86 fn_naked_noreturn_no_args_type,
87 fn_ccc_void_no_args_type,
8891 single_const_pointer_to_comptime_int_type,
8992 const_slice_u8_type,
9093 const_slice_u8_sentinel_0_type,
......@@ -108,7 +111,6 @@ pub const Value = extern union {
108111 // After this, the tag requires a payload.
109112
110113 ty,
111 int_type,
112114 int_u64,
113115 int_i64,
114116 int_big_positive,
......@@ -232,10 +234,6 @@ pub const Value = extern union {
232234 .noreturn_type,
233235 .null_type,
234236 .undefined_type,
235 .fn_noreturn_no_args_type,
236 .fn_void_no_args_type,
237 .fn_naked_noreturn_no_args_type,
238 .fn_ccc_void_no_args_type,
239237 .single_const_pointer_to_comptime_int_type,
240238 .anyframe_type,
241239 .const_slice_u8_type,
......@@ -304,7 +302,6 @@ pub const Value = extern union {
304302 .lazy_size,
305303 => Payload.Ty,
306304
307 .int_type => Payload.IntType,
308305 .int_u64 => Payload.U64,
309306 .int_i64 => Payload.I64,
310307 .function => Payload.Function,
......@@ -332,7 +329,10 @@ pub const Value = extern union {
332329 .base = .{ .tag = t },
333330 .data = data,
334331 };
335 return Value{ .ptr_otherwise = &ptr.base };
332 return Value{
333 .ip_index = .none,
334 .legacy = .{ .ptr_otherwise = &ptr.base },
335 };
336336 }
337337
338338 pub fn Data(comptime t: Tag) type {
......@@ -342,37 +342,47 @@ pub const Value = extern union {
342342
343343 pub fn initTag(small_tag: Tag) Value {
344344 assert(@enumToInt(small_tag) < Tag.no_payload_count);
345 return .{ .tag_if_small_enough = small_tag };
345 return Value{
346 .ip_index = .none,
347 .legacy = .{ .tag_if_small_enough = small_tag },
348 };
346349 }
347350
348351 pub fn initPayload(payload: *Payload) Value {
349352 assert(@enumToInt(payload.tag) >= Tag.no_payload_count);
350 return .{ .ptr_otherwise = payload };
353 return Value{
354 .ip_index = .none,
355 .legacy = .{ .ptr_otherwise = payload },
356 };
351357 }
352358
353359 pub fn tag(self: Value) Tag {
354 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
355 return self.tag_if_small_enough;
360 assert(self.ip_index == .none);
361 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
362 return self.legacy.tag_if_small_enough;
356363 } else {
357 return self.ptr_otherwise.tag;
364 return self.legacy.ptr_otherwise.tag;
358365 }
359366 }
360367
361368 /// Prefer `castTag` to this.
362369 pub fn cast(self: Value, comptime T: type) ?*T {
370 if (self.ip_index != .none) {
371 return null;
372 }
363373 if (@hasField(T, "base_tag")) {
364374 return self.castTag(T.base_tag);
365375 }
366 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
376 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
367377 return null;
368378 }
369379 inline for (@typeInfo(Tag).Enum.fields) |field| {
370380 if (field.value < Tag.no_payload_count)
371381 continue;
372382 const t = @intToEnum(Tag, field.value);
373 if (self.ptr_otherwise.tag == t) {
383 if (self.legacy.ptr_otherwise.tag == t) {
374384 if (T == t.Type()) {
375 return @fieldParentPtr(T, "base", self.ptr_otherwise);
385 return @fieldParentPtr(T, "base", self.legacy.ptr_otherwise);
376386 }
377387 return null;
378388 }
......@@ -381,11 +391,15 @@ pub const Value = extern union {
381391 }
382392
383393 pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() {
384 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count)
394 if (self.ip_index != .none) {
395 return null;
396 }
397
398 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count)
385399 return null;
386400
387 if (self.ptr_otherwise.tag == t)
388 return @fieldParentPtr(t.Type(), "base", self.ptr_otherwise);
401 if (self.legacy.ptr_otherwise.tag == t)
402 return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise);
389403
390404 return null;
391405 }
......@@ -393,9 +407,15 @@ pub const Value = extern union {
393407 /// It's intentional that this function is not passed a corresponding Type, so that
394408 /// a Value can be copied from a Sema to a Decl prior to resolving struct/union field types.
395409 pub fn copy(self: Value, arena: Allocator) error{OutOfMemory}!Value {
396 if (@enumToInt(self.tag_if_small_enough) < Tag.no_payload_count) {
397 return Value{ .tag_if_small_enough = self.tag_if_small_enough };
398 } else switch (self.ptr_otherwise.tag) {
410 if (self.ip_index != .none) {
411 return Value{ .ip_index = self.ip_index, .legacy = undefined };
412 }
413 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
414 return Value{
415 .ip_index = .none,
416 .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough },
417 };
418 } else switch (self.legacy.ptr_otherwise.tag) {
399419 .u1_type,
400420 .u8_type,
401421 .i8_type,
......@@ -435,10 +455,6 @@ pub const Value = extern union {
435455 .noreturn_type,
436456 .null_type,
437457 .undefined_type,
438 .fn_noreturn_no_args_type,
439 .fn_void_no_args_type,
440 .fn_naked_noreturn_no_args_type,
441 .fn_ccc_void_no_args_type,
442458 .single_const_pointer_to_comptime_int_type,
443459 .anyframe_type,
444460 .const_slice_u8_type,
......@@ -481,19 +497,24 @@ pub const Value = extern union {
481497 .base = payload.base,
482498 .data = try payload.data.copy(arena),
483499 };
484 return Value{ .ptr_otherwise = &new_payload.base };
500 return Value{
501 .ip_index = .none,
502 .legacy = .{ .ptr_otherwise = &new_payload.base },
503 };
485504 },
486 .int_type => return self.copyPayloadShallow(arena, Payload.IntType),
487505 .int_u64 => return self.copyPayloadShallow(arena, Payload.U64),
488506 .int_i64 => return self.copyPayloadShallow(arena, Payload.I64),
489507 .int_big_positive, .int_big_negative => {
490508 const old_payload = self.cast(Payload.BigInt).?;
491509 const new_payload = try arena.create(Payload.BigInt);
492510 new_payload.* = .{
493 .base = .{ .tag = self.ptr_otherwise.tag },
511 .base = .{ .tag = self.legacy.ptr_otherwise.tag },
494512 .data = try arena.dupe(std.math.big.Limb, old_payload.data),
495513 };
496 return Value{ .ptr_otherwise = &new_payload.base };
514 return Value{
515 .ip_index = .none,
516 .legacy = .{ .ptr_otherwise = &new_payload.base },
517 };
497518 },
498519 .function => return self.copyPayloadShallow(arena, Payload.Function),
499520 .extern_fn => return self.copyPayloadShallow(arena, Payload.ExternFn),
......@@ -512,7 +533,10 @@ pub const Value = extern union {
512533 .container_ty = try payload.data.container_ty.copy(arena),
513534 },
514535 };
515 return Value{ .ptr_otherwise = &new_payload.base };
536 return Value{
537 .ip_index = .none,
538 .legacy = .{ .ptr_otherwise = &new_payload.base },
539 };
516540 },
517541 .comptime_field_ptr => {
518542 const payload = self.cast(Payload.ComptimeFieldPtr).?;
......@@ -524,7 +548,10 @@ pub const Value = extern union {
524548 .field_ty = try payload.data.field_ty.copy(arena),
525549 },
526550 };
527 return Value{ .ptr_otherwise = &new_payload.base };
551 return Value{
552 .ip_index = .none,
553 .legacy = .{ .ptr_otherwise = &new_payload.base },
554 };
528555 },
529556 .elem_ptr => {
530557 const payload = self.castTag(.elem_ptr).?;
......@@ -537,7 +564,10 @@ pub const Value = extern union {
537564 .index = payload.data.index,
538565 },
539566 };
540 return Value{ .ptr_otherwise = &new_payload.base };
567 return Value{
568 .ip_index = .none,
569 .legacy = .{ .ptr_otherwise = &new_payload.base },
570 };
541571 },
542572 .field_ptr => {
543573 const payload = self.castTag(.field_ptr).?;
......@@ -550,7 +580,10 @@ pub const Value = extern union {
550580 .field_index = payload.data.field_index,
551581 },
552582 };
553 return Value{ .ptr_otherwise = &new_payload.base };
583 return Value{
584 .ip_index = .none,
585 .legacy = .{ .ptr_otherwise = &new_payload.base },
586 };
554587 },
555588 .bytes => {
556589 const bytes = self.castTag(.bytes).?.data;
......@@ -559,7 +592,10 @@ pub const Value = extern union {
559592 .base = .{ .tag = .bytes },
560593 .data = try arena.dupe(u8, bytes),
561594 };
562 return Value{ .ptr_otherwise = &new_payload.base };
595 return Value{
596 .ip_index = .none,
597 .legacy = .{ .ptr_otherwise = &new_payload.base },
598 };
563599 },
564600 .str_lit => return self.copyPayloadShallow(arena, Payload.StrLit),
565601 .repeated,
......@@ -574,7 +610,10 @@ pub const Value = extern union {
574610 .base = payload.base,
575611 .data = try payload.data.copy(arena),
576612 };
577 return Value{ .ptr_otherwise = &new_payload.base };
613 return Value{
614 .ip_index = .none,
615 .legacy = .{ .ptr_otherwise = &new_payload.base },
616 };
578617 },
579618 .slice => {
580619 const payload = self.castTag(.slice).?;
......@@ -586,7 +625,10 @@ pub const Value = extern union {
586625 .len = try payload.data.len.copy(arena),
587626 },
588627 };
589 return Value{ .ptr_otherwise = &new_payload.base };
628 return Value{
629 .ip_index = .none,
630 .legacy = .{ .ptr_otherwise = &new_payload.base },
631 };
590632 },
591633 .float_16 => return self.copyPayloadShallow(arena, Payload.Float_16),
592634 .float_32 => return self.copyPayloadShallow(arena, Payload.Float_32),
......@@ -600,7 +642,10 @@ pub const Value = extern union {
600642 .base = payload.base,
601643 .data = try arena.dupe(u8, payload.data),
602644 };
603 return Value{ .ptr_otherwise = &new_payload.base };
645 return Value{
646 .ip_index = .none,
647 .legacy = .{ .ptr_otherwise = &new_payload.base },
648 };
604649 },
605650 .enum_field_index => return self.copyPayloadShallow(arena, Payload.U32),
606651 .@"error" => return self.copyPayloadShallow(arena, Payload.Error),
......@@ -615,7 +660,10 @@ pub const Value = extern union {
615660 for (new_payload.data, 0..) |*elem, i| {
616661 elem.* = try payload.data[i].copy(arena);
617662 }
618 return Value{ .ptr_otherwise = &new_payload.base };
663 return Value{
664 .ip_index = .none,
665 .legacy = .{ .ptr_otherwise = &new_payload.base },
666 };
619667 },
620668
621669 .@"union" => {
......@@ -628,7 +676,10 @@ pub const Value = extern union {
628676 .val = try tag_and_val.val.copy(arena),
629677 },
630678 };
631 return Value{ .ptr_otherwise = &new_payload.base };
679 return Value{
680 .ip_index = .none,
681 .legacy = .{ .ptr_otherwise = &new_payload.base },
682 };
632683 },
633684
634685 .inferred_alloc => unreachable,
......@@ -640,7 +691,10 @@ pub const Value = extern union {
640691 const payload = self.cast(T).?;
641692 const new_payload = try arena.create(T);
642693 new_payload.* = payload.*;
643 return Value{ .ptr_otherwise = &new_payload.base };
694 return Value{
695 .ip_index = .none,
696 .legacy = .{ .ptr_otherwise = &new_payload.base },
697 };
644698 }
645699
646700 pub fn format(val: Value, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
......@@ -660,6 +714,10 @@ pub const Value = extern union {
660714 out_stream: anytype,
661715 ) !void {
662716 comptime assert(fmt.len == 0);
717 if (start_val.ip_index != .none) {
718 try out_stream.print("(interned {d})", .{@enumToInt(start_val.ip_index)});
719 return;
720 }
663721 var val = start_val;
664722 while (true) switch (val.tag()) {
665723 .u1_type => return out_stream.writeAll("u1"),
......@@ -701,10 +759,6 @@ pub const Value = extern union {
701759 .noreturn_type => return out_stream.writeAll("noreturn"),
702760 .null_type => return out_stream.writeAll("@Type(.Null)"),
703761 .undefined_type => return out_stream.writeAll("@Type(.Undefined)"),
704 .fn_noreturn_no_args_type => return out_stream.writeAll("fn() noreturn"),
705 .fn_void_no_args_type => return out_stream.writeAll("fn() void"),
706 .fn_naked_noreturn_no_args_type => return out_stream.writeAll("fn() callconv(.Naked) noreturn"),
707 .fn_ccc_void_no_args_type => return out_stream.writeAll("fn() callconv(.C) void"),
708762 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
709763 .anyframe_type => return out_stream.writeAll("anyframe"),
710764 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),
......@@ -755,13 +809,6 @@ pub const Value = extern union {
755809 try val.castTag(.lazy_size).?.data.dump("", options, out_stream);
756810 return try out_stream.writeAll(")");
757811 },
758 .int_type => {
759 const int_type = val.castTag(.int_type).?.data;
760 return out_stream.print("{s}{d}", .{
761 if (int_type.signed) "s" else "u",
762 int_type.bits,
763 });
764 },
765812 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", options, out_stream),
766813 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, out_stream),
767814 .int_big_positive => return out_stream.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
......@@ -848,7 +895,6 @@ pub const Value = extern union {
848895 /// Asserts that the value is representable as an array of bytes.
849896 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
850897 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {
851 const target = mod.getTarget();
852898 switch (val.tag()) {
853899 .bytes => {
854900 const bytes = val.castTag(.bytes).?.data;
......@@ -863,7 +909,7 @@ pub const Value = extern union {
863909 },
864910 .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data),
865911 .repeated => {
866 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt(target));
912 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt(mod));
867913 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen()));
868914 @memset(result, byte);
869915 return result;
......@@ -877,7 +923,7 @@ pub const Value = extern union {
877923 .the_only_possible_value => return &[_]u8{},
878924 .slice => {
879925 const slice = val.castTag(.slice).?.data;
880 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(target), allocator, mod);
926 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(mod), allocator, mod);
881927 },
882928 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator, mod),
883929 }
......@@ -888,15 +934,19 @@ pub const Value = extern union {
888934 var elem_value_buf: ElemValueBuffer = undefined;
889935 for (result, 0..) |*elem, i| {
890936 const elem_val = val.elemValueBuffer(mod, i, &elem_value_buf);
891 elem.* = @intCast(u8, elem_val.toUnsignedInt(mod.getTarget()));
937 elem.* = @intCast(u8, elem_val.toUnsignedInt(mod));
892938 }
893939 return result;
894940 }
895941
896 pub const ToTypeBuffer = Type.Payload.Bits;
897
898942 /// Asserts that the value is representable as a type.
899 pub fn toType(self: Value, buffer: *ToTypeBuffer) Type {
943 pub fn toType(self: Value) Type {
944 if (self.ip_index != .none) {
945 return .{
946 .ip_index = self.ip_index,
947 .legacy = undefined,
948 };
949 }
900950 return switch (self.tag()) {
901951 .ty => self.castTag(.ty).?.data,
902952 .u1_type => Type.initTag(.u1),
......@@ -938,10 +988,6 @@ pub const Value = extern union {
938988 .noreturn_type => Type.initTag(.noreturn),
939989 .null_type => Type.initTag(.null),
940990 .undefined_type => Type.initTag(.undefined),
941 .fn_noreturn_no_args_type => Type.initTag(.fn_noreturn_no_args),
942 .fn_void_no_args_type => Type.initTag(.fn_void_no_args),
943 .fn_naked_noreturn_no_args_type => Type.initTag(.fn_naked_noreturn_no_args),
944 .fn_ccc_void_no_args_type => Type.initTag(.fn_ccc_void_no_args),
945991 .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
946992 .anyframe_type => Type.initTag(.@"anyframe"),
947993 .const_slice_u8_type => Type.initTag(.const_slice_u8),
......@@ -964,17 +1010,6 @@ pub const Value = extern union {
9641010 .extern_options_type => Type.initTag(.extern_options),
9651011 .type_info_type => Type.initTag(.type_info),
9661012
967 .int_type => {
968 const payload = self.castTag(.int_type).?.data;
969 buffer.* = .{
970 .base = .{
971 .tag = if (payload.signed) .int_signed else .int_unsigned,
972 },
973 .data = payload.bits,
974 };
975 return Type.initPayload(&buffer.base);
976 },
977
9781013 else => unreachable,
9791014 };
9801015 }
......@@ -1050,7 +1085,7 @@ pub const Value = extern union {
10501085 }
10511086
10521087 pub fn tagName(val: Value, ty: Type, mod: *Module) []const u8 {
1053 if (ty.zigTypeTag() == .Union) return val.unionTag().tagName(ty.unionTagTypeHypothetical(), mod);
1088 if (ty.zigTypeTag(mod) == .Union) return val.unionTag().tagName(ty.unionTagTypeHypothetical(), mod);
10541089
10551090 const field_index = switch (val.tag()) {
10561091 .enum_field_index => val.castTag(.enum_field_index).?.data,
......@@ -1068,10 +1103,9 @@ pub const Value = extern union {
10681103 };
10691104 if (values.entries.len == 0) {
10701105 // auto-numbered enum
1071 break :field_index @intCast(u32, val.toUnsignedInt(mod.getTarget()));
1106 break :field_index @intCast(u32, val.toUnsignedInt(mod));
10721107 }
1073 var buffer: Type.Payload.Bits = undefined;
1074 const int_tag_ty = ty.intTagType(&buffer);
1108 const int_tag_ty = ty.intTagType();
10751109 break :field_index @intCast(u32, values.getIndexContext(val, .{ .ty = int_tag_ty, .mod = mod }).?);
10761110 },
10771111 };
......@@ -1086,15 +1120,15 @@ pub const Value = extern union {
10861120 }
10871121
10881122 /// Asserts the value is an integer.
1089 pub fn toBigInt(val: Value, space: *BigIntSpace, target: Target) BigIntConst {
1090 return val.toBigIntAdvanced(space, target, null) catch unreachable;
1123 pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *const Module) BigIntConst {
1124 return val.toBigIntAdvanced(space, mod, null) catch unreachable;
10911125 }
10921126
10931127 /// Asserts the value is an integer.
10941128 pub fn toBigIntAdvanced(
10951129 val: Value,
10961130 space: *BigIntSpace,
1097 target: Target,
1131 mod: *const Module,
10981132 opt_sema: ?*Sema,
10991133 ) Module.CompileError!BigIntConst {
11001134 switch (val.tag()) {
......@@ -1114,7 +1148,7 @@ pub const Value = extern union {
11141148 },
11151149 .runtime_value => {
11161150 const sub_val = val.castTag(.runtime_value).?.data;
1117 return sub_val.toBigIntAdvanced(space, target, opt_sema);
1151 return sub_val.toBigIntAdvanced(space, mod, opt_sema);
11181152 },
11191153 .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
11201154 .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
......@@ -1128,7 +1162,7 @@ pub const Value = extern union {
11281162 if (opt_sema) |sema| {
11291163 try sema.resolveTypeLayout(ty);
11301164 }
1131 const x = ty.abiAlignment(target);
1165 const x = ty.abiAlignment(mod);
11321166 return BigIntMutable.init(&space.limbs, x).toConst();
11331167 },
11341168 .lazy_size => {
......@@ -1136,14 +1170,14 @@ pub const Value = extern union {
11361170 if (opt_sema) |sema| {
11371171 try sema.resolveTypeLayout(ty);
11381172 }
1139 const x = ty.abiSize(target);
1173 const x = ty.abiSize(mod);
11401174 return BigIntMutable.init(&space.limbs, x).toConst();
11411175 },
11421176
11431177 .elem_ptr => {
11441178 const elem_ptr = val.castTag(.elem_ptr).?.data;
1145 const array_addr = (try elem_ptr.array_ptr.getUnsignedIntAdvanced(target, opt_sema)).?;
1146 const elem_size = elem_ptr.elem_ty.abiSize(target);
1179 const array_addr = (try elem_ptr.array_ptr.getUnsignedIntAdvanced(mod, opt_sema)).?;
1180 const elem_size = elem_ptr.elem_ty.abiSize(mod);
11471181 const new_addr = array_addr + elem_size * elem_ptr.index;
11481182 return BigIntMutable.init(&space.limbs, new_addr).toConst();
11491183 },
......@@ -1154,13 +1188,13 @@ pub const Value = extern union {
11541188
11551189 /// If the value fits in a u64, return it, otherwise null.
11561190 /// Asserts not undefined.
1157 pub fn getUnsignedInt(val: Value, target: Target) ?u64 {
1158 return getUnsignedIntAdvanced(val, target, null) catch unreachable;
1191 pub fn getUnsignedInt(val: Value, mod: *const Module) ?u64 {
1192 return getUnsignedIntAdvanced(val, mod, null) catch unreachable;
11591193 }
11601194
11611195 /// If the value fits in a u64, return it, otherwise null.
11621196 /// Asserts not undefined.
1163 pub fn getUnsignedIntAdvanced(val: Value, target: Target, opt_sema: ?*Sema) !?u64 {
1197 pub fn getUnsignedIntAdvanced(val: Value, mod: *const Module, opt_sema: ?*Sema) !?u64 {
11641198 switch (val.tag()) {
11651199 .zero,
11661200 .bool_false,
......@@ -1181,17 +1215,17 @@ pub const Value = extern union {
11811215 .lazy_align => {
11821216 const ty = val.castTag(.lazy_align).?.data;
11831217 if (opt_sema) |sema| {
1184 return (try ty.abiAlignmentAdvanced(target, .{ .sema = sema })).scalar;
1218 return (try ty.abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;
11851219 } else {
1186 return ty.abiAlignment(target);
1220 return ty.abiAlignment(mod);
11871221 }
11881222 },
11891223 .lazy_size => {
11901224 const ty = val.castTag(.lazy_size).?.data;
11911225 if (opt_sema) |sema| {
1192 return (try ty.abiSizeAdvanced(target, .{ .sema = sema })).scalar;
1226 return (try ty.abiSizeAdvanced(mod, .{ .sema = sema })).scalar;
11931227 } else {
1194 return ty.abiSize(target);
1228 return ty.abiSize(mod);
11951229 }
11961230 },
11971231
......@@ -1200,12 +1234,12 @@ pub const Value = extern union {
12001234 }
12011235
12021236 /// Asserts the value is an integer and it fits in a u64
1203 pub fn toUnsignedInt(val: Value, target: Target) u64 {
1204 return getUnsignedInt(val, target).?;
1237 pub fn toUnsignedInt(val: Value, mod: *const Module) u64 {
1238 return getUnsignedInt(val, mod).?;
12051239 }
12061240
12071241 /// Asserts the value is an integer and it fits in a i64
1208 pub fn toSignedInt(val: Value, target: Target) i64 {
1242 pub fn toSignedInt(val: Value, mod: *const Module) i64 {
12091243 switch (val.tag()) {
12101244 .zero,
12111245 .bool_false,
......@@ -1223,11 +1257,11 @@ pub const Value = extern union {
12231257
12241258 .lazy_align => {
12251259 const ty = val.castTag(.lazy_align).?.data;
1226 return @intCast(i64, ty.abiAlignment(target));
1260 return @intCast(i64, ty.abiAlignment(mod));
12271261 },
12281262 .lazy_size => {
12291263 const ty = val.castTag(.lazy_size).?.data;
1230 return @intCast(i64, ty.abiSize(target));
1264 return @intCast(i64, ty.abiSize(mod));
12311265 },
12321266
12331267 .undef => unreachable,
......@@ -1276,17 +1310,17 @@ pub const Value = extern union {
12761310 const target = mod.getTarget();
12771311 const endian = target.cpu.arch.endian();
12781312 if (val.isUndef()) {
1279 const size = @intCast(usize, ty.abiSize(target));
1313 const size = @intCast(usize, ty.abiSize(mod));
12801314 @memset(buffer[0..size], 0xaa);
12811315 return;
12821316 }
1283 switch (ty.zigTypeTag()) {
1317 switch (ty.zigTypeTag(mod)) {
12841318 .Void => {},
12851319 .Bool => {
12861320 buffer[0] = @boolToInt(val.toBool());
12871321 },
12881322 .Int, .Enum => {
1289 const int_info = ty.intInfo(target);
1323 const int_info = ty.intInfo(mod);
12901324 const bits = int_info.bits;
12911325 const byte_count = (bits + 7) / 8;
12921326
......@@ -1307,7 +1341,7 @@ pub const Value = extern union {
13071341 };
13081342 } else {
13091343 var bigint_buffer: BigIntSpace = undefined;
1310 const bigint = int_val.toBigInt(&bigint_buffer, target);
1344 const bigint = int_val.toBigInt(&bigint_buffer, mod);
13111345 bigint.writeTwosComplement(buffer[0..byte_count], endian);
13121346 }
13131347 },
......@@ -1322,7 +1356,7 @@ pub const Value = extern union {
13221356 .Array => {
13231357 const len = ty.arrayLen();
13241358 const elem_ty = ty.childType();
1325 const elem_size = @intCast(usize, elem_ty.abiSize(target));
1359 const elem_size = @intCast(usize, elem_ty.abiSize(mod));
13261360 var elem_i: usize = 0;
13271361 var elem_value_buf: ElemValueBuffer = undefined;
13281362 var buf_off: usize = 0;
......@@ -1335,7 +1369,7 @@ pub const Value = extern union {
13351369 .Vector => {
13361370 // We use byte_count instead of abi_size here, so that any padding bytes
13371371 // follow the data bytes, on both big- and little-endian systems.
1338 const byte_count = (@intCast(usize, ty.bitSize(target)) + 7) / 8;
1372 const byte_count = (@intCast(usize, ty.bitSize(mod)) + 7) / 8;
13391373 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);
13401374 },
13411375 .Struct => switch (ty.containerLayout()) {
......@@ -1344,12 +1378,12 @@ pub const Value = extern union {
13441378 const fields = ty.structFields().values();
13451379 const field_vals = val.castTag(.aggregate).?.data;
13461380 for (fields, 0..) |field, i| {
1347 const off = @intCast(usize, ty.structFieldOffset(i, target));
1381 const off = @intCast(usize, ty.structFieldOffset(i, mod));
13481382 try writeToMemory(field_vals[i], field.ty, mod, buffer[off..]);
13491383 }
13501384 },
13511385 .Packed => {
1352 const byte_count = (@intCast(usize, ty.bitSize(target)) + 7) / 8;
1386 const byte_count = (@intCast(usize, ty.bitSize(mod)) + 7) / 8;
13531387 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);
13541388 },
13551389 },
......@@ -1363,7 +1397,7 @@ pub const Value = extern union {
13631397 .Auto => return error.IllDefinedMemoryLayout,
13641398 .Extern => return error.Unimplemented,
13651399 .Packed => {
1366 const byte_count = (@intCast(usize, ty.bitSize(target)) + 7) / 8;
1400 const byte_count = (@intCast(usize, ty.bitSize(mod)) + 7) / 8;
13671401 return writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0);
13681402 },
13691403 },
......@@ -1373,10 +1407,10 @@ pub const Value = extern union {
13731407 return val.writeToMemory(Type.usize, mod, buffer);
13741408 },
13751409 .Optional => {
1376 if (!ty.isPtrLikeOptional()) return error.IllDefinedMemoryLayout;
1410 if (!ty.isPtrLikeOptional(mod)) return error.IllDefinedMemoryLayout;
13771411 var buf: Type.Payload.ElemType = undefined;
13781412 const child = ty.optionalChild(&buf);
1379 const opt_val = val.optionalValue();
1413 const opt_val = val.optionalValue(mod);
13801414 if (opt_val) |some| {
13811415 return some.writeToMemory(child, mod, buffer);
13821416 } else {
......@@ -1395,11 +1429,11 @@ pub const Value = extern union {
13951429 const target = mod.getTarget();
13961430 const endian = target.cpu.arch.endian();
13971431 if (val.isUndef()) {
1398 const bit_size = @intCast(usize, ty.bitSize(target));
1432 const bit_size = @intCast(usize, ty.bitSize(mod));
13991433 std.mem.writeVarPackedInt(buffer, bit_offset, bit_size, @as(u1, 0), endian);
14001434 return;
14011435 }
1402 switch (ty.zigTypeTag()) {
1436 switch (ty.zigTypeTag(mod)) {
14031437 .Void => {},
14041438 .Bool => {
14051439 const byte_index = switch (endian) {
......@@ -1413,8 +1447,8 @@ pub const Value = extern union {
14131447 }
14141448 },
14151449 .Int, .Enum => {
1416 const bits = ty.intInfo(target).bits;
1417 const abi_size = @intCast(usize, ty.abiSize(target));
1450 const bits = ty.intInfo(mod).bits;
1451 const abi_size = @intCast(usize, ty.abiSize(mod));
14181452
14191453 var enum_buffer: Payload.U64 = undefined;
14201454 const int_val = val.enumToInt(ty, &enum_buffer);
......@@ -1431,7 +1465,7 @@ pub const Value = extern union {
14311465 std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian);
14321466 } else {
14331467 var bigint_buffer: BigIntSpace = undefined;
1434 const bigint = int_val.toBigInt(&bigint_buffer, target);
1468 const bigint = int_val.toBigInt(&bigint_buffer, mod);
14351469 bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian);
14361470 }
14371471 },
......@@ -1445,7 +1479,7 @@ pub const Value = extern union {
14451479 },
14461480 .Vector => {
14471481 const elem_ty = ty.childType();
1448 const elem_bit_size = @intCast(u16, elem_ty.bitSize(target));
1482 const elem_bit_size = @intCast(u16, elem_ty.bitSize(mod));
14491483 const len = @intCast(usize, ty.arrayLen());
14501484
14511485 var bits: u16 = 0;
......@@ -1467,7 +1501,7 @@ pub const Value = extern union {
14671501 const fields = ty.structFields().values();
14681502 const field_vals = val.castTag(.aggregate).?.data;
14691503 for (fields, 0..) |field, i| {
1470 const field_bits = @intCast(u16, field.ty.bitSize(target));
1504 const field_bits = @intCast(u16, field.ty.bitSize(mod));
14711505 try field_vals[i].writeToPackedMemory(field.ty, mod, buffer, bit_offset + bits);
14721506 bits += field_bits;
14731507 }
......@@ -1479,7 +1513,7 @@ pub const Value = extern union {
14791513 .Packed => {
14801514 const field_index = ty.unionTagFieldIndex(val.unionTag(), mod);
14811515 const field_type = ty.unionFields().values()[field_index.?].ty;
1482 const field_val = val.fieldValue(field_type, field_index.?);
1516 const field_val = val.fieldValue(field_type, mod, field_index.?);
14831517
14841518 return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset);
14851519 },
......@@ -1490,10 +1524,10 @@ pub const Value = extern union {
14901524 return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset);
14911525 },
14921526 .Optional => {
1493 assert(ty.isPtrLikeOptional());
1527 assert(ty.isPtrLikeOptional(mod));
14941528 var buf: Type.Payload.ElemType = undefined;
14951529 const child = ty.optionalChild(&buf);
1496 const opt_val = val.optionalValue();
1530 const opt_val = val.optionalValue(mod);
14971531 if (opt_val) |some| {
14981532 return some.writeToPackedMemory(child, mod, buffer, bit_offset);
14991533 } else {
......@@ -1516,7 +1550,7 @@ pub const Value = extern union {
15161550 ) Allocator.Error!Value {
15171551 const target = mod.getTarget();
15181552 const endian = target.cpu.arch.endian();
1519 switch (ty.zigTypeTag()) {
1553 switch (ty.zigTypeTag(mod)) {
15201554 .Void => return Value.void,
15211555 .Bool => {
15221556 if (buffer[0] == 0) {
......@@ -1526,7 +1560,7 @@ pub const Value = extern union {
15261560 }
15271561 },
15281562 .Int, .Enum => {
1529 const int_info = ty.intInfo(target);
1563 const int_info = ty.intInfo(mod);
15301564 const bits = int_info.bits;
15311565 const byte_count = (bits + 7) / 8;
15321566 if (bits == 0 or buffer.len == 0) return Value.zero;
......@@ -1560,7 +1594,7 @@ pub const Value = extern union {
15601594 },
15611595 .Array => {
15621596 const elem_ty = ty.childType();
1563 const elem_size = elem_ty.abiSize(target);
1597 const elem_size = elem_ty.abiSize(mod);
15641598 const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen()));
15651599 var offset: usize = 0;
15661600 for (elems) |*elem| {
......@@ -1572,7 +1606,7 @@ pub const Value = extern union {
15721606 .Vector => {
15731607 // We use byte_count instead of abi_size here, so that any padding bytes
15741608 // follow the data bytes, on both big- and little-endian systems.
1575 const byte_count = (@intCast(usize, ty.bitSize(target)) + 7) / 8;
1609 const byte_count = (@intCast(usize, ty.bitSize(mod)) + 7) / 8;
15761610 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);
15771611 },
15781612 .Struct => switch (ty.containerLayout()) {
......@@ -1581,14 +1615,14 @@ pub const Value = extern union {
15811615 const fields = ty.structFields().values();
15821616 const field_vals = try arena.alloc(Value, fields.len);
15831617 for (fields, 0..) |field, i| {
1584 const off = @intCast(usize, ty.structFieldOffset(i, target));
1585 const sz = @intCast(usize, ty.structFieldType(i).abiSize(target));
1618 const off = @intCast(usize, ty.structFieldOffset(i, mod));
1619 const sz = @intCast(usize, ty.structFieldType(i).abiSize(mod));
15861620 field_vals[i] = try readFromMemory(field.ty, mod, buffer[off..(off + sz)], arena);
15871621 }
15881622 return Tag.aggregate.create(arena, field_vals);
15891623 },
15901624 .Packed => {
1591 const byte_count = (@intCast(usize, ty.bitSize(target)) + 7) / 8;
1625 const byte_count = (@intCast(usize, ty.bitSize(mod)) + 7) / 8;
15921626 return readFromPackedMemory(ty, mod, buffer[0..byte_count], 0, arena);
15931627 },
15941628 },
......@@ -1609,7 +1643,7 @@ pub const Value = extern union {
16091643 return readFromMemory(Type.usize, mod, buffer, arena);
16101644 },
16111645 .Optional => {
1612 assert(ty.isPtrLikeOptional());
1646 assert(ty.isPtrLikeOptional(mod));
16131647 var buf: Type.Payload.ElemType = undefined;
16141648 const child = ty.optionalChild(&buf);
16151649 return readFromMemory(child, mod, buffer, arena);
......@@ -1631,7 +1665,7 @@ pub const Value = extern union {
16311665 ) Allocator.Error!Value {
16321666 const target = mod.getTarget();
16331667 const endian = target.cpu.arch.endian();
1634 switch (ty.zigTypeTag()) {
1668 switch (ty.zigTypeTag(mod)) {
16351669 .Void => return Value.void,
16361670 .Bool => {
16371671 const byte = switch (endian) {
......@@ -1646,8 +1680,8 @@ pub const Value = extern union {
16461680 },
16471681 .Int, .Enum => {
16481682 if (buffer.len == 0) return Value.zero;
1649 const int_info = ty.intInfo(target);
1650 const abi_size = @intCast(usize, ty.abiSize(target));
1683 const int_info = ty.intInfo(mod);
1684 const abi_size = @intCast(usize, ty.abiSize(mod));
16511685
16521686 const bits = int_info.bits;
16531687 if (bits == 0) return Value.zero;
......@@ -1677,7 +1711,7 @@ pub const Value = extern union {
16771711 const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen()));
16781712
16791713 var bits: u16 = 0;
1680 const elem_bit_size = @intCast(u16, elem_ty.bitSize(target));
1714 const elem_bit_size = @intCast(u16, elem_ty.bitSize(mod));
16811715 for (elems, 0..) |_, i| {
16821716 // On big-endian systems, LLVM reverses the element order of vectors by default
16831717 const tgt_elem_i = if (endian == .Big) elems.len - i - 1 else i;
......@@ -1694,7 +1728,7 @@ pub const Value = extern union {
16941728 const fields = ty.structFields().values();
16951729 const field_vals = try arena.alloc(Value, fields.len);
16961730 for (fields, 0..) |field, i| {
1697 const field_bits = @intCast(u16, field.ty.bitSize(target));
1731 const field_bits = @intCast(u16, field.ty.bitSize(mod));
16981732 field_vals[i] = try readFromPackedMemory(field.ty, mod, buffer, bit_offset + bits, arena);
16991733 bits += field_bits;
17001734 }
......@@ -1706,7 +1740,7 @@ pub const Value = extern union {
17061740 return readFromPackedMemory(Type.usize, mod, buffer, bit_offset, arena);
17071741 },
17081742 .Optional => {
1709 assert(ty.isPtrLikeOptional());
1743 assert(ty.isPtrLikeOptional(mod));
17101744 var buf: Type.Payload.ElemType = undefined;
17111745 const child = ty.optionalChild(&buf);
17121746 return readFromPackedMemory(child, mod, buffer, bit_offset, arena);
......@@ -1764,8 +1798,8 @@ pub const Value = extern union {
17641798 }
17651799 }
17661800
1767 pub fn clz(val: Value, ty: Type, target: Target) u64 {
1768 const ty_bits = ty.intInfo(target).bits;
1801 pub fn clz(val: Value, ty: Type, mod: *const Module) u64 {
1802 const ty_bits = ty.intInfo(mod).bits;
17691803 switch (val.tag()) {
17701804 .zero, .bool_false => return ty_bits,
17711805 .one, .bool_true => return ty_bits - 1,
......@@ -1792,7 +1826,7 @@ pub const Value = extern union {
17921826
17931827 .lazy_align, .lazy_size => {
17941828 var bigint_buf: BigIntSpace = undefined;
1795 const bigint = val.toBigIntAdvanced(&bigint_buf, target, null) catch unreachable;
1829 const bigint = val.toBigIntAdvanced(&bigint_buf, mod, null) catch unreachable;
17961830 return bigint.clz(ty_bits);
17971831 },
17981832
......@@ -1800,8 +1834,8 @@ pub const Value = extern union {
18001834 }
18011835 }
18021836
1803 pub fn ctz(val: Value, ty: Type, target: Target) u64 {
1804 const ty_bits = ty.intInfo(target).bits;
1837 pub fn ctz(val: Value, ty: Type, mod: *const Module) u64 {
1838 const ty_bits = ty.intInfo(mod).bits;
18051839 switch (val.tag()) {
18061840 .zero, .bool_false => return ty_bits,
18071841 .one, .bool_true => return 0,
......@@ -1828,7 +1862,7 @@ pub const Value = extern union {
18281862
18291863 .lazy_align, .lazy_size => {
18301864 var bigint_buf: BigIntSpace = undefined;
1831 const bigint = val.toBigIntAdvanced(&bigint_buf, target, null) catch unreachable;
1865 const bigint = val.toBigIntAdvanced(&bigint_buf, mod, null) catch unreachable;
18321866 return bigint.ctz();
18331867 },
18341868
......@@ -1836,7 +1870,7 @@ pub const Value = extern union {
18361870 }
18371871 }
18381872
1839 pub fn popCount(val: Value, ty: Type, target: Target) u64 {
1873 pub fn popCount(val: Value, ty: Type, mod: *const Module) u64 {
18401874 assert(!val.isUndef());
18411875 switch (val.tag()) {
18421876 .zero, .bool_false => return 0,
......@@ -1845,22 +1879,22 @@ pub const Value = extern union {
18451879 .int_u64 => return @popCount(val.castTag(.int_u64).?.data),
18461880
18471881 else => {
1848 const info = ty.intInfo(target);
1882 const info = ty.intInfo(mod);
18491883
18501884 var buffer: Value.BigIntSpace = undefined;
1851 const int = val.toBigInt(&buffer, target);
1885 const int = val.toBigInt(&buffer, mod);
18521886 return @intCast(u64, int.popCount(info.bits));
18531887 },
18541888 }
18551889 }
18561890
1857 pub fn bitReverse(val: Value, ty: Type, target: Target, arena: Allocator) !Value {
1891 pub fn bitReverse(val: Value, ty: Type, mod: *const Module, arena: Allocator) !Value {
18581892 assert(!val.isUndef());
18591893
1860 const info = ty.intInfo(target);
1894 const info = ty.intInfo(mod);
18611895
18621896 var buffer: Value.BigIntSpace = undefined;
1863 const operand_bigint = val.toBigInt(&buffer, target);
1897 const operand_bigint = val.toBigInt(&buffer, mod);
18641898
18651899 const limbs = try arena.alloc(
18661900 std.math.big.Limb,
......@@ -1872,16 +1906,16 @@ pub const Value = extern union {
18721906 return fromBigInt(arena, result_bigint.toConst());
18731907 }
18741908
1875 pub fn byteSwap(val: Value, ty: Type, target: Target, arena: Allocator) !Value {
1909 pub fn byteSwap(val: Value, ty: Type, mod: *const Module, arena: Allocator) !Value {
18761910 assert(!val.isUndef());
18771911
1878 const info = ty.intInfo(target);
1912 const info = ty.intInfo(mod);
18791913
18801914 // Bit count must be evenly divisible by 8
18811915 assert(info.bits % 8 == 0);
18821916
18831917 var buffer: Value.BigIntSpace = undefined;
1884 const operand_bigint = val.toBigInt(&buffer, target);
1918 const operand_bigint = val.toBigInt(&buffer, mod);
18851919
18861920 const limbs = try arena.alloc(
18871921 std.math.big.Limb,
......@@ -1895,7 +1929,8 @@ pub const Value = extern union {
18951929
18961930 /// Asserts the value is an integer and not undefined.
18971931 /// Returns the number of bits the value requires to represent stored in twos complement form.
1898 pub fn intBitCountTwosComp(self: Value, target: Target) usize {
1932 pub fn intBitCountTwosComp(self: Value, mod: *const Module) usize {
1933 const target = mod.getTarget();
18991934 switch (self.tag()) {
19001935 .zero,
19011936 .bool_false,
......@@ -1926,7 +1961,7 @@ pub const Value = extern union {
19261961
19271962 else => {
19281963 var buffer: BigIntSpace = undefined;
1929 return self.toBigInt(&buffer, target).bitCountTwosComp();
1964 return self.toBigInt(&buffer, mod).bitCountTwosComp();
19301965 },
19311966 }
19321967 }
......@@ -1962,12 +1997,13 @@ pub const Value = extern union {
19621997 };
19631998 }
19641999
1965 pub fn orderAgainstZero(lhs: Value) std.math.Order {
1966 return orderAgainstZeroAdvanced(lhs, null) catch unreachable;
2000 pub fn orderAgainstZero(lhs: Value, mod: *const Module) std.math.Order {
2001 return orderAgainstZeroAdvanced(lhs, mod, null) catch unreachable;
19672002 }
19682003
19692004 pub fn orderAgainstZeroAdvanced(
19702005 lhs: Value,
2006 mod: *const Module,
19712007 opt_sema: ?*Sema,
19722008 ) Module.CompileError!std.math.Order {
19732009 return switch (lhs.tag()) {
......@@ -1991,7 +2027,7 @@ pub const Value = extern union {
19912027 // This is needed to correctly handle hashing the value.
19922028 // Checks in Sema should prevent direct comparisons from reaching here.
19932029 const val = lhs.castTag(.runtime_value).?.data;
1994 return val.orderAgainstZeroAdvanced(opt_sema);
2030 return val.orderAgainstZeroAdvanced(mod, opt_sema);
19952031 },
19962032 .int_u64 => std.math.order(lhs.castTag(.int_u64).?.data, 0),
19972033 .int_i64 => std.math.order(lhs.castTag(.int_i64).?.data, 0),
......@@ -2001,7 +2037,7 @@ pub const Value = extern union {
20012037 .lazy_align => {
20022038 const ty = lhs.castTag(.lazy_align).?.data;
20032039 const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
2004 if (ty.hasRuntimeBitsAdvanced(false, strat) catch |err| switch (err) {
2040 if (ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
20052041 error.NeedLazy => unreachable,
20062042 else => |e| return e,
20072043 }) {
......@@ -2013,7 +2049,7 @@ pub const Value = extern union {
20132049 .lazy_size => {
20142050 const ty = lhs.castTag(.lazy_size).?.data;
20152051 const strat: Type.AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
2016 if (ty.hasRuntimeBitsAdvanced(false, strat) catch |err| switch (err) {
2052 if (ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
20172053 error.NeedLazy => unreachable,
20182054 else => |e| return e,
20192055 }) {
......@@ -2031,7 +2067,7 @@ pub const Value = extern union {
20312067
20322068 .elem_ptr => {
20332069 const elem_ptr = lhs.castTag(.elem_ptr).?.data;
2034 switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(opt_sema)) {
2070 switch (try elem_ptr.array_ptr.orderAgainstZeroAdvanced(mod, opt_sema)) {
20352071 .lt => unreachable,
20362072 .gt => return .gt,
20372073 .eq => {
......@@ -2049,17 +2085,17 @@ pub const Value = extern union {
20492085 }
20502086
20512087 /// Asserts the value is comparable.
2052 pub fn order(lhs: Value, rhs: Value, target: Target) std.math.Order {
2053 return orderAdvanced(lhs, rhs, target, null) catch unreachable;
2088 pub fn order(lhs: Value, rhs: Value, mod: *const Module) std.math.Order {
2089 return orderAdvanced(lhs, rhs, mod, null) catch unreachable;
20542090 }
20552091
20562092 /// Asserts the value is comparable.
20572093 /// If opt_sema is null then this function asserts things are resolved and cannot fail.
2058 pub fn orderAdvanced(lhs: Value, rhs: Value, target: Target, opt_sema: ?*Sema) !std.math.Order {
2094 pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *const Module, opt_sema: ?*Sema) !std.math.Order {
20592095 const lhs_tag = lhs.tag();
20602096 const rhs_tag = rhs.tag();
2061 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(opt_sema);
2062 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(opt_sema);
2097 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, opt_sema);
2098 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, opt_sema);
20632099 switch (lhs_against_zero) {
20642100 .lt => if (rhs_against_zero != .lt) return .lt,
20652101 .eq => return rhs_against_zero.invert(),
......@@ -2093,22 +2129,22 @@ pub const Value = extern union {
20932129
20942130 var lhs_bigint_space: BigIntSpace = undefined;
20952131 var rhs_bigint_space: BigIntSpace = undefined;
2096 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, target, opt_sema);
2097 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, target, opt_sema);
2132 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, mod, opt_sema);
2133 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, mod, opt_sema);
20982134 return lhs_bigint.order(rhs_bigint);
20992135 }
21002136
21012137 /// Asserts the value is comparable. Does not take a type parameter because it supports
21022138 /// comparisons between heterogeneous types.
2103 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, target: Target) bool {
2104 return compareHeteroAdvanced(lhs, op, rhs, target, null) catch unreachable;
2139 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, mod: *const Module) bool {
2140 return compareHeteroAdvanced(lhs, op, rhs, mod, null) catch unreachable;
21052141 }
21062142
21072143 pub fn compareHeteroAdvanced(
21082144 lhs: Value,
21092145 op: std.math.CompareOperator,
21102146 rhs: Value,
2111 target: Target,
2147 mod: *const Module,
21122148 opt_sema: ?*Sema,
21132149 ) !bool {
21142150 if (lhs.pointerDecl()) |lhs_decl| {
......@@ -2132,20 +2168,20 @@ pub const Value = extern union {
21322168 else => {},
21332169 }
21342170 }
2135 return (try orderAdvanced(lhs, rhs, target, opt_sema)).compare(op);
2171 return (try orderAdvanced(lhs, rhs, mod, opt_sema)).compare(op);
21362172 }
21372173
21382174 /// Asserts the values are comparable. Both operands have type `ty`.
21392175 /// For vectors, returns true if comparison is true for ALL elements.
21402176 pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, mod: *Module) bool {
2141 if (ty.zigTypeTag() == .Vector) {
2177 if (ty.zigTypeTag(mod) == .Vector) {
21422178 var i: usize = 0;
21432179 while (i < ty.vectorLen()) : (i += 1) {
21442180 var lhs_buf: Value.ElemValueBuffer = undefined;
21452181 var rhs_buf: Value.ElemValueBuffer = undefined;
21462182 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
21472183 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
2148 if (!compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(), mod)) {
2184 if (!compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod), mod)) {
21492185 return false;
21502186 }
21512187 }
......@@ -2165,7 +2201,7 @@ pub const Value = extern union {
21652201 return switch (op) {
21662202 .eq => lhs.eql(rhs, ty, mod),
21672203 .neq => !lhs.eql(rhs, ty, mod),
2168 else => compareHetero(lhs, op, rhs, mod.getTarget()),
2204 else => compareHetero(lhs, op, rhs, mod),
21692205 };
21702206 }
21712207
......@@ -2231,7 +2267,7 @@ pub const Value = extern union {
22312267 .float_128 => if (std.math.isNan(lhs.castTag(.float_128).?.data)) return op == .neq,
22322268 else => {},
22332269 }
2234 return (try orderAgainstZeroAdvanced(lhs, opt_sema)).compare(op);
2270 return (try orderAgainstZeroAdvanced(lhs, mod, opt_sema)).compare(op);
22352271 }
22362272
22372273 pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {
......@@ -2346,7 +2382,7 @@ pub const Value = extern union {
23462382 return true;
23472383 }
23482384
2349 if (ty.zigTypeTag() == .Struct) {
2385 if (ty.zigTypeTag(mod) == .Struct) {
23502386 const fields = ty.structFields().values();
23512387 assert(fields.len == a_field_vals.len);
23522388 for (fields, 0..) |field, i| {
......@@ -2406,12 +2442,10 @@ pub const Value = extern union {
24062442 return false;
24072443 }
24082444
2409 switch (ty.zigTypeTag()) {
2445 switch (ty.zigTypeTag(mod)) {
24102446 .Type => {
2411 var buf_a: ToTypeBuffer = undefined;
2412 var buf_b: ToTypeBuffer = undefined;
2413 const a_type = a.toType(&buf_a);
2414 const b_type = b.toType(&buf_b);
2447 const a_type = a.toType();
2448 const b_type = b.toType();
24152449 return a_type.eql(b_type, mod);
24162450 },
24172451 .Enum => {
......@@ -2419,8 +2453,7 @@ pub const Value = extern union {
24192453 var buf_b: Payload.U64 = undefined;
24202454 const a_val = a.enumToInt(ty, &buf_a);
24212455 const b_val = b.enumToInt(ty, &buf_b);
2422 var buf_ty: Type.Payload.Bits = undefined;
2423 const int_ty = ty.intTagType(&buf_ty);
2456 const int_ty = ty.intTagType();
24242457 return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema);
24252458 },
24262459 .Array, .Vector => {
......@@ -2466,11 +2499,11 @@ pub const Value = extern union {
24662499 // .the_one_possible_value,
24672500 // .aggregate,
24682501 // Note that we already checked above for matching tags, e.g. both .aggregate.
2469 return ty.onePossibleValue() != null;
2502 return ty.onePossibleValue(mod) != null;
24702503 },
24712504 .Union => {
24722505 // Here we have to check for value equality, as-if `a` has been coerced to `ty`.
2473 if (ty.onePossibleValue() != null) {
2506 if (ty.onePossibleValue(mod) != null) {
24742507 return true;
24752508 }
24762509 if (a_ty.castTag(.anon_struct)) |payload| {
......@@ -2533,13 +2566,13 @@ pub const Value = extern union {
25332566 else => {},
25342567 }
25352568 if (a_tag == .null_value or a_tag == .@"error") return false;
2536 return (try orderAdvanced(a, b, target, opt_sema)).compare(.eq);
2569 return (try orderAdvanced(a, b, mod, opt_sema)).compare(.eq);
25372570 }
25382571
25392572 /// This function is used by hash maps and so treats floating-point NaNs as equal
25402573 /// to each other, and not equal to other floating-point values.
25412574 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
2542 const zig_ty_tag = ty.zigTypeTag();
2575 const zig_ty_tag = ty.zigTypeTag(mod);
25432576 std.hash.autoHash(hasher, zig_ty_tag);
25442577 if (val.isUndef()) return;
25452578 // The value is runtime-known and shouldn't affect the hash.
......@@ -2555,8 +2588,7 @@ pub const Value = extern union {
25552588 => {},
25562589
25572590 .Type => {
2558 var buf: ToTypeBuffer = undefined;
2559 return val.toType(&buf).hashWithHasher(hasher, mod);
2591 return val.toType().hashWithHasher(hasher, mod);
25602592 },
25612593 .Float => {
25622594 // For hash/eql purposes, we treat floats as their IEEE integer representation.
......@@ -2588,7 +2620,7 @@ pub const Value = extern union {
25882620 hash(slice.len, Type.usize, hasher, mod);
25892621 },
25902622
2591 else => return hashPtr(val, hasher, mod.getTarget()),
2623 else => return hashPtr(val, hasher, mod),
25922624 },
25932625 .Array, .Vector => {
25942626 const len = ty.arrayLen();
......@@ -2648,7 +2680,7 @@ pub const Value = extern union {
26482680 .Enum => {
26492681 var enum_space: Payload.U64 = undefined;
26502682 const int_val = val.enumToInt(ty, &enum_space);
2651 hashInt(int_val, hasher, mod.getTarget());
2683 hashInt(int_val, hasher, mod);
26522684 },
26532685 .Union => {
26542686 const union_obj = val.cast(Payload.Union).?.data;
......@@ -2691,7 +2723,7 @@ pub const Value = extern union {
26912723 // The value is runtime-known and shouldn't affect the hash.
26922724 if (val.tag() == .runtime_value) return;
26932725
2694 switch (ty.zigTypeTag()) {
2726 switch (ty.zigTypeTag(mod)) {
26952727 .Opaque => unreachable, // Cannot hash opaque types
26962728 .Void,
26972729 .NoReturn,
......@@ -2700,8 +2732,7 @@ pub const Value = extern union {
27002732 .Struct, // It sure would be nice to do something clever with structs.
27012733 => |zig_type_tag| std.hash.autoHash(hasher, zig_type_tag),
27022734 .Type => {
2703 var buf: ToTypeBuffer = undefined;
2704 val.toType(&buf).hashWithHasher(hasher, mod);
2735 val.toType().hashWithHasher(hasher, mod);
27052736 },
27062737 .Float, .ComptimeFloat => std.hash.autoHash(hasher, @bitCast(u128, val.toFloat(f128))),
27072738 .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) {
......@@ -2711,7 +2742,7 @@ pub const Value = extern union {
27112742 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
27122743 slice.ptr.hashUncoerced(ptr_ty, hasher, mod);
27132744 },
2714 else => val.hashPtr(hasher, mod.getTarget()),
2745 else => val.hashPtr(hasher, mod),
27152746 },
27162747 .Array, .Vector => {
27172748 const len = ty.arrayLen();
......@@ -2821,16 +2852,16 @@ pub const Value = extern union {
28212852 };
28222853 }
28232854
2824 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash, target: Target) void {
2855 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash, mod: *const Module) void {
28252856 var buffer: BigIntSpace = undefined;
2826 const big = int_val.toBigInt(&buffer, target);
2857 const big = int_val.toBigInt(&buffer, mod);
28272858 std.hash.autoHash(hasher, big.positive);
28282859 for (big.limbs) |limb| {
28292860 std.hash.autoHash(hasher, limb);
28302861 }
28312862 }
28322863
2833 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash, target: Target) void {
2864 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash, mod: *const Module) void {
28342865 switch (ptr_val.tag()) {
28352866 .decl_ref,
28362867 .decl_ref_mut,
......@@ -2847,25 +2878,25 @@ pub const Value = extern union {
28472878
28482879 .elem_ptr => {
28492880 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2850 hashPtr(elem_ptr.array_ptr, hasher, target);
2881 hashPtr(elem_ptr.array_ptr, hasher, mod);
28512882 std.hash.autoHash(hasher, Value.Tag.elem_ptr);
28522883 std.hash.autoHash(hasher, elem_ptr.index);
28532884 },
28542885 .field_ptr => {
28552886 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
28562887 std.hash.autoHash(hasher, Value.Tag.field_ptr);
2857 hashPtr(field_ptr.container_ptr, hasher, target);
2888 hashPtr(field_ptr.container_ptr, hasher, mod);
28582889 std.hash.autoHash(hasher, field_ptr.field_index);
28592890 },
28602891 .eu_payload_ptr => {
28612892 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
28622893 std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr);
2863 hashPtr(err_union_ptr.container_ptr, hasher, target);
2894 hashPtr(err_union_ptr.container_ptr, hasher, mod);
28642895 },
28652896 .opt_payload_ptr => {
28662897 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
28672898 std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr);
2868 hashPtr(opt_ptr.container_ptr, hasher, target);
2899 hashPtr(opt_ptr.container_ptr, hasher, mod);
28692900 },
28702901
28712902 .zero,
......@@ -2880,7 +2911,7 @@ pub const Value = extern union {
28802911 .the_only_possible_value,
28812912 .lazy_align,
28822913 .lazy_size,
2883 => return hashInt(ptr_val, hasher, target),
2914 => return hashInt(ptr_val, hasher, mod),
28842915
28852916 else => unreachable,
28862917 }
......@@ -2897,11 +2928,11 @@ pub const Value = extern union {
28972928
28982929 pub fn sliceLen(val: Value, mod: *Module) u64 {
28992930 return switch (val.tag()) {
2900 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(mod.getTarget()),
2931 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(mod),
29012932 .decl_ref => {
29022933 const decl_index = val.castTag(.decl_ref).?.data;
29032934 const decl = mod.declPtr(decl_index);
2904 if (decl.ty.zigTypeTag() == .Array) {
2935 if (decl.ty.zigTypeTag(mod) == .Array) {
29052936 return decl.ty.arrayLen();
29062937 } else {
29072938 return 1;
......@@ -2910,7 +2941,7 @@ pub const Value = extern union {
29102941 .decl_ref_mut => {
29112942 const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index;
29122943 const decl = mod.declPtr(decl_index);
2913 if (decl.ty.zigTypeTag() == .Array) {
2944 if (decl.ty.zigTypeTag(mod) == .Array) {
29142945 return decl.ty.arrayLen();
29152946 } else {
29162947 return 1;
......@@ -2918,7 +2949,7 @@ pub const Value = extern union {
29182949 },
29192950 .comptime_field_ptr => {
29202951 const payload = val.castTag(.comptime_field_ptr).?.data;
2921 if (payload.field_ty.zigTypeTag() == .Array) {
2952 if (payload.field_ty.zigTypeTag(mod) == .Array) {
29222953 return payload.field_ty.arrayLen();
29232954 } else {
29242955 return 1;
......@@ -3003,7 +3034,7 @@ pub const Value = extern union {
30033034 if (data.container_ptr.pointerDecl()) |decl_index| {
30043035 const container_decl = mod.declPtr(decl_index);
30053036 const field_type = data.container_ty.structFieldType(data.field_index);
3006 const field_val = container_decl.val.fieldValue(field_type, data.field_index);
3037 const field_val = container_decl.val.fieldValue(field_type, mod, data.field_index);
30073038 return field_val.elemValueAdvanced(mod, index, arena, buffer);
30083039 } else unreachable;
30093040 },
......@@ -3032,10 +3063,7 @@ pub const Value = extern union {
30323063 }
30333064
30343065 /// Returns true if a Value is backed by a variable
3035 pub fn isVariable(
3036 val: Value,
3037 mod: *Module,
3038 ) bool {
3066 pub fn isVariable(val: Value, mod: *Module) bool {
30393067 return switch (val.tag()) {
30403068 .slice => val.castTag(.slice).?.data.ptr.isVariable(mod),
30413069 .comptime_field_ptr => val.castTag(.comptime_field_ptr).?.data.field_val.isVariable(mod),
......@@ -3119,7 +3147,7 @@ pub const Value = extern union {
31193147 };
31203148 }
31213149
3122 pub fn fieldValue(val: Value, ty: Type, index: usize) Value {
3150 pub fn fieldValue(val: Value, ty: Type, mod: *const Module, index: usize) Value {
31233151 switch (val.tag()) {
31243152 .aggregate => {
31253153 const field_values = val.castTag(.aggregate).?.data;
......@@ -3131,14 +3159,14 @@ pub const Value = extern union {
31313159 return payload.val;
31323160 },
31333161
3134 .the_only_possible_value => return ty.onePossibleValue().?,
3162 .the_only_possible_value => return ty.onePossibleValue(mod).?,
31353163
31363164 .empty_struct_value => {
31373165 if (ty.isSimpleTupleOrAnonStruct()) {
31383166 const tuple = ty.tupleFields();
31393167 return tuple.values[index];
31403168 }
3141 if (ty.structFieldValueComptime(index)) |some| {
3169 if (ty.structFieldValueComptime(mod, index)) |some| {
31423170 return some;
31433171 }
31443172 unreachable;
......@@ -3165,7 +3193,7 @@ pub const Value = extern union {
31653193 index: usize,
31663194 mod: *Module,
31673195 ) Allocator.Error!Value {
3168 const elem_ty = ty.elemType2();
3196 const elem_ty = ty.elemType2(mod);
31693197 const ptr_val = switch (val.tag()) {
31703198 .slice => val.castTag(.slice).?.data.ptr,
31713199 else => val,
......@@ -3207,7 +3235,7 @@ pub const Value = extern union {
32073235 switch (self.tag()) {
32083236 .slice => {
32093237 const payload = self.castTag(.slice).?;
3210 const len = payload.data.len.toUnsignedInt(mod.getTarget());
3238 const len = payload.data.len.toUnsignedInt(mod);
32113239
32123240 var elem_value_buf: ElemValueBuffer = undefined;
32133241 var i: usize = 0;
......@@ -3233,7 +3261,7 @@ pub const Value = extern union {
32333261
32343262 /// Asserts the value is not undefined and not unreachable.
32353263 /// Integer value 0 is considered null because of C pointers.
3236 pub fn isNull(self: Value) bool {
3264 pub fn isNull(self: Value, mod: *const Module) bool {
32373265 return switch (self.tag()) {
32383266 .null_value => true,
32393267 .opt_payload => false,
......@@ -3254,7 +3282,7 @@ pub const Value = extern union {
32543282 .int_i64,
32553283 .int_big_positive,
32563284 .int_big_negative,
3257 => self.orderAgainstZero().compare(.eq),
3285 => self.orderAgainstZero(mod).compare(.eq),
32583286
32593287 .undef => unreachable,
32603288 .unreachable_value => unreachable,
......@@ -3300,8 +3328,8 @@ pub const Value = extern union {
33003328 }
33013329
33023330 /// Value of the optional, null if optional has no payload.
3303 pub fn optionalValue(val: Value) ?Value {
3304 if (val.isNull()) return null;
3331 pub fn optionalValue(val: Value, mod: *const Module) ?Value {
3332 if (val.isNull(mod)) return null;
33053333
33063334 // Valid for optional representation to be the direct value
33073335 // and not use opt_payload.
......@@ -3333,20 +3361,20 @@ pub const Value = extern union {
33333361 }
33343362
33353363 pub fn intToFloatAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value {
3336 const target = mod.getTarget();
3337 if (int_ty.zigTypeTag() == .Vector) {
3364 if (int_ty.zigTypeTag(mod) == .Vector) {
33383365 const result_data = try arena.alloc(Value, int_ty.vectorLen());
33393366 for (result_data, 0..) |*scalar, i| {
33403367 var buf: Value.ElemValueBuffer = undefined;
33413368 const elem_val = val.elemValueBuffer(mod, i, &buf);
3342 scalar.* = try intToFloatScalar(elem_val, arena, float_ty.scalarType(), target, opt_sema);
3369 scalar.* = try intToFloatScalar(elem_val, arena, float_ty.scalarType(mod), mod, opt_sema);
33433370 }
33443371 return Value.Tag.aggregate.create(arena, result_data);
33453372 }
3346 return intToFloatScalar(val, arena, float_ty, target, opt_sema);
3373 return intToFloatScalar(val, arena, float_ty, mod, opt_sema);
33473374 }
33483375
3349 pub fn intToFloatScalar(val: Value, arena: Allocator, float_ty: Type, target: Target, opt_sema: ?*Sema) !Value {
3376 pub fn intToFloatScalar(val: Value, arena: Allocator, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value {
3377 const target = mod.getTarget();
33503378 switch (val.tag()) {
33513379 .undef, .zero, .one => return val,
33523380 .the_only_possible_value => return Value.initTag(.zero), // for i0, u0
......@@ -3369,17 +3397,17 @@ pub const Value = extern union {
33693397 .lazy_align => {
33703398 const ty = val.castTag(.lazy_align).?.data;
33713399 if (opt_sema) |sema| {
3372 return intToFloatInner((try ty.abiAlignmentAdvanced(target, .{ .sema = sema })).scalar, arena, float_ty, target);
3400 return intToFloatInner((try ty.abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar, arena, float_ty, target);
33733401 } else {
3374 return intToFloatInner(ty.abiAlignment(target), arena, float_ty, target);
3402 return intToFloatInner(ty.abiAlignment(mod), arena, float_ty, target);
33753403 }
33763404 },
33773405 .lazy_size => {
33783406 const ty = val.castTag(.lazy_size).?.data;
33793407 if (opt_sema) |sema| {
3380 return intToFloatInner((try ty.abiSizeAdvanced(target, .{ .sema = sema })).scalar, arena, float_ty, target);
3408 return intToFloatInner((try ty.abiSizeAdvanced(mod, .{ .sema = sema })).scalar, arena, float_ty, target);
33813409 } else {
3382 return intToFloatInner(ty.abiSize(target), arena, float_ty, target);
3410 return intToFloatInner(ty.abiSize(mod), arena, float_ty, target);
33833411 }
33843412 },
33853413 else => unreachable,
......@@ -3446,19 +3474,18 @@ pub const Value = extern union {
34463474 arena: Allocator,
34473475 mod: *Module,
34483476 ) !Value {
3449 const target = mod.getTarget();
3450 if (ty.zigTypeTag() == .Vector) {
3477 if (ty.zigTypeTag(mod) == .Vector) {
34513478 const result_data = try arena.alloc(Value, ty.vectorLen());
34523479 for (result_data, 0..) |*scalar, i| {
34533480 var lhs_buf: Value.ElemValueBuffer = undefined;
34543481 var rhs_buf: Value.ElemValueBuffer = undefined;
34553482 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
34563483 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3457 scalar.* = try intAddSatScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, target);
3484 scalar.* = try intAddSatScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
34583485 }
34593486 return Value.Tag.aggregate.create(arena, result_data);
34603487 }
3461 return intAddSatScalar(lhs, rhs, ty, arena, target);
3488 return intAddSatScalar(lhs, rhs, ty, arena, mod);
34623489 }
34633490
34643491 /// Supports integers only; asserts neither operand is undefined.
......@@ -3467,17 +3494,17 @@ pub const Value = extern union {
34673494 rhs: Value,
34683495 ty: Type,
34693496 arena: Allocator,
3470 target: Target,
3497 mod: *Module,
34713498 ) !Value {
34723499 assert(!lhs.isUndef());
34733500 assert(!rhs.isUndef());
34743501
3475 const info = ty.intInfo(target);
3502 const info = ty.intInfo(mod);
34763503
34773504 var lhs_space: Value.BigIntSpace = undefined;
34783505 var rhs_space: Value.BigIntSpace = undefined;
3479 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3480 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3506 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3507 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
34813508 const limbs = try arena.alloc(
34823509 std.math.big.Limb,
34833510 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -3495,19 +3522,18 @@ pub const Value = extern union {
34953522 arena: Allocator,
34963523 mod: *Module,
34973524 ) !Value {
3498 const target = mod.getTarget();
3499 if (ty.zigTypeTag() == .Vector) {
3525 if (ty.zigTypeTag(mod) == .Vector) {
35003526 const result_data = try arena.alloc(Value, ty.vectorLen());
35013527 for (result_data, 0..) |*scalar, i| {
35023528 var lhs_buf: Value.ElemValueBuffer = undefined;
35033529 var rhs_buf: Value.ElemValueBuffer = undefined;
35043530 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
35053531 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3506 scalar.* = try intSubSatScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, target);
3532 scalar.* = try intSubSatScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
35073533 }
35083534 return Value.Tag.aggregate.create(arena, result_data);
35093535 }
3510 return intSubSatScalar(lhs, rhs, ty, arena, target);
3536 return intSubSatScalar(lhs, rhs, ty, arena, mod);
35113537 }
35123538
35133539 /// Supports integers only; asserts neither operand is undefined.
......@@ -3516,17 +3542,17 @@ pub const Value = extern union {
35163542 rhs: Value,
35173543 ty: Type,
35183544 arena: Allocator,
3519 target: Target,
3545 mod: *Module,
35203546 ) !Value {
35213547 assert(!lhs.isUndef());
35223548 assert(!rhs.isUndef());
35233549
3524 const info = ty.intInfo(target);
3550 const info = ty.intInfo(mod);
35253551
35263552 var lhs_space: Value.BigIntSpace = undefined;
35273553 var rhs_space: Value.BigIntSpace = undefined;
3528 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3529 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3554 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3555 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
35303556 const limbs = try arena.alloc(
35313557 std.math.big.Limb,
35323558 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -3543,8 +3569,7 @@ pub const Value = extern union {
35433569 arena: Allocator,
35443570 mod: *Module,
35453571 ) !OverflowArithmeticResult {
3546 const target = mod.getTarget();
3547 if (ty.zigTypeTag() == .Vector) {
3572 if (ty.zigTypeTag(mod) == .Vector) {
35483573 const overflowed_data = try arena.alloc(Value, ty.vectorLen());
35493574 const result_data = try arena.alloc(Value, ty.vectorLen());
35503575 for (result_data, 0..) |*scalar, i| {
......@@ -3552,7 +3577,7 @@ pub const Value = extern union {
35523577 var rhs_buf: Value.ElemValueBuffer = undefined;
35533578 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
35543579 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3555 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, target);
3580 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
35563581 overflowed_data[i] = of_math_result.overflow_bit;
35573582 scalar.* = of_math_result.wrapped_result;
35583583 }
......@@ -3561,7 +3586,7 @@ pub const Value = extern union {
35613586 .wrapped_result = try Value.Tag.aggregate.create(arena, result_data),
35623587 };
35633588 }
3564 return intMulWithOverflowScalar(lhs, rhs, ty, arena, target);
3589 return intMulWithOverflowScalar(lhs, rhs, ty, arena, mod);
35653590 }
35663591
35673592 pub fn intMulWithOverflowScalar(
......@@ -3569,14 +3594,14 @@ pub const Value = extern union {
35693594 rhs: Value,
35703595 ty: Type,
35713596 arena: Allocator,
3572 target: Target,
3597 mod: *Module,
35733598 ) !OverflowArithmeticResult {
3574 const info = ty.intInfo(target);
3599 const info = ty.intInfo(mod);
35753600
35763601 var lhs_space: Value.BigIntSpace = undefined;
35773602 var rhs_space: Value.BigIntSpace = undefined;
3578 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3579 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3603 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3604 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
35803605 const limbs = try arena.alloc(
35813606 std.math.big.Limb,
35823607 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
......@@ -3607,14 +3632,14 @@ pub const Value = extern union {
36073632 arena: Allocator,
36083633 mod: *Module,
36093634 ) !Value {
3610 if (ty.zigTypeTag() == .Vector) {
3635 if (ty.zigTypeTag(mod) == .Vector) {
36113636 const result_data = try arena.alloc(Value, ty.vectorLen());
36123637 for (result_data, 0..) |*scalar, i| {
36133638 var lhs_buf: Value.ElemValueBuffer = undefined;
36143639 var rhs_buf: Value.ElemValueBuffer = undefined;
36153640 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
36163641 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3617 scalar.* = try numberMulWrapScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, mod);
3642 scalar.* = try numberMulWrapScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
36183643 }
36193644 return Value.Tag.aggregate.create(arena, result_data);
36203645 }
......@@ -3631,7 +3656,7 @@ pub const Value = extern union {
36313656 ) !Value {
36323657 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
36333658
3634 if (ty.zigTypeTag() == .ComptimeInt) {
3659 if (ty.zigTypeTag(mod) == .ComptimeInt) {
36353660 return intMul(lhs, rhs, ty, arena, mod);
36363661 }
36373662
......@@ -3651,19 +3676,18 @@ pub const Value = extern union {
36513676 arena: Allocator,
36523677 mod: *Module,
36533678 ) !Value {
3654 const target = mod.getTarget();
3655 if (ty.zigTypeTag() == .Vector) {
3679 if (ty.zigTypeTag(mod) == .Vector) {
36563680 const result_data = try arena.alloc(Value, ty.vectorLen());
36573681 for (result_data, 0..) |*scalar, i| {
36583682 var lhs_buf: Value.ElemValueBuffer = undefined;
36593683 var rhs_buf: Value.ElemValueBuffer = undefined;
36603684 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
36613685 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3662 scalar.* = try intMulSatScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, target);
3686 scalar.* = try intMulSatScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
36633687 }
36643688 return Value.Tag.aggregate.create(arena, result_data);
36653689 }
3666 return intMulSatScalar(lhs, rhs, ty, arena, target);
3690 return intMulSatScalar(lhs, rhs, ty, arena, mod);
36673691 }
36683692
36693693 /// Supports (vectors of) integers only; asserts neither operand is undefined.
......@@ -3672,17 +3696,17 @@ pub const Value = extern union {
36723696 rhs: Value,
36733697 ty: Type,
36743698 arena: Allocator,
3675 target: Target,
3699 mod: *Module,
36763700 ) !Value {
36773701 assert(!lhs.isUndef());
36783702 assert(!rhs.isUndef());
36793703
3680 const info = ty.intInfo(target);
3704 const info = ty.intInfo(mod);
36813705
36823706 var lhs_space: Value.BigIntSpace = undefined;
36833707 var rhs_space: Value.BigIntSpace = undefined;
3684 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3685 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3708 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3709 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
36863710 const limbs = try arena.alloc(
36873711 std.math.big.Limb,
36883712 std.math.max(
......@@ -3702,24 +3726,24 @@ pub const Value = extern union {
37023726 }
37033727
37043728 /// Supports both floats and ints; handles undefined.
3705 pub fn numberMax(lhs: Value, rhs: Value, target: Target) Value {
3729 pub fn numberMax(lhs: Value, rhs: Value, mod: *Module) Value {
37063730 if (lhs.isUndef() or rhs.isUndef()) return undef;
37073731 if (lhs.isNan()) return rhs;
37083732 if (rhs.isNan()) return lhs;
37093733
3710 return switch (order(lhs, rhs, target)) {
3734 return switch (order(lhs, rhs, mod)) {
37113735 .lt => rhs,
37123736 .gt, .eq => lhs,
37133737 };
37143738 }
37153739
37163740 /// Supports both floats and ints; handles undefined.
3717 pub fn numberMin(lhs: Value, rhs: Value, target: Target) Value {
3741 pub fn numberMin(lhs: Value, rhs: Value, mod: *Module) Value {
37183742 if (lhs.isUndef() or rhs.isUndef()) return undef;
37193743 if (lhs.isNan()) return rhs;
37203744 if (rhs.isNan()) return lhs;
37213745
3722 return switch (order(lhs, rhs, target)) {
3746 return switch (order(lhs, rhs, mod)) {
37233747 .lt => lhs,
37243748 .gt, .eq => rhs,
37253749 };
......@@ -3727,24 +3751,23 @@ pub const Value = extern union {
37273751
37283752 /// operands must be (vectors of) integers; handles undefined scalars.
37293753 pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3730 const target = mod.getTarget();
3731 if (ty.zigTypeTag() == .Vector) {
3754 if (ty.zigTypeTag(mod) == .Vector) {
37323755 const result_data = try arena.alloc(Value, ty.vectorLen());
37333756 for (result_data, 0..) |*scalar, i| {
37343757 var buf: Value.ElemValueBuffer = undefined;
37353758 const elem_val = val.elemValueBuffer(mod, i, &buf);
3736 scalar.* = try bitwiseNotScalar(elem_val, ty.scalarType(), arena, target);
3759 scalar.* = try bitwiseNotScalar(elem_val, ty.scalarType(mod), arena, mod);
37373760 }
37383761 return Value.Tag.aggregate.create(arena, result_data);
37393762 }
3740 return bitwiseNotScalar(val, ty, arena, target);
3763 return bitwiseNotScalar(val, ty, arena, mod);
37413764 }
37423765
37433766 /// operands must be integers; handles undefined.
3744 pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, target: Target) !Value {
3767 pub fn bitwiseNotScalar(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
37453768 if (val.isUndef()) return Value.initTag(.undef);
37463769
3747 const info = ty.intInfo(target);
3770 const info = ty.intInfo(mod);
37483771
37493772 if (info.bits == 0) {
37503773 return val;
......@@ -3753,7 +3776,7 @@ pub const Value = extern union {
37533776 // TODO is this a performance issue? maybe we should try the operation without
37543777 // resorting to BigInt first.
37553778 var val_space: Value.BigIntSpace = undefined;
3756 const val_bigint = val.toBigInt(&val_space, target);
3779 const val_bigint = val.toBigInt(&val_space, mod);
37573780 const limbs = try arena.alloc(
37583781 std.math.big.Limb,
37593782 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -3766,31 +3789,30 @@ pub const Value = extern union {
37663789
37673790 /// operands must be (vectors of) integers; handles undefined scalars.
37683791 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3769 const target = mod.getTarget();
3770 if (ty.zigTypeTag() == .Vector) {
3792 if (ty.zigTypeTag(mod) == .Vector) {
37713793 const result_data = try allocator.alloc(Value, ty.vectorLen());
37723794 for (result_data, 0..) |*scalar, i| {
37733795 var lhs_buf: Value.ElemValueBuffer = undefined;
37743796 var rhs_buf: Value.ElemValueBuffer = undefined;
37753797 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
37763798 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3777 scalar.* = try bitwiseAndScalar(lhs_elem, rhs_elem, allocator, target);
3799 scalar.* = try bitwiseAndScalar(lhs_elem, rhs_elem, allocator, mod);
37783800 }
37793801 return Value.Tag.aggregate.create(allocator, result_data);
37803802 }
3781 return bitwiseAndScalar(lhs, rhs, allocator, target);
3803 return bitwiseAndScalar(lhs, rhs, allocator, mod);
37823804 }
37833805
37843806 /// operands must be integers; handles undefined.
3785 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
3807 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator, mod: *Module) !Value {
37863808 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
37873809
37883810 // TODO is this a performance issue? maybe we should try the operation without
37893811 // resorting to BigInt first.
37903812 var lhs_space: Value.BigIntSpace = undefined;
37913813 var rhs_space: Value.BigIntSpace = undefined;
3792 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3793 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3814 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3815 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
37943816 const limbs = try arena.alloc(
37953817 std.math.big.Limb,
37963818 // + 1 for negatives
......@@ -3803,14 +3825,14 @@ pub const Value = extern union {
38033825
38043826 /// operands must be (vectors of) integers; handles undefined scalars.
38053827 pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value {
3806 if (ty.zigTypeTag() == .Vector) {
3828 if (ty.zigTypeTag(mod) == .Vector) {
38073829 const result_data = try arena.alloc(Value, ty.vectorLen());
38083830 for (result_data, 0..) |*scalar, i| {
38093831 var lhs_buf: Value.ElemValueBuffer = undefined;
38103832 var rhs_buf: Value.ElemValueBuffer = undefined;
38113833 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
38123834 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3813 scalar.* = try bitwiseNandScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, mod);
3835 scalar.* = try bitwiseNandScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
38143836 }
38153837 return Value.Tag.aggregate.create(arena, result_data);
38163838 }
......@@ -3823,41 +3845,40 @@ pub const Value = extern union {
38233845
38243846 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);
38253847
3826 const all_ones = if (ty.isSignedInt())
3848 const all_ones = if (ty.isSignedInt(mod))
38273849 try Value.Tag.int_i64.create(arena, -1)
38283850 else
3829 try ty.maxInt(arena, mod.getTarget());
3851 try ty.maxInt(arena, mod);
38303852
38313853 return bitwiseXor(anded, all_ones, ty, arena, mod);
38323854 }
38333855
38343856 /// operands must be (vectors of) integers; handles undefined scalars.
38353857 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3836 const target = mod.getTarget();
3837 if (ty.zigTypeTag() == .Vector) {
3858 if (ty.zigTypeTag(mod) == .Vector) {
38383859 const result_data = try allocator.alloc(Value, ty.vectorLen());
38393860 for (result_data, 0..) |*scalar, i| {
38403861 var lhs_buf: Value.ElemValueBuffer = undefined;
38413862 var rhs_buf: Value.ElemValueBuffer = undefined;
38423863 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
38433864 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3844 scalar.* = try bitwiseOrScalar(lhs_elem, rhs_elem, allocator, target);
3865 scalar.* = try bitwiseOrScalar(lhs_elem, rhs_elem, allocator, mod);
38453866 }
38463867 return Value.Tag.aggregate.create(allocator, result_data);
38473868 }
3848 return bitwiseOrScalar(lhs, rhs, allocator, target);
3869 return bitwiseOrScalar(lhs, rhs, allocator, mod);
38493870 }
38503871
38513872 /// operands must be integers; handles undefined.
3852 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
3873 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator, mod: *Module) !Value {
38533874 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
38543875
38553876 // TODO is this a performance issue? maybe we should try the operation without
38563877 // resorting to BigInt first.
38573878 var lhs_space: Value.BigIntSpace = undefined;
38583879 var rhs_space: Value.BigIntSpace = undefined;
3859 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3860 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3880 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3881 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
38613882 const limbs = try arena.alloc(
38623883 std.math.big.Limb,
38633884 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
......@@ -3869,31 +3890,30 @@ pub const Value = extern union {
38693890
38703891 /// operands must be (vectors of) integers; handles undefined scalars.
38713892 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3872 const target = mod.getTarget();
3873 if (ty.zigTypeTag() == .Vector) {
3893 if (ty.zigTypeTag(mod) == .Vector) {
38743894 const result_data = try allocator.alloc(Value, ty.vectorLen());
38753895 for (result_data, 0..) |*scalar, i| {
38763896 var lhs_buf: Value.ElemValueBuffer = undefined;
38773897 var rhs_buf: Value.ElemValueBuffer = undefined;
38783898 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
38793899 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3880 scalar.* = try bitwiseXorScalar(lhs_elem, rhs_elem, allocator, target);
3900 scalar.* = try bitwiseXorScalar(lhs_elem, rhs_elem, allocator, mod);
38813901 }
38823902 return Value.Tag.aggregate.create(allocator, result_data);
38833903 }
3884 return bitwiseXorScalar(lhs, rhs, allocator, target);
3904 return bitwiseXorScalar(lhs, rhs, allocator, mod);
38853905 }
38863906
38873907 /// operands must be integers; handles undefined.
3888 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
3908 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator, mod: *Module) !Value {
38893909 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
38903910
38913911 // TODO is this a performance issue? maybe we should try the operation without
38923912 // resorting to BigInt first.
38933913 var lhs_space: Value.BigIntSpace = undefined;
38943914 var rhs_space: Value.BigIntSpace = undefined;
3895 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3896 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3915 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3916 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
38973917 const limbs = try arena.alloc(
38983918 std.math.big.Limb,
38993919 // + 1 for negatives
......@@ -3905,28 +3925,27 @@ pub const Value = extern union {
39053925 }
39063926
39073927 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3908 const target = mod.getTarget();
3909 if (ty.zigTypeTag() == .Vector) {
3928 if (ty.zigTypeTag(mod) == .Vector) {
39103929 const result_data = try allocator.alloc(Value, ty.vectorLen());
39113930 for (result_data, 0..) |*scalar, i| {
39123931 var lhs_buf: Value.ElemValueBuffer = undefined;
39133932 var rhs_buf: Value.ElemValueBuffer = undefined;
39143933 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
39153934 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3916 scalar.* = try intDivScalar(lhs_elem, rhs_elem, allocator, target);
3935 scalar.* = try intDivScalar(lhs_elem, rhs_elem, allocator, mod);
39173936 }
39183937 return Value.Tag.aggregate.create(allocator, result_data);
39193938 }
3920 return intDivScalar(lhs, rhs, allocator, target);
3939 return intDivScalar(lhs, rhs, allocator, mod);
39213940 }
39223941
3923 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3942 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {
39243943 // TODO is this a performance issue? maybe we should try the operation without
39253944 // resorting to BigInt first.
39263945 var lhs_space: Value.BigIntSpace = undefined;
39273946 var rhs_space: Value.BigIntSpace = undefined;
3928 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3929 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3947 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3948 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
39303949 const limbs_q = try allocator.alloc(
39313950 std.math.big.Limb,
39323951 lhs_bigint.limbs.len,
......@@ -3946,28 +3965,27 @@ pub const Value = extern union {
39463965 }
39473966
39483967 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3949 const target = mod.getTarget();
3950 if (ty.zigTypeTag() == .Vector) {
3968 if (ty.zigTypeTag(mod) == .Vector) {
39513969 const result_data = try allocator.alloc(Value, ty.vectorLen());
39523970 for (result_data, 0..) |*scalar, i| {
39533971 var lhs_buf: Value.ElemValueBuffer = undefined;
39543972 var rhs_buf: Value.ElemValueBuffer = undefined;
39553973 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
39563974 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3957 scalar.* = try intDivFloorScalar(lhs_elem, rhs_elem, allocator, target);
3975 scalar.* = try intDivFloorScalar(lhs_elem, rhs_elem, allocator, mod);
39583976 }
39593977 return Value.Tag.aggregate.create(allocator, result_data);
39603978 }
3961 return intDivFloorScalar(lhs, rhs, allocator, target);
3979 return intDivFloorScalar(lhs, rhs, allocator, mod);
39623980 }
39633981
3964 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3982 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {
39653983 // TODO is this a performance issue? maybe we should try the operation without
39663984 // resorting to BigInt first.
39673985 var lhs_space: Value.BigIntSpace = undefined;
39683986 var rhs_space: Value.BigIntSpace = undefined;
3969 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3970 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3987 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
3988 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
39713989 const limbs_q = try allocator.alloc(
39723990 std.math.big.Limb,
39733991 lhs_bigint.limbs.len,
......@@ -3987,28 +4005,27 @@ pub const Value = extern union {
39874005 }
39884006
39894007 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
3990 const target = mod.getTarget();
3991 if (ty.zigTypeTag() == .Vector) {
4008 if (ty.zigTypeTag(mod) == .Vector) {
39924009 const result_data = try allocator.alloc(Value, ty.vectorLen());
39934010 for (result_data, 0..) |*scalar, i| {
39944011 var lhs_buf: Value.ElemValueBuffer = undefined;
39954012 var rhs_buf: Value.ElemValueBuffer = undefined;
39964013 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
39974014 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3998 scalar.* = try intModScalar(lhs_elem, rhs_elem, allocator, target);
4015 scalar.* = try intModScalar(lhs_elem, rhs_elem, allocator, mod);
39994016 }
40004017 return Value.Tag.aggregate.create(allocator, result_data);
40014018 }
4002 return intModScalar(lhs, rhs, allocator, target);
4019 return intModScalar(lhs, rhs, allocator, mod);
40034020 }
40044021
4005 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
4022 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {
40064023 // TODO is this a performance issue? maybe we should try the operation without
40074024 // resorting to BigInt first.
40084025 var lhs_space: Value.BigIntSpace = undefined;
40094026 var rhs_space: Value.BigIntSpace = undefined;
4010 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
4011 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
4027 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4028 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
40124029 const limbs_q = try allocator.alloc(
40134030 std.math.big.Limb,
40144031 lhs_bigint.limbs.len,
......@@ -4064,14 +4081,14 @@ pub const Value = extern union {
40644081
40654082 pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
40664083 const target = mod.getTarget();
4067 if (float_type.zigTypeTag() == .Vector) {
4084 if (float_type.zigTypeTag(mod) == .Vector) {
40684085 const result_data = try arena.alloc(Value, float_type.vectorLen());
40694086 for (result_data, 0..) |*scalar, i| {
40704087 var lhs_buf: Value.ElemValueBuffer = undefined;
40714088 var rhs_buf: Value.ElemValueBuffer = undefined;
40724089 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
40734090 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4074 scalar.* = try floatRemScalar(lhs_elem, rhs_elem, float_type.scalarType(), arena, target);
4091 scalar.* = try floatRemScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
40754092 }
40764093 return Value.Tag.aggregate.create(arena, result_data);
40774094 }
......@@ -4111,14 +4128,14 @@ pub const Value = extern union {
41114128
41124129 pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
41134130 const target = mod.getTarget();
4114 if (float_type.zigTypeTag() == .Vector) {
4131 if (float_type.zigTypeTag(mod) == .Vector) {
41154132 const result_data = try arena.alloc(Value, float_type.vectorLen());
41164133 for (result_data, 0..) |*scalar, i| {
41174134 var lhs_buf: Value.ElemValueBuffer = undefined;
41184135 var rhs_buf: Value.ElemValueBuffer = undefined;
41194136 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
41204137 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4121 scalar.* = try floatModScalar(lhs_elem, rhs_elem, float_type.scalarType(), arena, target);
4138 scalar.* = try floatModScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
41224139 }
41234140 return Value.Tag.aggregate.create(arena, result_data);
41244141 }
......@@ -4157,28 +4174,27 @@ pub const Value = extern union {
41574174 }
41584175
41594176 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
4160 const target = mod.getTarget();
4161 if (ty.zigTypeTag() == .Vector) {
4177 if (ty.zigTypeTag(mod) == .Vector) {
41624178 const result_data = try allocator.alloc(Value, ty.vectorLen());
41634179 for (result_data, 0..) |*scalar, i| {
41644180 var lhs_buf: Value.ElemValueBuffer = undefined;
41654181 var rhs_buf: Value.ElemValueBuffer = undefined;
41664182 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
41674183 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4168 scalar.* = try intMulScalar(lhs_elem, rhs_elem, allocator, target);
4184 scalar.* = try intMulScalar(lhs_elem, rhs_elem, allocator, mod);
41694185 }
41704186 return Value.Tag.aggregate.create(allocator, result_data);
41714187 }
4172 return intMulScalar(lhs, rhs, allocator, target);
4188 return intMulScalar(lhs, rhs, allocator, mod);
41734189 }
41744190
4175 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
4191 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {
41764192 // TODO is this a performance issue? maybe we should try the operation without
41774193 // resorting to BigInt first.
41784194 var lhs_space: Value.BigIntSpace = undefined;
41794195 var rhs_space: Value.BigIntSpace = undefined;
4180 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
4181 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
4196 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4197 const rhs_bigint = rhs.toBigInt(&rhs_space, mod);
41824198 const limbs = try allocator.alloc(
41834199 std.math.big.Limb,
41844200 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
......@@ -4194,17 +4210,16 @@ pub const Value = extern union {
41944210 }
41954211
41964212 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value {
4197 const target = mod.getTarget();
4198 if (ty.zigTypeTag() == .Vector) {
4213 if (ty.zigTypeTag(mod) == .Vector) {
41994214 const result_data = try allocator.alloc(Value, ty.vectorLen());
42004215 for (result_data, 0..) |*scalar, i| {
42014216 var buf: Value.ElemValueBuffer = undefined;
42024217 const elem_val = val.elemValueBuffer(mod, i, &buf);
4203 scalar.* = try intTruncScalar(elem_val, allocator, signedness, bits, target);
4218 scalar.* = try intTruncScalar(elem_val, allocator, signedness, bits, mod);
42044219 }
42054220 return Value.Tag.aggregate.create(allocator, result_data);
42064221 }
4207 return intTruncScalar(val, allocator, signedness, bits, target);
4222 return intTruncScalar(val, allocator, signedness, bits, mod);
42084223 }
42094224
42104225 /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.
......@@ -4216,26 +4231,25 @@ pub const Value = extern union {
42164231 bits: Value,
42174232 mod: *Module,
42184233 ) !Value {
4219 const target = mod.getTarget();
4220 if (ty.zigTypeTag() == .Vector) {
4234 if (ty.zigTypeTag(mod) == .Vector) {
42214235 const result_data = try allocator.alloc(Value, ty.vectorLen());
42224236 for (result_data, 0..) |*scalar, i| {
42234237 var buf: Value.ElemValueBuffer = undefined;
42244238 const elem_val = val.elemValueBuffer(mod, i, &buf);
42254239 var bits_buf: Value.ElemValueBuffer = undefined;
42264240 const bits_elem = bits.elemValueBuffer(mod, i, &bits_buf);
4227 scalar.* = try intTruncScalar(elem_val, allocator, signedness, @intCast(u16, bits_elem.toUnsignedInt(target)), target);
4241 scalar.* = try intTruncScalar(elem_val, allocator, signedness, @intCast(u16, bits_elem.toUnsignedInt(mod)), mod);
42284242 }
42294243 return Value.Tag.aggregate.create(allocator, result_data);
42304244 }
4231 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt(target)), target);
4245 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt(mod)), mod);
42324246 }
42334247
4234 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, target: Target) !Value {
4248 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value {
42354249 if (bits == 0) return Value.zero;
42364250
42374251 var val_space: Value.BigIntSpace = undefined;
4238 const val_bigint = val.toBigInt(&val_space, target);
4252 const val_bigint = val.toBigInt(&val_space, mod);
42394253
42404254 const limbs = try allocator.alloc(
42414255 std.math.big.Limb,
......@@ -4248,27 +4262,26 @@ pub const Value = extern union {
42484262 }
42494263
42504264 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
4251 const target = mod.getTarget();
4252 if (ty.zigTypeTag() == .Vector) {
4265 if (ty.zigTypeTag(mod) == .Vector) {
42534266 const result_data = try allocator.alloc(Value, ty.vectorLen());
42544267 for (result_data, 0..) |*scalar, i| {
42554268 var lhs_buf: Value.ElemValueBuffer = undefined;
42564269 var rhs_buf: Value.ElemValueBuffer = undefined;
42574270 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
42584271 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4259 scalar.* = try shlScalar(lhs_elem, rhs_elem, allocator, target);
4272 scalar.* = try shlScalar(lhs_elem, rhs_elem, allocator, mod);
42604273 }
42614274 return Value.Tag.aggregate.create(allocator, result_data);
42624275 }
4263 return shlScalar(lhs, rhs, allocator, target);
4276 return shlScalar(lhs, rhs, allocator, mod);
42644277 }
42654278
4266 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
4279 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {
42674280 // TODO is this a performance issue? maybe we should try the operation without
42684281 // resorting to BigInt first.
42694282 var lhs_space: Value.BigIntSpace = undefined;
4270 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
4271 const shift = @intCast(usize, rhs.toUnsignedInt(target));
4283 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4284 const shift = @intCast(usize, rhs.toUnsignedInt(mod));
42724285 const limbs = try allocator.alloc(
42734286 std.math.big.Limb,
42744287 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
......@@ -4289,8 +4302,7 @@ pub const Value = extern union {
42894302 allocator: Allocator,
42904303 mod: *Module,
42914304 ) !OverflowArithmeticResult {
4292 const target = mod.getTarget();
4293 if (ty.zigTypeTag() == .Vector) {
4305 if (ty.zigTypeTag(mod) == .Vector) {
42944306 const overflowed_data = try allocator.alloc(Value, ty.vectorLen());
42954307 const result_data = try allocator.alloc(Value, ty.vectorLen());
42964308 for (result_data, 0..) |*scalar, i| {
......@@ -4298,7 +4310,7 @@ pub const Value = extern union {
42984310 var rhs_buf: Value.ElemValueBuffer = undefined;
42994311 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
43004312 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4301 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(), allocator, target);
4313 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(mod), allocator, mod);
43024314 overflowed_data[i] = of_math_result.overflow_bit;
43034315 scalar.* = of_math_result.wrapped_result;
43044316 }
......@@ -4307,7 +4319,7 @@ pub const Value = extern union {
43074319 .wrapped_result = try Value.Tag.aggregate.create(allocator, result_data),
43084320 };
43094321 }
4310 return shlWithOverflowScalar(lhs, rhs, ty, allocator, target);
4322 return shlWithOverflowScalar(lhs, rhs, ty, allocator, mod);
43114323 }
43124324
43134325 pub fn shlWithOverflowScalar(
......@@ -4315,12 +4327,12 @@ pub const Value = extern union {
43154327 rhs: Value,
43164328 ty: Type,
43174329 allocator: Allocator,
4318 target: Target,
4330 mod: *Module,
43194331 ) !OverflowArithmeticResult {
4320 const info = ty.intInfo(target);
4332 const info = ty.intInfo(mod);
43214333 var lhs_space: Value.BigIntSpace = undefined;
4322 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
4323 const shift = @intCast(usize, rhs.toUnsignedInt(target));
4334 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4335 const shift = @intCast(usize, rhs.toUnsignedInt(mod));
43244336 const limbs = try allocator.alloc(
43254337 std.math.big.Limb,
43264338 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
......@@ -4348,19 +4360,18 @@ pub const Value = extern union {
43484360 arena: Allocator,
43494361 mod: *Module,
43504362 ) !Value {
4351 const target = mod.getTarget();
4352 if (ty.zigTypeTag() == .Vector) {
4363 if (ty.zigTypeTag(mod) == .Vector) {
43534364 const result_data = try arena.alloc(Value, ty.vectorLen());
43544365 for (result_data, 0..) |*scalar, i| {
43554366 var lhs_buf: Value.ElemValueBuffer = undefined;
43564367 var rhs_buf: Value.ElemValueBuffer = undefined;
43574368 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
43584369 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4359 scalar.* = try shlSatScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, target);
4370 scalar.* = try shlSatScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
43604371 }
43614372 return Value.Tag.aggregate.create(arena, result_data);
43624373 }
4363 return shlSatScalar(lhs, rhs, ty, arena, target);
4374 return shlSatScalar(lhs, rhs, ty, arena, mod);
43644375 }
43654376
43664377 pub fn shlSatScalar(
......@@ -4368,15 +4379,15 @@ pub const Value = extern union {
43684379 rhs: Value,
43694380 ty: Type,
43704381 arena: Allocator,
4371 target: Target,
4382 mod: *Module,
43724383 ) !Value {
43734384 // TODO is this a performance issue? maybe we should try the operation without
43744385 // resorting to BigInt first.
4375 const info = ty.intInfo(target);
4386 const info = ty.intInfo(mod);
43764387
43774388 var lhs_space: Value.BigIntSpace = undefined;
4378 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
4379 const shift = @intCast(usize, rhs.toUnsignedInt(target));
4389 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4390 const shift = @intCast(usize, rhs.toUnsignedInt(mod));
43804391 const limbs = try arena.alloc(
43814392 std.math.big.Limb,
43824393 std.math.big.int.calcTwosCompLimbCount(info.bits) + 1,
......@@ -4397,14 +4408,14 @@ pub const Value = extern union {
43974408 arena: Allocator,
43984409 mod: *Module,
43994410 ) !Value {
4400 if (ty.zigTypeTag() == .Vector) {
4411 if (ty.zigTypeTag(mod) == .Vector) {
44014412 const result_data = try arena.alloc(Value, ty.vectorLen());
44024413 for (result_data, 0..) |*scalar, i| {
44034414 var lhs_buf: Value.ElemValueBuffer = undefined;
44044415 var rhs_buf: Value.ElemValueBuffer = undefined;
44054416 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
44064417 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4407 scalar.* = try shlTruncScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, mod);
4418 scalar.* = try shlTruncScalar(lhs_elem, rhs_elem, ty.scalarType(mod), arena, mod);
44084419 }
44094420 return Value.Tag.aggregate.create(arena, result_data);
44104421 }
......@@ -4419,33 +4430,32 @@ pub const Value = extern union {
44194430 mod: *Module,
44204431 ) !Value {
44214432 const shifted = try lhs.shl(rhs, ty, arena, mod);
4422 const int_info = ty.intInfo(mod.getTarget());
4433 const int_info = ty.intInfo(mod);
44234434 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, mod);
44244435 return truncated;
44254436 }
44264437
44274438 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value {
4428 const target = mod.getTarget();
4429 if (ty.zigTypeTag() == .Vector) {
4439 if (ty.zigTypeTag(mod) == .Vector) {
44304440 const result_data = try allocator.alloc(Value, ty.vectorLen());
44314441 for (result_data, 0..) |*scalar, i| {
44324442 var lhs_buf: Value.ElemValueBuffer = undefined;
44334443 var rhs_buf: Value.ElemValueBuffer = undefined;
44344444 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
44354445 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4436 scalar.* = try shrScalar(lhs_elem, rhs_elem, allocator, target);
4446 scalar.* = try shrScalar(lhs_elem, rhs_elem, allocator, mod);
44374447 }
44384448 return Value.Tag.aggregate.create(allocator, result_data);
44394449 }
4440 return shrScalar(lhs, rhs, allocator, target);
4450 return shrScalar(lhs, rhs, allocator, mod);
44414451 }
44424452
4443 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
4453 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator, mod: *Module) !Value {
44444454 // TODO is this a performance issue? maybe we should try the operation without
44454455 // resorting to BigInt first.
44464456 var lhs_space: Value.BigIntSpace = undefined;
4447 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
4448 const shift = @intCast(usize, rhs.toUnsignedInt(target));
4457 const lhs_bigint = lhs.toBigInt(&lhs_space, mod);
4458 const shift = @intCast(usize, rhs.toUnsignedInt(mod));
44494459
44504460 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
44514461 if (result_limbs == 0) {
......@@ -4478,12 +4488,12 @@ pub const Value = extern union {
44784488 mod: *Module,
44794489 ) !Value {
44804490 const target = mod.getTarget();
4481 if (float_type.zigTypeTag() == .Vector) {
4491 if (float_type.zigTypeTag(mod) == .Vector) {
44824492 const result_data = try arena.alloc(Value, float_type.vectorLen());
44834493 for (result_data, 0..) |*scalar, i| {
44844494 var buf: Value.ElemValueBuffer = undefined;
44854495 const elem_val = val.elemValueBuffer(mod, i, &buf);
4486 scalar.* = try floatNegScalar(elem_val, float_type.scalarType(), arena, target);
4496 scalar.* = try floatNegScalar(elem_val, float_type.scalarType(mod), arena, target);
44874497 }
44884498 return Value.Tag.aggregate.create(arena, result_data);
44894499 }
......@@ -4514,14 +4524,14 @@ pub const Value = extern union {
45144524 mod: *Module,
45154525 ) !Value {
45164526 const target = mod.getTarget();
4517 if (float_type.zigTypeTag() == .Vector) {
4527 if (float_type.zigTypeTag(mod) == .Vector) {
45184528 const result_data = try arena.alloc(Value, float_type.vectorLen());
45194529 for (result_data, 0..) |*scalar, i| {
45204530 var lhs_buf: Value.ElemValueBuffer = undefined;
45214531 var rhs_buf: Value.ElemValueBuffer = undefined;
45224532 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
45234533 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4524 scalar.* = try floatDivScalar(lhs_elem, rhs_elem, float_type.scalarType(), arena, target);
4534 scalar.* = try floatDivScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
45254535 }
45264536 return Value.Tag.aggregate.create(arena, result_data);
45274537 }
......@@ -4573,14 +4583,14 @@ pub const Value = extern union {
45734583 mod: *Module,
45744584 ) !Value {
45754585 const target = mod.getTarget();
4576 if (float_type.zigTypeTag() == .Vector) {
4586 if (float_type.zigTypeTag(mod) == .Vector) {
45774587 const result_data = try arena.alloc(Value, float_type.vectorLen());
45784588 for (result_data, 0..) |*scalar, i| {
45794589 var lhs_buf: Value.ElemValueBuffer = undefined;
45804590 var rhs_buf: Value.ElemValueBuffer = undefined;
45814591 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
45824592 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4583 scalar.* = try floatDivFloorScalar(lhs_elem, rhs_elem, float_type.scalarType(), arena, target);
4593 scalar.* = try floatDivFloorScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
45844594 }
45854595 return Value.Tag.aggregate.create(arena, result_data);
45864596 }
......@@ -4632,14 +4642,14 @@ pub const Value = extern union {
46324642 mod: *Module,
46334643 ) !Value {
46344644 const target = mod.getTarget();
4635 if (float_type.zigTypeTag() == .Vector) {
4645 if (float_type.zigTypeTag(mod) == .Vector) {
46364646 const result_data = try arena.alloc(Value, float_type.vectorLen());
46374647 for (result_data, 0..) |*scalar, i| {
46384648 var lhs_buf: Value.ElemValueBuffer = undefined;
46394649 var rhs_buf: Value.ElemValueBuffer = undefined;
46404650 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
46414651 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4642 scalar.* = try floatDivTruncScalar(lhs_elem, rhs_elem, float_type.scalarType(), arena, target);
4652 scalar.* = try floatDivTruncScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
46434653 }
46444654 return Value.Tag.aggregate.create(arena, result_data);
46454655 }
......@@ -4691,14 +4701,14 @@ pub const Value = extern union {
46914701 mod: *Module,
46924702 ) !Value {
46934703 const target = mod.getTarget();
4694 if (float_type.zigTypeTag() == .Vector) {
4704 if (float_type.zigTypeTag(mod) == .Vector) {
46954705 const result_data = try arena.alloc(Value, float_type.vectorLen());
46964706 for (result_data, 0..) |*scalar, i| {
46974707 var lhs_buf: Value.ElemValueBuffer = undefined;
46984708 var rhs_buf: Value.ElemValueBuffer = undefined;
46994709 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
47004710 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4701 scalar.* = try floatMulScalar(lhs_elem, rhs_elem, float_type.scalarType(), arena, target);
4711 scalar.* = try floatMulScalar(lhs_elem, rhs_elem, float_type.scalarType(mod), arena, target);
47024712 }
47034713 return Value.Tag.aggregate.create(arena, result_data);
47044714 }
......@@ -4744,12 +4754,12 @@ pub const Value = extern union {
47444754
47454755 pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
47464756 const target = mod.getTarget();
4747 if (float_type.zigTypeTag() == .Vector) {
4757 if (float_type.zigTypeTag(mod) == .Vector) {
47484758 const result_data = try arena.alloc(Value, float_type.vectorLen());
47494759 for (result_data, 0..) |*scalar, i| {
47504760 var buf: Value.ElemValueBuffer = undefined;
47514761 const elem_val = val.elemValueBuffer(mod, i, &buf);
4752 scalar.* = try sqrtScalar(elem_val, float_type.scalarType(), arena, target);
4762 scalar.* = try sqrtScalar(elem_val, float_type.scalarType(mod), arena, target);
47534763 }
47544764 return Value.Tag.aggregate.create(arena, result_data);
47554765 }
......@@ -4784,12 +4794,12 @@ pub const Value = extern union {
47844794
47854795 pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
47864796 const target = mod.getTarget();
4787 if (float_type.zigTypeTag() == .Vector) {
4797 if (float_type.zigTypeTag(mod) == .Vector) {
47884798 const result_data = try arena.alloc(Value, float_type.vectorLen());
47894799 for (result_data, 0..) |*scalar, i| {
47904800 var buf: Value.ElemValueBuffer = undefined;
47914801 const elem_val = val.elemValueBuffer(mod, i, &buf);
4792 scalar.* = try sinScalar(elem_val, float_type.scalarType(), arena, target);
4802 scalar.* = try sinScalar(elem_val, float_type.scalarType(mod), arena, target);
47934803 }
47944804 return Value.Tag.aggregate.create(arena, result_data);
47954805 }
......@@ -4824,12 +4834,12 @@ pub const Value = extern union {
48244834
48254835 pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
48264836 const target = mod.getTarget();
4827 if (float_type.zigTypeTag() == .Vector) {
4837 if (float_type.zigTypeTag(mod) == .Vector) {
48284838 const result_data = try arena.alloc(Value, float_type.vectorLen());
48294839 for (result_data, 0..) |*scalar, i| {
48304840 var buf: Value.ElemValueBuffer = undefined;
48314841 const elem_val = val.elemValueBuffer(mod, i, &buf);
4832 scalar.* = try cosScalar(elem_val, float_type.scalarType(), arena, target);
4842 scalar.* = try cosScalar(elem_val, float_type.scalarType(mod), arena, target);
48334843 }
48344844 return Value.Tag.aggregate.create(arena, result_data);
48354845 }
......@@ -4864,12 +4874,12 @@ pub const Value = extern union {
48644874
48654875 pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
48664876 const target = mod.getTarget();
4867 if (float_type.zigTypeTag() == .Vector) {
4877 if (float_type.zigTypeTag(mod) == .Vector) {
48684878 const result_data = try arena.alloc(Value, float_type.vectorLen());
48694879 for (result_data, 0..) |*scalar, i| {
48704880 var buf: Value.ElemValueBuffer = undefined;
48714881 const elem_val = val.elemValueBuffer(mod, i, &buf);
4872 scalar.* = try tanScalar(elem_val, float_type.scalarType(), arena, target);
4882 scalar.* = try tanScalar(elem_val, float_type.scalarType(mod), arena, target);
48734883 }
48744884 return Value.Tag.aggregate.create(arena, result_data);
48754885 }
......@@ -4904,12 +4914,12 @@ pub const Value = extern union {
49044914
49054915 pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
49064916 const target = mod.getTarget();
4907 if (float_type.zigTypeTag() == .Vector) {
4917 if (float_type.zigTypeTag(mod) == .Vector) {
49084918 const result_data = try arena.alloc(Value, float_type.vectorLen());
49094919 for (result_data, 0..) |*scalar, i| {
49104920 var buf: Value.ElemValueBuffer = undefined;
49114921 const elem_val = val.elemValueBuffer(mod, i, &buf);
4912 scalar.* = try expScalar(elem_val, float_type.scalarType(), arena, target);
4922 scalar.* = try expScalar(elem_val, float_type.scalarType(mod), arena, target);
49134923 }
49144924 return Value.Tag.aggregate.create(arena, result_data);
49154925 }
......@@ -4944,12 +4954,12 @@ pub const Value = extern union {
49444954
49454955 pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
49464956 const target = mod.getTarget();
4947 if (float_type.zigTypeTag() == .Vector) {
4957 if (float_type.zigTypeTag(mod) == .Vector) {
49484958 const result_data = try arena.alloc(Value, float_type.vectorLen());
49494959 for (result_data, 0..) |*scalar, i| {
49504960 var buf: Value.ElemValueBuffer = undefined;
49514961 const elem_val = val.elemValueBuffer(mod, i, &buf);
4952 scalar.* = try exp2Scalar(elem_val, float_type.scalarType(), arena, target);
4962 scalar.* = try exp2Scalar(elem_val, float_type.scalarType(mod), arena, target);
49534963 }
49544964 return Value.Tag.aggregate.create(arena, result_data);
49554965 }
......@@ -4984,12 +4994,12 @@ pub const Value = extern union {
49844994
49854995 pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
49864996 const target = mod.getTarget();
4987 if (float_type.zigTypeTag() == .Vector) {
4997 if (float_type.zigTypeTag(mod) == .Vector) {
49884998 const result_data = try arena.alloc(Value, float_type.vectorLen());
49894999 for (result_data, 0..) |*scalar, i| {
49905000 var buf: Value.ElemValueBuffer = undefined;
49915001 const elem_val = val.elemValueBuffer(mod, i, &buf);
4992 scalar.* = try logScalar(elem_val, float_type.scalarType(), arena, target);
5002 scalar.* = try logScalar(elem_val, float_type.scalarType(mod), arena, target);
49935003 }
49945004 return Value.Tag.aggregate.create(arena, result_data);
49955005 }
......@@ -5024,12 +5034,12 @@ pub const Value = extern union {
50245034
50255035 pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
50265036 const target = mod.getTarget();
5027 if (float_type.zigTypeTag() == .Vector) {
5037 if (float_type.zigTypeTag(mod) == .Vector) {
50285038 const result_data = try arena.alloc(Value, float_type.vectorLen());
50295039 for (result_data, 0..) |*scalar, i| {
50305040 var buf: Value.ElemValueBuffer = undefined;
50315041 const elem_val = val.elemValueBuffer(mod, i, &buf);
5032 scalar.* = try log2Scalar(elem_val, float_type.scalarType(), arena, target);
5042 scalar.* = try log2Scalar(elem_val, float_type.scalarType(mod), arena, target);
50335043 }
50345044 return Value.Tag.aggregate.create(arena, result_data);
50355045 }
......@@ -5064,12 +5074,12 @@ pub const Value = extern union {
50645074
50655075 pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
50665076 const target = mod.getTarget();
5067 if (float_type.zigTypeTag() == .Vector) {
5077 if (float_type.zigTypeTag(mod) == .Vector) {
50685078 const result_data = try arena.alloc(Value, float_type.vectorLen());
50695079 for (result_data, 0..) |*scalar, i| {
50705080 var buf: Value.ElemValueBuffer = undefined;
50715081 const elem_val = val.elemValueBuffer(mod, i, &buf);
5072 scalar.* = try log10Scalar(elem_val, float_type.scalarType(), arena, target);
5082 scalar.* = try log10Scalar(elem_val, float_type.scalarType(mod), arena, target);
50735083 }
50745084 return Value.Tag.aggregate.create(arena, result_data);
50755085 }
......@@ -5104,12 +5114,12 @@ pub const Value = extern union {
51045114
51055115 pub fn fabs(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
51065116 const target = mod.getTarget();
5107 if (float_type.zigTypeTag() == .Vector) {
5117 if (float_type.zigTypeTag(mod) == .Vector) {
51085118 const result_data = try arena.alloc(Value, float_type.vectorLen());
51095119 for (result_data, 0..) |*scalar, i| {
51105120 var buf: Value.ElemValueBuffer = undefined;
51115121 const elem_val = val.elemValueBuffer(mod, i, &buf);
5112 scalar.* = try fabsScalar(elem_val, float_type.scalarType(), arena, target);
5122 scalar.* = try fabsScalar(elem_val, float_type.scalarType(mod), arena, target);
51135123 }
51145124 return Value.Tag.aggregate.create(arena, result_data);
51155125 }
......@@ -5144,12 +5154,12 @@ pub const Value = extern union {
51445154
51455155 pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
51465156 const target = mod.getTarget();
5147 if (float_type.zigTypeTag() == .Vector) {
5157 if (float_type.zigTypeTag(mod) == .Vector) {
51485158 const result_data = try arena.alloc(Value, float_type.vectorLen());
51495159 for (result_data, 0..) |*scalar, i| {
51505160 var buf: Value.ElemValueBuffer = undefined;
51515161 const elem_val = val.elemValueBuffer(mod, i, &buf);
5152 scalar.* = try floorScalar(elem_val, float_type.scalarType(), arena, target);
5162 scalar.* = try floorScalar(elem_val, float_type.scalarType(mod), arena, target);
51535163 }
51545164 return Value.Tag.aggregate.create(arena, result_data);
51555165 }
......@@ -5184,12 +5194,12 @@ pub const Value = extern union {
51845194
51855195 pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
51865196 const target = mod.getTarget();
5187 if (float_type.zigTypeTag() == .Vector) {
5197 if (float_type.zigTypeTag(mod) == .Vector) {
51885198 const result_data = try arena.alloc(Value, float_type.vectorLen());
51895199 for (result_data, 0..) |*scalar, i| {
51905200 var buf: Value.ElemValueBuffer = undefined;
51915201 const elem_val = val.elemValueBuffer(mod, i, &buf);
5192 scalar.* = try ceilScalar(elem_val, float_type.scalarType(), arena, target);
5202 scalar.* = try ceilScalar(elem_val, float_type.scalarType(mod), arena, target);
51935203 }
51945204 return Value.Tag.aggregate.create(arena, result_data);
51955205 }
......@@ -5224,12 +5234,12 @@ pub const Value = extern union {
52245234
52255235 pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
52265236 const target = mod.getTarget();
5227 if (float_type.zigTypeTag() == .Vector) {
5237 if (float_type.zigTypeTag(mod) == .Vector) {
52285238 const result_data = try arena.alloc(Value, float_type.vectorLen());
52295239 for (result_data, 0..) |*scalar, i| {
52305240 var buf: Value.ElemValueBuffer = undefined;
52315241 const elem_val = val.elemValueBuffer(mod, i, &buf);
5232 scalar.* = try roundScalar(elem_val, float_type.scalarType(), arena, target);
5242 scalar.* = try roundScalar(elem_val, float_type.scalarType(mod), arena, target);
52335243 }
52345244 return Value.Tag.aggregate.create(arena, result_data);
52355245 }
......@@ -5264,12 +5274,12 @@ pub const Value = extern union {
52645274
52655275 pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value {
52665276 const target = mod.getTarget();
5267 if (float_type.zigTypeTag() == .Vector) {
5277 if (float_type.zigTypeTag(mod) == .Vector) {
52685278 const result_data = try arena.alloc(Value, float_type.vectorLen());
52695279 for (result_data, 0..) |*scalar, i| {
52705280 var buf: Value.ElemValueBuffer = undefined;
52715281 const elem_val = val.elemValueBuffer(mod, i, &buf);
5272 scalar.* = try truncScalar(elem_val, float_type.scalarType(), arena, target);
5282 scalar.* = try truncScalar(elem_val, float_type.scalarType(mod), arena, target);
52735283 }
52745284 return Value.Tag.aggregate.create(arena, result_data);
52755285 }
......@@ -5311,7 +5321,7 @@ pub const Value = extern union {
53115321 mod: *Module,
53125322 ) !Value {
53135323 const target = mod.getTarget();
5314 if (float_type.zigTypeTag() == .Vector) {
5324 if (float_type.zigTypeTag(mod) == .Vector) {
53155325 const result_data = try arena.alloc(Value, float_type.vectorLen());
53165326 for (result_data, 0..) |*scalar, i| {
53175327 var mulend1_buf: Value.ElemValueBuffer = undefined;
......@@ -5321,7 +5331,7 @@ pub const Value = extern union {
53215331 var addend_buf: Value.ElemValueBuffer = undefined;
53225332 const addend_elem = addend.elemValueBuffer(mod, i, &addend_buf);
53235333 scalar.* = try mulAddScalar(
5324 float_type.scalarType(),
5334 float_type.scalarType(mod),
53255335 mulend1_elem,
53265336 mulend2_elem,
53275337 addend_elem,
......@@ -5380,8 +5390,7 @@ pub const Value = extern union {
53805390 /// If the value is represented in-memory as a series of bytes that all
53815391 /// have the same value, return that byte value, otherwise null.
53825392 pub fn hasRepeatedByteRepr(val: Value, ty: Type, mod: *Module, value_buffer: *Payload.U64) !?Value {
5383 const target = mod.getTarget();
5384 const abi_size = std.math.cast(usize, ty.abiSize(target)) orelse return null;
5393 const abi_size = std.math.cast(usize, ty.abiSize(mod)) orelse return null;
53855394 assert(abi_size >= 1);
53865395 const byte_buffer = try mod.gpa.alloc(u8, abi_size);
53875396 defer mod.gpa.free(byte_buffer);
......@@ -5549,16 +5558,6 @@ pub const Value = extern union {
55495558 data: Type,
55505559 };
55515560
5552 pub const IntType = struct {
5553 pub const base_tag = Tag.int_type;
5554
5555 base: Payload = Payload{ .tag = base_tag },
5556 data: struct {
5557 bits: u16,
5558 signed: bool,
5559 },
5560 };
5561
55625561 pub const Float_16 = struct {
55635562 pub const base_tag = Tag.float_16;
55645563
......@@ -5659,7 +5658,10 @@ pub const Value = extern union {
56595658
56605659 pub const zero = initTag(.zero);
56615660 pub const one = initTag(.one);
5662 pub const negative_one: Value = .{ .ptr_otherwise = &negative_one_payload.base };
5661 pub const negative_one: Value = .{
5662 .ip_index = .none,
5663 .legacy = .{ .ptr_otherwise = &negative_one_payload.base },
5664 };
56635665 pub const undef = initTag(.undef);
56645666 pub const @"void" = initTag(.void_value);
56655667 pub const @"null" = initTag(.null_value);